summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKen Raeburn <raeburn@mit.edu>2004-06-03 00:30:02 +0000
committerKen Raeburn <raeburn@mit.edu>2004-06-03 00:30:02 +0000
commit2e74ca109da51b550958ccf1809f15eadd6ded93 (patch)
treed2d7a7ff114ca9fc3d310a7d56b501a3d338ae04 /src
parent4a7895d8c1f8b08ebd0e3bcfd975783fcc8bd057 (diff)
downloadkrb5-2e74ca109da51b550958ccf1809f15eadd6ded93.tar.gz
krb5-2e74ca109da51b550958ccf1809f15eadd6ded93.tar.xz
krb5-2e74ca109da51b550958ccf1809f15eadd6ded93.zip
The com_err library is now probably as thread-safe as it's going to get, on
UNIX; Windows still needs work.... * com_err.c: Include stdlib.h. (com_err_hook_lock): New mutex. (com_err_lock_hook_handle): New function. (com_err_va, set_com_err_hook, reset_com_err_hook): Call com_err_finish_init, and grab the lock. * error_message.c: Don't include k5-thread.h. (com_err_finish_init): New function. (com_err_initialize): Initialize the new mutex. * error_table.h: Include k5-thread.h. (com_err_hook_lock, com_err_finish_init): Declare. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@16394 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src')
-rw-r--r--src/util/et/ChangeLog13
-rw-r--r--src/util/et/com_err.c56
-rw-r--r--src/util/et/error_message.c9
-rw-r--r--src/util/et/error_table.h4
4 files changed, 74 insertions, 8 deletions
diff --git a/src/util/et/ChangeLog b/src/util/et/ChangeLog
index 9115708fa0..caf7c990c3 100644
--- a/src/util/et/ChangeLog
+++ b/src/util/et/ChangeLog
@@ -1,3 +1,16 @@
+2004-06-02 Ken Raeburn <raeburn@mit.edu>
+
+ * com_err.c: Include stdlib.h.
+ (com_err_hook_lock): New mutex.
+ (com_err_lock_hook_handle): New function.
+ (com_err_va, set_com_err_hook, reset_com_err_hook): Call
+ com_err_finish_init, and grab the lock.
+ * error_message.c: Don't include k5-thread.h.
+ (com_err_finish_init): New function.
+ (com_err_initialize): Initialize the new mutex.
+ * error_table.h: Include k5-thread.h.
+ (com_err_hook_lock, com_err_finish_init): Declare.
+
2004-05-31 Ken Raeburn <raeburn@mit.edu>
* error_message.c (terminated): New variable.
diff --git a/src/util/et/com_err.c b/src/util/et/com_err.c
index 59db443456..e7843ecc59 100644
--- a/src/util/et/com_err.c
+++ b/src/util/et/com_err.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "com_err.h"
#include "error_table.h"
@@ -30,6 +31,7 @@
#endif
static /*@null@*/ et_old_error_hook_func com_err_hook = 0;
+k5_mutex_t com_err_hook_lock = K5_MUTEX_PARTIAL_INITIALIZER;
static void default_com_err_proc (const char *whoami, errcode_t code,
const char *fmt, va_list ap)
@@ -89,10 +91,32 @@ void KRB5_CALLCONV com_err_va(const char *whoami,
const char *fmt,
va_list ap)
{
- if (!com_err_hook)
- default_com_err_proc(whoami, code, fmt, ap);
- else
- (com_err_hook)(whoami, code, fmt, ap);
+ int err;
+ et_old_error_hook_func p;
+
+ err = com_err_finish_init();
+ if (err)
+ goto best_try;
+ err = k5_mutex_lock(&com_err_hook_lock);
+ if (err)
+ goto best_try;
+ p = com_err_hook ? com_err_hook : default_com_err_proc;
+ (*p)(whoami, code, fmt, ap);
+ k5_mutex_unlock(&com_err_hook_lock);
+
+best_try:
+ /* Yikes. Our library initialization failed or we couldn't lock
+ the lock we want. We could be in trouble. Gosh, we should
+ probably print an error message. Oh, wait. That's what we're
+ trying to do. In fact, if we're losing on initialization here,
+ there's a good chance it has to do with failed initialization
+ of the caller. */
+ if (!com_err_hook)
+ default_com_err_proc(whoami, code, fmt, ap);
+ else
+ (com_err_hook)(whoami, code, fmt, ap);
+ assert(err == 0);
+ abort();
}
@@ -108,19 +132,37 @@ void KRB5_CALLCONV_C com_err(const char *whoami,
}
#if !(defined(_WIN32))
+/* Make a separate function because the assert invocations below
+ use the macro expansion on some platforms, which may be insanely
+ long and incomprehensible. */
+static int com_err_lock_hook_handle(void)
+{
+ return k5_mutex_lock(&com_err_hook_lock);
+}
+
et_old_error_hook_func set_com_err_hook (et_old_error_hook_func new_proc)
{
- et_old_error_hook_func x = com_err_hook;
+ et_old_error_hook_func x;
+ /* Broken initialization? What can we do? */
+ assert(com_err_finish_init() == 0);
+ assert(com_err_lock_hook_handle() == 0);
+ x = com_err_hook;
com_err_hook = new_proc;
+ k5_mutex_unlock(&com_err_hook_lock);
return x;
}
et_old_error_hook_func reset_com_err_hook ()
{
- et_old_error_hook_func x = com_err_hook;
-
+ et_old_error_hook_func x;
+
+ /* Broken initialization? What can we do? */
+ assert(com_err_finish_init() == 0);
+ assert(com_err_lock_hook_handle() == 0);
+ x = com_err_hook;
com_err_hook = NULL;
+ k5_mutex_unlock(&com_err_hook_lock);
return x;
}
#endif
diff --git a/src/util/et/error_message.c b/src/util/et/error_message.c
index e785172d92..07c1fcd1d1 100644
--- a/src/util/et/error_message.c
+++ b/src/util/et/error_message.c
@@ -26,7 +26,6 @@
#include <string.h>
#include "com_err.h"
#include "error_table.h"
-#include "k5-thread.h"
#include "k5-platform.h"
#if defined(_WIN32)
@@ -51,6 +50,9 @@ int com_err_initialize(void)
err = k5_mutex_finish_init(&et_list_lock);
if (err)
return err;
+ err = k5_mutex_finish_init(&com_err_hook_lock);
+ if (err)
+ return err;
err = k5_key_register(K5_KEY_COM_ERR, free);
if (err)
return err;
@@ -333,3 +335,8 @@ remove_error_table(const struct error_table * et)
k5_mutex_unlock(&et_list_lock);
return ENOENT;
}
+
+int com_err_finish_init()
+{
+ return CALL_INIT_FUNCTION(com_err_initialize);
+}
diff --git a/src/util/et/error_table.h b/src/util/et/error_table.h
index 41453587c4..ea804cf005 100644
--- a/src/util/et/error_table.h
+++ b/src/util/et/error_table.h
@@ -31,5 +31,9 @@ extern const char *error_table_name_r (unsigned long,
/*@out@*/ /*@returned@*/ char *outbuf)
/*@modifies outbuf@*/;
+#include "k5-thread.h"
+extern k5_mutex_t com_err_hook_lock;
+extern int com_err_finish_init(void);
+
#define _ET_H
#endif