bus: Fix maximum log levels when mixing log/vlog implementing loggers
authorTobias Brunner <tobias@strongswan.org>
Thu, 22 Sep 2016 13:51:09 +0000 (15:51 +0200)
committerTobias Brunner <tobias@strongswan.org>
Fri, 30 Sep 2016 16:34:04 +0000 (18:34 +0200)
The maximum would not get set correctly when a logger is removed and the
first remaining logger in the list (the one with the highest log level) does
e.g. only implement vlog() while there are other loggers that implement log().
This would result in only max_vlevel getting set correctly while max_level
would incorrectly get set to -1 so that log() would not get called for any
of the loggers anymore.

References #574.

src/libcharon/bus/bus.c

index e17d629..ba44a22 100644 (file)
@@ -208,6 +208,24 @@ static inline void register_logger(private_bus_t *this, debug_t group,
 }
 
 /**
+ * Find the log level of the first registered logger that implements log or
+ * vlog (or both).
+ */
+static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level,
+                                                       level_t *vlevel)
+{
+       if (entry->logger->log && *level == LEVEL_SILENT)
+       {
+               *level = entry->levels[*group];
+       }
+       if (entry->logger->vlog && *vlevel == LEVEL_SILENT)
+       {
+               *vlevel = entry->levels[*group];
+       }
+       return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT;
+}
+
+/**
  * Unregister a logger from all log groups (destroys the log_entry_t)
  */
 static inline void unregister_logger(private_bus_t *this, logger_t *logger)
@@ -240,18 +258,8 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger)
                        {
                                loggers = this->loggers[group];
                                loggers->remove(loggers, found, NULL);
-
-                               if (loggers->get_first(loggers, (void**)&entry) == SUCCESS)
-                               {
-                                       if (entry->logger->log)
-                                       {
-                                               level = entry->levels[group];
-                                       }
-                                       if (entry->logger->vlog)
-                                       {
-                                               vlevel = entry->levels[group];
-                                       }
-                               }
+                               loggers->find_first(loggers, (linked_list_match_t)find_max_levels, NULL,
+                                                                       &group, &level, &vlevel);
                                set_level(&this->max_level[group], level);
                                set_level(&this->max_vlevel[group], vlevel);
                        }