]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/log-stream.c
Resources: Allow res_free(NULL) and res_detach(NULL)
[libucw.git] / ucw / log-stream.c
index 097faef905440873a47a6f3aa50409b3de76043a..5af9f3e6581ad264797e64c566ba0573db40f5d8 100644 (file)
@@ -52,22 +52,26 @@ log_init_module(void)
   log_add_substream(ls, &log_stream_default);
 }
 
   log_add_substream(ls, &log_stream_default);
 }
 
-/* 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)
 {
   if (!log_initialized)
     return;
 
 void
 log_close_all(void)
 {
   if (!log_initialized)
     return;
 
-  // Close all open streams
+  // Remove substreams of all streams
   for (int i=0; i < log_streams_after; i++)
     if (log_streams.ptr[i]->regnum >= 0)
   for (int i=0; i < log_streams_after; i++)
     if (log_streams.ptr[i]->regnum >= 0)
-      log_close_stream(log_streams.ptr[i]);
+      log_rm_substream(log_streams.ptr[i], NULL);
 
 
-  // Free all cached structures
+  // Close all streams that remain and free all cached structures
   for (int i=0; i < log_streams_after; i++)
   for (int i=0; i < log_streams_after; i++)
-    xfree(log_streams.ptr[i]);
+    {
+      struct log_stream *ls = log_streams.ptr[i];
+      if (ls->regnum >= 0)
+       log_close_stream(ls);
+      ASSERT(ls->regnum < 0 || !ls->use_count);
+      xfree(ls);
+    }
 
   /* Back to the default state */
   lsbuf_done(&log_streams);
 
   /* Back to the default state */
   lsbuf_done(&log_streams);
@@ -76,8 +80,6 @@ log_close_all(void)
   log_initialized = 0;
 }
 
   log_initialized = 0;
 }
 
-/* Add a new substream. The parent stream takes a reference on the substream,
- * preventing it from being closed as long as it is linked. */
 void
 log_add_substream(struct log_stream *where, struct log_stream *what)
 {
 void
 log_add_substream(struct log_stream *where, struct log_stream *what)
 {
@@ -89,9 +91,6 @@ log_add_substream(struct log_stream *where, struct log_stream *what)
   clist_add_tail(&where->substreams, &n->n);
 }
 
   clist_add_tail(&where->substreams, &n->n);
 }
 
-/* Remove all occurrences of a substream together with the references they
- * keep. If a substream becomes unreferenced, it is closed. If what is NULL,
- * all substreams are removed. Returns the number of deleted entries. */
 int
 log_rm_substream(struct log_stream *where, struct log_stream *what)
 {
 int
 log_rm_substream(struct log_stream *where, struct log_stream *what)
 {
@@ -110,7 +109,6 @@ log_rm_substream(struct log_stream *where, struct log_stream *what)
   return cnt;
 }
 
   return cnt;
 }
 
-/* Return a pointer to a new stream with no handler and an empty substream list. */
 struct log_stream *
 log_new_stream(size_t size)
 {
 struct log_stream *
 log_new_stream(size_t size)
 {
@@ -138,14 +136,12 @@ log_new_stream(size_t size)
   /* Initialize the stream */
   bzero(l, sizeof(*l));
   l->levels = ~0U;
   /* Initialize the stream */
   bzero(l, sizeof(*l));
   l->levels = ~0U;
+  l->types = ~0U;
   l->regnum = LS_SET_STRNUM(index);
   clist_init(&l->substreams);
   return log_ref_stream(l);
 }
 
   l->regnum = LS_SET_STRNUM(index);
   clist_init(&l->substreams);
   return log_ref_stream(l);
 }
 
-/* Remove a reference on a stream and close it if it was the last reference.
- * Closing automatically unlinks all substreams and closes them if they are
- * no longer referenced. Returns 1 if the stream has been really closed. */
 int
 log_close_stream(struct log_stream *ls)
 {
 int
 log_close_stream(struct log_stream *ls)
 {
@@ -173,3 +169,35 @@ log_set_format(struct log_stream *ls, uns mask, uns data)
   CLIST_FOR_EACH(simp_node *, i, ls->substreams)
     log_set_format(i->p, mask, data);
 }
   CLIST_FOR_EACH(simp_node *, i, ls->substreams)
     log_set_format(i->p, mask, data);
 }
+
+/*** Registry of type names ***/
+
+int log_register_type(const char *name)
+{
+  if (!log_type_names)
+    {
+      log_type_names = xmalloc_zero(LS_NUM_TYPES * sizeof(char *));
+      log_type_names[0] = "default";
+    }
+  uns id;
+  for (id=0; id < LS_NUM_TYPES && log_type_names[id]; id++)
+    if (!strcmp(log_type_names[id], name))
+      return LS_SET_TYPE(id);
+  ASSERT(id < LS_NUM_TYPES);
+  log_type_names[id] = xstrdup(name);
+  return LS_SET_TYPE(id);
+}
+
+/** Find a message type by name and return its ID encoded by `LS_SET_TYPE`. Returns -1 if no such type found. **/
+int log_find_type(const char *name)
+{
+  if (!strcmp(name, "default"))
+    return 0;
+  if (!log_type_names)
+    return -1;
+
+  for (uns id=0; id < LS_NUM_TYPES && log_type_names[id]; id++)
+    if (!strcmp(log_type_names[id], name))
+      return LS_SET_TYPE(id);
+  return -1;
+}