[vlc-commits] messages: make logger class for the switch functionality

Rémi Denis-Courmont git at videolan.org
Wed Feb 20 19:06:37 CET 2019


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Wed Feb 20 19:46:04 2019 +0200| [8110beb648d1b34483202df30302fe99a9109647] | committer: Rémi Denis-Courmont

messages: make logger class for the switch functionality

The read/write lock is only useful for the top-level logger. As there
are now two stacked loggers, one for the backend and one for the switch
function, this avoids a redundant lock and separates concerns properly.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8110beb648d1b34483202df30302fe99a9109647
---

 src/libvlc.h        |  2 +-
 src/misc/messages.c | 94 +++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 75 insertions(+), 21 deletions(-)

diff --git a/src/libvlc.h b/src/libvlc.h
index e692ede7b4..c4fffb920a 100644
--- a/src/libvlc.h
+++ b/src/libvlc.h
@@ -75,7 +75,7 @@ void vlc_mutex_unmark(const vlc_mutex_t *);
 /*
  * Logging
  */
-typedef struct vlc_logger_t vlc_logger_t;
+typedef struct vlc_logger vlc_logger_t;
 
 int vlc_LogPreinit(libvlc_int_t *) VLC_USED;
 void vlc_LogInit(libvlc_int_t *);
diff --git a/src/misc/messages.c b/src/misc/messages.c
index 35cc414ee4..90d24a95c9 100644
--- a/src/misc/messages.c
+++ b/src/misc/messages.c
@@ -42,9 +42,7 @@
 #include <vlc_modules.h>
 #include "../libvlc.h"
 
-struct vlc_logger_t
-{
-    vlc_rwlock_t lock;
+struct vlc_logger {
     const struct vlc_logger_operations *ops;
     void *sys;
 };
@@ -57,9 +55,7 @@ static void vlc_vaLogCallback(vlc_logger_t *logger, int type,
 
     assert(logger != NULL);
     canc = vlc_savecancel();
-    vlc_rwlock_rdlock(&logger->lock);
     logger->ops->log(logger->sys, type, item, format, ap);
-    vlc_rwlock_unlock(&logger->lock);
     vlc_restorecancel(canc);
 }
 
@@ -204,6 +200,11 @@ static void Win32DebugOutputMsg (void* d, int type, const vlc_log_t *p_item,
 }
 #endif
 
+/**
+ * Early (latched) message log.
+ *
+ * A message log that stores messages in memory until another log is available.
+ */
 typedef struct vlc_log_early_t
 {
     struct vlc_log_early_t *next;
@@ -303,28 +304,78 @@ static const struct vlc_logger_operations discard_ops =
     NULL,
 };
 
+/**
+ * Switchable message log.
+ *
+ * A message log that can be redirected live.
+ */
+struct vlc_logger_switch {
+    struct vlc_logger backend;
+    vlc_rwlock_t lock;
+};
+
+static void vlc_vaLogSwitch(void *d, int type, const vlc_log_t *item,
+                            const char *format, va_list ap)
+{
+    struct vlc_logger_switch *logswitch = d;
+
+    vlc_rwlock_rdlock(&logswitch->lock);
+    logswitch->backend.ops->log(logswitch->backend.sys, type, item,
+                                format, ap);
+    vlc_rwlock_unlock(&logswitch->lock);
+}
+
+static void vlc_LogSwitchClose(void *d)
+{
+    struct vlc_logger_switch *logswitch = d;
+
+    if (logswitch->backend.ops->destroy != NULL)
+        logswitch->backend.ops->destroy(logswitch->backend.sys);
+
+    vlc_rwlock_destroy(&logswitch->lock);
+    free(logswitch);
+}
+
+static const struct vlc_logger_operations switch_ops = {
+    vlc_vaLogSwitch,
+    vlc_LogSwitchClose,
+};
+
 static void vlc_LogSwitch(libvlc_int_t *vlc,
                           const struct vlc_logger_operations *ops,
                           void *opaque)
 {
-    vlc_logger_t *logger = libvlc_priv(vlc)->logger;
-    const struct vlc_logger_operations *old_ops;
-    void *old_opaque;
+    struct vlc_logger *logger = libvlc_priv(vlc)->logger;
+    struct vlc_logger_switch *logswitch = logger->sys;
+    struct vlc_logger old_logger;
 
-    assert(logger != NULL);
+    assert(logger->ops == &switch_ops);
+    assert(logswitch != NULL);
 
     if (ops == NULL)
         ops = &discard_ops;
 
-    vlc_rwlock_wrlock(&logger->lock);
-    old_ops = logger->ops;
-    old_opaque = logger->sys;
-    logger->ops = ops;
-    logger->sys = opaque;
-    vlc_rwlock_unlock(&logger->lock);
+    vlc_rwlock_wrlock(&logswitch->lock);
+    old_logger = logswitch->backend;
+    logswitch->backend.ops = ops;
+    logswitch->backend.sys = opaque;
+    vlc_rwlock_unlock(&logswitch->lock);
+
+    if (old_logger.ops->destroy != NULL)
+        old_logger.ops->destroy(old_logger.sys);
+}
+
+static
+const struct vlc_logger_operations *vlc_LogSwitchCreate(void **restrict sysp)
+{
+    struct vlc_logger_switch *logswitch = malloc(sizeof (*logswitch));
+    if (unlikely(logswitch == NULL))
+        return NULL;
 
-    if (old_ops->destroy != NULL)
-        old_ops->destroy(old_opaque);
+    logswitch->backend.ops = &discard_ops;
+    vlc_rwlock_init(&logswitch->lock);
+    *sysp = logswitch;
+    return &switch_ops;
 }
 
 /**
@@ -406,9 +457,13 @@ int vlc_LogPreinit(libvlc_int_t *vlc)
     if (unlikely(logger == NULL))
         return -1;
 
+    logger->ops = vlc_LogSwitchCreate(&logger->sys);
+    if (unlikely(logger->ops == NULL)) {
+        free(logger);
+        return -1;
+    }
+
     libvlc_priv(vlc)->logger = logger;
-    vlc_rwlock_init(&logger->lock);
-    logger->ops = &discard_ops;
 
     const struct vlc_logger_operations *ops;
     void *opaque;
@@ -440,6 +495,5 @@ void vlc_LogDestroy(vlc_logger_t *logger)
     if (logger->ops->destroy != NULL)
         logger->ops->destroy(logger->sys);
 
-    vlc_rwlock_destroy(&logger->lock);
     free(logger);
 }



More information about the vlc-commits mailing list