/** Used for colored log messages. */
char log_colors[NUM_LOGLEVELS][COLOR_MAXLEN];
char *old_cwd;
+ /*
+ * If these pointers are non-NULL, the functions are called from
+ * daemon_log() before and after writing each log message.
+ */
+ void (*pre_log_hook)(void);
+ void (*post_log_hook)(void);
};
static struct daemon the_daemon, *me = &the_daemon;
me->loglevel = ret;
}
+void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void))
+{
+ me->pre_log_hook = pre_log_hook;
+ me->post_log_hook = post_log_hook;
+}
+
/**
* Set one of the daemon config flags.
*
return;
fp = me->logfile? me->logfile : stderr;
+ if (me->pre_log_hook)
+ me->pre_log_hook();
color = daemon_test_flag(DF_COLOR_LOG)? me->log_colors[ll] : NULL;
if (color)
fprintf(fp, "%s", color);
va_end(argp);
if (color)
fprintf(fp, "%s", COLOR_RESET);
+ if (me->post_log_hook)
+ me->post_log_hook();
}
time_t daemon_get_uptime(const struct timeval *current_time);
__malloc char *daemon_get_uptime_str(const struct timeval *current_time);
void daemon_set_logfile(const char *logfile_name);
+void daemon_set_hooks(void (*pre_log_hook)(void), void (*post_log_hook)(void));
void daemon_set_flag(unsigned flag);
void daemon_set_loglevel(const char *loglevel);
bool daemon_init_colors_or_die(int color_arg, int color_arg_auto,
/** The mutex protecting the shared memory area containing the mmd struct. */
int mmd_mutex;
+/* Serializes log output. */
+static int log_mutex;
+
static struct sched sched;
static struct signal_task *signal_task;
return get_task_list(&sched);
}
-/*
- * setup shared memory area and get mutex for locking
- */
+static void pre_log_hook(void)
+{
+ mutex_lock(log_mutex);
+}
+
+static void post_log_hook(void)
+{
+ mutex_unlock(log_mutex);
+}
+
+/* Setup shared memory area and init mutexes */
static void init_ipc_or_die(void)
{
void *shm;
if (ret < 0)
goto err_out;
mmd_mutex = ret;
+ ret = mutex_new();
+ if (ret < 0)
+ goto destroy_mmd_mutex;
+ log_mutex = ret;
mmd->num_played = 0;
mmd->num_commands = 0;
mmd->vss_status_flags = VSS_NEXT;
mmd->new_vss_status_flags = VSS_NEXT;
return;
+destroy_mmd_mutex:
+ mutex_destroy(mmd_mutex);
err_out:
PARA_EMERG_LOG("%s\n", para_strerror(-ret));
exit(EXIT_FAILURE);
server_pid = getpid();
init_random_seed_or_die();
daemon_log_welcome("server");
- init_ipc_or_die(); /* init mmd struct and mmd->lock */
+ init_ipc_or_die(); /* init mmd struct, mmd and log mutex */
daemon_set_start_time();
+ daemon_set_hooks(pre_log_hook, post_log_hook);
PARA_NOTICE_LOG("initializing audio format handlers\n");
afh_init();
signal_shutdown(signal_task);
if (!process_is_command_handler()) { /* parent (server) */
mutex_destroy(mmd_mutex);
+ daemon_set_hooks(NULL, NULL); /* only one process remaining */
+ mutex_destroy(log_mutex);
shm_detach(mmd);
if (ret < 0)
PARA_EMERG_LOG("%s\n", para_strerror(-ret));