rarely, less then 1% of the time, it is possible for aisexec to deadlock
in an atexit() handler registered by logsys. The reason is that
pthread_cond_wait() is used within the atexit() handler which is a nono.
This patch changes the call paths of exit to avoid calling
pthread_cond_wait inside atexit.
Index: exec/print.h
===================================================================
--- exec/print.h (revision 2120)
+++ exec/print.h (working copy)
@@ -95,7 +95,8 @@
extern void internal_log_printf (char *file, int line, int priority, char *format, ...) __attribute__((format(printf, 4, 5)));
extern void internal_log_printf2 (char *file, int line, int level, int id, char *format, ...) __attribute__((format(printf, 5, 6)));
extern void trace (char *file, int line, int tag, int id, char *format, ...) __attribute__((format(printf, 5, 6)));
-extern void log_flush(void);
+extern void log_flush_at_signal(void);
+extern void log_flush_before_exit(void);
#define LEVELMASK 0x07 /* 3 bits */
#define LOG_LEVEL(p) ((p) & LEVELMASK)
Index: exec/util.c
===================================================================
--- exec/util.c (revision 2120)
+++ exec/util.c (working copy)
@@ -166,7 +166,7 @@
}
}
log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting (reason: %s).\n", error_string);
- log_flush();
+ log_flush_before_exit();
exit (err);
}
Index: exec/service.c
===================================================================
--- exec/service.c (revision 2120)
+++ exec/service.c (working copy)
@@ -411,7 +411,7 @@
if ((int)arg >= OPENAIS_SHUTDOWN_ERRORCODES_START) {
log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting (reason: %s).\n", shutdown_strings[((int)arg) - OPENAIS_SHUTDOWN_ERRORCODES_START]);
- log_flush();
+ log_flush_before_exit();
return NULL;
}
openais_exit_error ((enum e_ais_done)arg);
Index: exec/main.c
===================================================================
--- exec/main.c (revision 2120)
+++ exec/main.c (working copy)
@@ -112,14 +112,14 @@
static void sigsegv_handler (int num)
{
signal (SIGSEGV, SIG_DFL);
- log_flush ();
+ log_flush_at_signal ();
raise (SIGSEGV);
}
static void sigabrt_handler (int num)
{
signal (SIGABRT, SIG_DFL);
- log_flush ();
+ log_flush_at_signal ();
raise (SIGABRT);
}
Index: exec/print.c
===================================================================
--- exec/print.c (revision 2120)
+++ exec/print.c (working copy)
@@ -101,7 +101,7 @@
char *log_string;
};
-static void log_atexit (void);
+static void log_flush_at_setup (void);
static int logger_init (const char *ident, int tags, int level, int mode)
{
@@ -356,12 +356,10 @@
/*
** Flush what we have buffered
*/
- log_flush();
+ log_flush_at_setup();
internal_log_printf(__FILE__, __LINE__, LOG_LEVEL_DEBUG, "log setup\n");
- atexit (log_atexit);
-
log_setup_called = 1;
return (0);
@@ -410,14 +408,33 @@
}
}
-static void log_atexit (void)
+void log_flush_before_exit (void)
{
if (log_setup_called) {
+ log_setup_called = 0;
worker_thread_group_wait (&log_thread_group);
+ worker_thread_group_exit (&log_thread_group);
+ worker_thread_group_atsegv (&log_thread_group);
+ } else {
+ struct log_entry *entry = head;
+ struct log_entry *tmp;
+
+ /* do not buffer these printouts */
+ logmode &= ~LOG_MODE_BUFFER;
+
+ while (entry) {
+ internal_log_printf(entry->file, entry->line,
+ entry->level, entry->str);
+ tmp = entry;
+ entry = entry->next;
+ free(tmp);
+ }
+
+ head = tail = NULL;
}
}
-void log_flush (void)
+void log_flush_at_signal (void)
{
if (log_setup_called) {
log_setup_called = 0;
@@ -441,3 +458,22 @@
head = tail = NULL;
}
}
+
+static void log_flush_at_setup (void)
+{
+ struct log_entry *entry = head;
+ struct log_entry *tmp;
+
+ /* do not buffer these printouts */
+ logmode &= ~LOG_MODE_BUFFER;
+
+ while (entry) {
+ internal_log_printf(entry->file, entry->line,
+ entry->level, entry->str);
+ tmp = entry;
+ entry = entry->next;
+ free(tmp);
+ }
+
+ head = tail = NULL;
+}
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais