vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
