This is an automated email from the ASF dual-hosted git repository.

mgoulish pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/main by this push:
     new 25360c6  DISPATCH-1956: Changes to sink-side only This closes #1311
25360c6 is described below

commit 25360c6cf6655e85cfb521e0c475b8a6a12bc592
Author: mgoulish <mgoul...@redhat.com>
AuthorDate: Wed Jul 21 07:59:40 2021 -0400

    DISPATCH-1956: Changes to sink-side only
    This closes #1311
---
 src/log.c | 66 +++++++++++++++++++++++++++++++++++----------------------------
 1 file changed, 37 insertions(+), 29 deletions(-)

diff --git a/src/log.c b/src/log.c
index cac7fbd..e032bf6 100644
--- a/src/log.c
+++ b/src/log.c
@@ -84,6 +84,7 @@ typedef struct log_sink_t {
 
 DEQ_DECLARE(log_sink_t, log_sink_list_t);
 
+static sys_mutex_t *log_sink_list_lock = 0;
 static log_sink_list_t sink_list = {0};
 
 const char *format = "%Y-%m-%d %H:%M:%S.%%06lu %z";
@@ -110,30 +111,30 @@ static const char* SINK_STDERR = "stderr";
 static const char* SINK_SYSLOG = "syslog";
 static const char* SOURCE_DEFAULT = "DEFAULT";
 
-static log_sink_t* find_log_sink_lh(const char* name) {
-    log_sink_t* sink = DEQ_HEAD(sink_list);
-    DEQ_FIND(sink, strcmp(sink->name, name) == 0);
-    return sink;
-}
-
-// Must hold the log_source_lock
-static void log_sink_free_lh(log_sink_t* sink) {
+static void log_sink_decref(const log_sink_t *sink) {
     if (!sink) return;
+    sys_mutex_lock(log_sink_list_lock);
     assert(sink->ref_count);
 
-    if (sys_atomic_dec(&sink->ref_count) == 1) {
-        DEQ_REMOVE(sink_list, sink);
-        free(sink->name);
-        if (sink->file && sink->file != stderr)
-            fclose(sink->file);
-        if (sink->syslog)
+    log_sink_t *mutable_sink = (log_sink_t *)sink;
+
+    if (sys_atomic_dec(&mutable_sink->ref_count) == 1) {
+        DEQ_REMOVE(sink_list, mutable_sink);
+        free(mutable_sink->name);
+        if (mutable_sink->file && mutable_sink->file != stderr)
+            fclose(mutable_sink->file);
+        if (mutable_sink->syslog)
             closelog();
-        free(sink);
+        free(mutable_sink);
     }
+    sys_mutex_unlock(log_sink_list_lock);
 }
 
-static log_sink_t* log_sink_lh(const char* name) {
-    log_sink_t* sink = find_log_sink_lh(name);
+static const log_sink_t* log_sink(const char* name) {
+    sys_mutex_lock(log_sink_list_lock);
+    log_sink_t* sink = DEQ_HEAD(sink_list);
+    DEQ_FIND(sink, strcmp(sink->name, name) == 0);
+
     if (sink) {
         sys_atomic_inc(&sink->ref_count);
     }
@@ -155,12 +156,11 @@ static log_sink_t* log_sink_lh(const char* name) {
             file = fopen(name, "a");
         }
 
-
-
         //If file is not there, return 0.
         // We are not logging an error here since we are already holding the 
log_source_lock
         // Writing a log message will try to re-obtain the log_source_lock 
lock and cause a deadlock.
         if (!file && !syslog) {
+            sys_mutex_unlock(log_sink_list_lock);
             return 0;
         }
 
@@ -173,7 +173,8 @@ static log_sink_t* log_sink_lh(const char* name) {
         DEQ_INSERT_TAIL(sink_list, sink);
 
     }
-    return sink;
+    sys_mutex_unlock(log_sink_list_lock);
+    return (const log_sink_t *)sink;
 }
 
 
@@ -190,7 +191,7 @@ struct qd_log_source_t {
     int includeTimestamp;       /* boolean or -1 means not set */
     int includeSource;          /* boolean or -1 means not set */
     bool syslog;
-    log_sink_t *sink;
+    const log_sink_t *sink;
     uint64_t severity_histogram[N_LEVEL_INDICES];
 };
 
@@ -305,8 +306,13 @@ static bool default_bool(int value, int default_value) {
 
 static void write_log(qd_log_source_t *log_source, qd_log_entry_t *entry)
 {
-    log_sink_t* sink = log_source->sink ? log_source->sink : 
default_log_source->sink;
-    if (!sink) return;
+    // Don't let the sink list change while we are writing to one of them.
+    sys_mutex_lock(log_sink_list_lock);
+    const log_sink_t* sink = log_source->sink ? log_source->sink : 
default_log_source->sink;
+    if (!sink) {
+        sys_mutex_unlock(log_sink_list_lock);
+        return;
+    }
 
     char log_str[LOG_MAX];
     char *begin = log_str;
@@ -339,7 +345,6 @@ static void write_log(qd_log_source_t *log_source, 
qd_log_entry_t *entry)
             char msg[TEXT_MAX];
             snprintf(msg, sizeof(msg), "Cannot write log output to '%s'", 
sink->name);
             perror(msg);
-            exit(1);
         };
         fflush(sink->file);
     }
@@ -348,6 +353,7 @@ static void write_log(qd_log_source_t *log_source, 
qd_log_entry_t *entry)
         if (syslog_level != -1)
             syslog(syslog_level, "%s", log_str);
     }
+    sys_mutex_unlock(log_sink_list_lock);
 }
 
 /// Reset the log source to the default state
@@ -395,7 +401,7 @@ qd_log_source_t *qd_log_source_reset(const char *module)
 
 static void qd_log_source_free_lh(qd_log_source_t* src) {
     DEQ_REMOVE(source_list, src);
-    log_sink_free_lh(src->sink);
+    log_sink_decref(src->sink);
     free(src->module);
     free(src);
 }
@@ -506,6 +512,8 @@ void qd_log_initialize(void)
     DEQ_INIT(source_list);
     DEQ_INIT(sink_list);
 
+    log_sink_list_lock = sys_mutex();
+
     // Set up level_names for use in error messages.
     char *begin = level_names, *end = level_names+sizeof(level_names);
     aprintf(&begin, end, "%s", levels[NONE].name);
@@ -518,7 +526,7 @@ void qd_log_initialize(void)
     default_log_source->mask = levels[INFO].mask;
     default_log_source->includeTimestamp = true;
     default_log_source->includeSource = 0;
-    default_log_source->sink = log_sink_lh(SINK_STDERR);
+    default_log_source->sink = log_sink(SINK_STDERR);
 }
 
 
@@ -528,7 +536,7 @@ void qd_log_finalize(void) {
     while (DEQ_HEAD(entries))
         qd_log_entry_free_lh(DEQ_HEAD(entries));
     while (DEQ_HEAD(sink_list))
-        log_sink_free_lh(DEQ_HEAD(sink_list));
+        log_sink_decref(DEQ_HEAD(sink_list));
     default_log_source = NULL;  // stale value would misconfigure new router 
started again in the same process
 }
 
@@ -602,7 +610,7 @@ qd_error_t qd_log_entity(qd_entity_t *entity)
         qd_log_source_t *src = qd_log_source_lh(module); /* The 
original(already existing) log source */
 
         if (has_output_file) {
-            log_sink_t* sink = log_sink_lh(outputFile);
+            const log_sink_t* sink = log_sink(outputFile);
             if (!sink) {
                 error_in_output = true;
                 sys_mutex_unlock(log_source_lock);
@@ -611,7 +619,7 @@ qd_error_t qd_log_entity(qd_entity_t *entity)
 
             // DEFAULT source may already have a sink, so free the old sink 
first
             if (src->sink) {
-                log_sink_free_lh(src->sink);
+                log_sink_decref(src->sink);
             }
 
             // Assign the new sink

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to