From: Martin Mares Date: Fri, 13 Feb 2009 17:12:39 +0000 (+0100) Subject: Logging: Clean up log-stream.c. X-Git-Tag: holmes-import~101 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=50f3497ac9b5b0178de03522b2cfcb5893e7ac2f;p=libucw.git Logging: Clean up log-stream.c. o Simplified log_new_stream() -- recycling of closed streams and allocation of new streams are two different code paths now. o The calls to log_init_module() need not be conditional. o Use clist_init() for initializing clists. o The usual coding style and namespace cleanups. Also added an explanatory comment about the uninitialized state to log.c. --- diff --git a/ucw/log-file.c b/ucw/log-file.c index 98a4b8e2..2df09498 100644 --- a/ucw/log-file.c +++ b/ucw/log-file.c @@ -138,7 +138,7 @@ static int ls_fdfile_handler(struct log_stream* ls, const char *m, uns cat UNUSE /* initialize with the default formatting, does NOT close the descriptor */ struct log_stream *ls_fdfile_new(int fd) { - struct log_stream *ls=ls_new(); + struct log_stream *ls=log_new_stream(); ls->idata=fd; ls->msgfmt=LSFMT_DEFAULT; ls->handler=ls_fdfile_handler; @@ -153,10 +153,10 @@ struct log_stream *ls_file_new(const char *path) int fd = open(path, O_WRONLY | O_CREAT | O_APPEND, 0666); if (fd<0) { - ls_msg(L_ERROR, "Opening logfile '%s' failed: %m.", path); + msg(L_ERROR, "Opening logfile '%s' failed: %m.", path); return NULL; } - ls = ls_new(); + ls = log_new_stream(); ls->name = xstrdup(path); ls->idata = fd; ls->msgfmt = LSFMT_DEFAULT; diff --git a/ucw/log-stream.c b/ucw/log-stream.c index 748164c8..01ada420 100644 --- a/ucw/log-stream.c +++ b/ucw/log-stream.c @@ -9,161 +9,155 @@ */ #include "ucw/lib.h" -#include "ucw/clists.h" -#include "ucw/simple-lists.h" #include "ucw/log.h" +#include "ucw/simple-lists.h" #include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +/* Initial number of streams to allocate (must be >=2) */ +#define LS_INIT_STREAMS 8 /* Flag indicating initialization of the module */ -static int ls_initialized = 0; +static int log_initialized = 0; -/* The head of the list of freed log_streams indexes in ls_streams.ptr (-1 if none free). - * Freed positions in ls_streams.ptr are connected into a linked list in the following way: - * ls_streams.ptr[ls_streams_free].idata is the index of next freed position (or -1) */ -static int ls_streams_free = -1; +/* The head of the list of freed log_streams indexes in log_streams.ptr (-1 if none free). + * Freed positions in log_streams.ptr are connected into a linked list in the following way: + * log_streams.ptr[log_streams_free].idata is the index of next freed position (or -1) */ +static int log_streams_free = -1; /* Initialize the logstream module. * It is not neccessary to call this explicitely as it is called by - * the first ls_new() (for backward compatibility and ease of use). */ -static void ls_init_module(void) + * the first log_new_stream() (for backward compatibility and ease of use). */ +static void +log_init_module(void) { - if (ls_initialized) return; + if (log_initialized) + return; - /* create the grow array */ + /* Create the growing array */ lsbuf_init(&log_streams); lsbuf_set_size(&log_streams, LS_INIT_STREAMS); bzero(log_streams.ptr, sizeof(struct log_stream*) * (log_streams.len)); - ls_streams_free = -1; + log_streams_free = -1; - ls_initialized = 1; + log_initialized = 1; /* init the default stream (0) as forwarder to fd2 */ - struct log_stream *ls = ls_new(); + struct log_stream *ls = log_new_stream(); ASSERT(ls == log_streams.ptr[0]); ASSERT(ls->regnum == 0); ls->name = "default"; - ls_add_substream(ls, (struct log_stream *) &ls_default_log); + log_add_substream(ls, (struct log_stream *) &log_stream_default); - /* log this */ - ls_msg(L_DEBUG, "logstream module initialized."); + // FIXME + msg(L_DEBUG, "logstream module initialized."); } -/* close all open streams, un-initialize the module, free all memory, - * use only ls_default_log */ -void ls_close_all(void) +/* Close all open streams, un-initialize the module, free all memory, + * and fall back to using only log_stream_default. */ +void +log_close_all(void) { - int i; + if (!log_initialized) + return; - if (!ls_initialized) return; - - for (i=0; iregnum>=0) - ls_close(log_streams.ptr[i]); - xfree(log_streams.ptr[i]); - } + for (int i=0; i < log_streams_after; i++) + { + if (log_streams.ptr[i]->regnum >= 0) + log_close_stream(log_streams.ptr[i]); + xfree(log_streams.ptr[i]); + } - /* set to the default state */ + /* Back to the default state */ lsbuf_done(&log_streams); - log_streams_after=0; - ls_streams_free=-1; - ls_initialized = 0; + log_streams_after = 0; + log_streams_free = -1; + log_initialized = 0; } -/* add a new substream, malloc()-ate a new simp_node */ -void ls_add_substream(struct log_stream *where, struct log_stream *what) +/* Add a new substream, xmalloc()-ate a new simp_node. */ +void +log_add_substream(struct log_stream *where, struct log_stream *what) { ASSERT(where); ASSERT(what); simp_node *n = xmalloc(sizeof(simp_node)); n->p = what; - clist_add_tail(&(where->substreams), (cnode*)n); + clist_add_tail(&where->substreams, &n->n); } -/* remove all occurences of a substream, free() the simp_node */ -/* return number of deleted entries */ -int ls_rm_substream(struct log_stream *where, struct log_stream *what) +/* Remove all occurences of a substream, xfree() the simp_node. */ +/* Return the number of deleted entries. */ +int +log_rm_substream(struct log_stream *where, struct log_stream *what) { void *tmp; - int cnt=0; + int cnt = 0; ASSERT(where); ASSERT(what); CLIST_FOR_EACH_DELSAFE(simp_node *, i, where->substreams, tmp) if (i->p == what) - { - clist_remove((cnode*)i); - xfree(i); - cnt++; - } + { + clist_remove(&i->n); + xfree(i); + cnt++; + } return cnt; } /* Return a pointer to a new stream with no handler and an empty substream list. */ -struct log_stream *ls_new(void) +struct log_stream * +log_new_stream(void) { struct log_stream *l; int index; - /* initialize the array if not initialized already */ - if (unlikely(ls_initialized==0)) - ls_init_module(); - - /* there is no closed stream -- allocate a new one */ - if (ls_streams_free==-1) - { - /* check the size of the pointer array */ - lsbuf_grow(&log_streams, log_streams_after+1); - ls_streams_free = log_streams_after++; - log_streams.ptr[ls_streams_free] = xmalloc(sizeof(struct log_stream)); - log_streams.ptr[ls_streams_free]->idata = -1; - log_streams.ptr[ls_streams_free]->regnum = -1; - } - - ASSERT(ls_streams_free>=0); - - /* initialize the stream */ - index = ls_streams_free; + /* Initialize the data structures if needed */ + log_init_module(); + + /* Get a free stream, possibly recycling a closed one */ + if (log_streams_free < 0) + { + lsbuf_grow(&log_streams, log_streams_after+1); + index = log_streams_after++; + l = log_streams.ptr[log_streams_free] = xmalloc(sizeof(struct log_stream)); + } + else + { + index = log_streams_free; l = log_streams.ptr[index]; - ls_streams_free = l->idata; - memset(l, 0, sizeof(struct log_stream)); + log_streams_free = l->idata; + } + + /* Initialize the stream */ + bzero(l, sizeof(*l)); l->levels = LS_ALL_LEVELS; l->regnum = LS_SET_STRNUM(index); - l->substreams.head.next = &(l->substreams.head); - l->substreams.head.prev = &(l->substreams.head); + clist_init(&l->substreams); return l; } -/* Close and remember given log_stream */ -/* does not affect substreams, but frees the .substreams list */ -void ls_close(struct log_stream *ls) +/* Close a stream, unlink (but do not close) all its substreams */ +void +log_close_stream(struct log_stream *ls) { void *tmp; ASSERT(ls); /* xfree() all the simp_nodes from substreams */ CLIST_FOR_EACH_DELSAFE(simp_node *, i, ls->substreams, tmp) - { - clist_remove((cnode*)i); - xfree(i); - } + { + clist_remove(&i->n); + xfree(i); + } - /* close and remember the stream */ - if (ls->close!=NULL) + /* Close the stream and add it to the free-list */ + if (ls->close) ls->close(ls); - ls->idata = ls_streams_free; - ls_streams_free = LS_GET_STRNUM(ls->regnum); + ls->idata = log_streams_free; + log_streams_free = LS_GET_STRNUM(ls->regnum); ls->regnum = -1; } diff --git a/ucw/log-syslog.c b/ucw/log-syslog.c index f92b6165..e4ec85ed 100644 --- a/ucw/log-syslog.c +++ b/ucw/log-syslog.c @@ -58,7 +58,7 @@ static int ls_syslog_handler(struct log_stream *ls, const char *m, uns flags) /* name is optional prefix (NULL for none) */ struct log_stream *ls_syslog_new(int facility, const char *name) { - struct log_stream *ls=ls_new(); + struct log_stream *ls=log_new_stream(); if (name) ls->name = xstrdup(name); ls->idata = facility; ls->msgfmt = LSFMT_NONE; diff --git a/ucw/log.c b/ucw/log.c index 8c53d0f5..075caffb 100644 --- a/ucw/log.c +++ b/ucw/log.c @@ -53,7 +53,10 @@ int log_streams_after = 0; /* The first never-used index in log_streams.ptr */ /* * Find a stream by its identifier given as LS_SET_STRNUM(flags). * Returns NULL if the stream doesn't exist or it's invalid. - * When stream #0 is requested, fall back to log_stream_default. + * + * If the log-stream machinery has not been initialized (which is normal for programs + * with no fancy logging), the log_streams gbuf is empty and this function only + * translates stream #0 to the static log_stream_default. */ struct log_stream * @@ -141,6 +144,9 @@ vmsg(uns cat, const char *fmt, va_list args) xfree(m); } +/* Maximal depth of log_pass_msg recursion */ +#define LS_MAX_DEPTH 64 + int log_pass_msg(int depth, struct log_stream *ls, const char *stime, const char *sutime, const char *m, uns cat) { diff --git a/ucw/log.h b/ucw/log.h index bcd9ebc9..d77632b2 100644 --- a/ucw/log.h +++ b/ucw/log.h @@ -41,7 +41,7 @@ struct log_stream }; /* the default logger */ -extern const struct log_stream ls_default_log; +extern const struct log_stream log_stream_default; /* A message is processed as follows: * 1. Discard if message level not in levels @@ -120,41 +120,29 @@ enum ls_flagmasks { // The module is initialized when a first stream is created. // Before that only the default stream exists. -// Initial number of streams to allocate (must be >=2) -#define LS_INIT_STREAMS 8 - /* Return pointer a new (xmalloc()-ated) stream with no handler and an empty substream list. */ -struct log_stream *ls_new(void); +struct log_stream *log_new_stream(void); /* Close and xfree() given log_stream */ /* Does not affect substreams */ -void ls_close(struct log_stream *ls); +void log_close_stream(struct log_stream *ls); /* close all open streams, un-initialize the module, free all memory, * use only ls_default_log */ -void ls_close_all(void); +void log_close_all(void); /* add a new substream, xmalloc()-ate a new simp_node */ -void ls_add_substream(struct log_stream *where, struct log_stream *what); +void log_add_substream(struct log_stream *where, struct log_stream *what); /* remove all occurences of a substream, free() the simp_node */ /* return number of deleted entries */ -int ls_rm_substream(struct log_stream *where, struct log_stream *what); +int log_rm_substream(struct log_stream *where, struct log_stream *what); /* get a stream by its number (regnum) */ /* returns NULL for free numbers */ /* defaults to ls_default_stream for 0 when stream number 0 not set */ struct log_stream *log_stream_by_flags(uns flags); -/* The proposed alternative to original vmsg() */ -void ls_vmsg(unsigned int cat, const char *fmt, va_list args); - -/* The proposed alternative to original msg() */ -void ls_msg(unsigned int cat, const char *fmt, ...); - -/* The proposed alternative to original die() */ -void ls_die(const char *fmt, ...); - /* process a message (string) (INTERNAL) */ /* depth prevents undetected looping */ /* returns 1 in case of loop detection or other fatal error @@ -162,9 +150,6 @@ void ls_die(const char *fmt, ...); int log_pass_msg(int depth, struct log_stream *ls, const char *stime, const char *sutime, const char *msg, uns cat); -/* Maximal depth of ls_passmsg recursion */ -#define LS_MAX_DEPTH 64 - /* Define an array (growing buffer) for pointers to log_streams. */ #define GBUF_TYPE struct log_stream* #define GBUF_PREFIX(x) lsbuf_##x