[syslog-ng] [PATCH 1/4] scratch-buffers: Support any number of stacks
Gergely Nagy
algernon at balabit.hu
Fri Feb 15 16:26:02 CET 2013
From: Gergely Nagy <algernon at madhouse-project.org>
Instead of being tied to GStrings only, support registering new kinds
of stacks, which will be automatiaclly free'd on thread shutdown. For
convenience, wrappers are provided for GString-based scratch buffer
acquire and release, and that stack is automatically registered and
free'd by the library itself.
This fixes #2.
Signed-off-by: Gergely Nagy <algernon at madhouse-project.org>
---
lib/mainloop.c | 3 +-
lib/scratch-buffers.c | 80 +++++++++++++++++++++++++++++++++++----------
lib/scratch-buffers.h | 41 +++++++++++++++++++----
lib/value-pairs.c | 34 ++++++++++---------
lib/vptransform.c | 38 +++++++++++----------
modules/afamqp/afamqp.c | 20 ++++++------
modules/json/jsonparser.c | 54 +++++++++++++++---------------
7 files changed, 174 insertions(+), 96 deletions(-)
diff --git a/lib/mainloop.c b/lib/mainloop.c
index 2d7383f..6dd1979 100644
--- a/lib/mainloop.c
+++ b/lib/mainloop.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002-2012 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2002-2013 BalaBit IT Ltd, Budapest, Hungary
* Copyright (c) 1998-2012 Balázs Scheidler
*
* This library is free software; you can redistribute it and/or
@@ -292,6 +292,7 @@ main_loop_io_worker_thread_start(void *cookie)
gint id;
dns_cache_init();
+ scratch_buffers_init();
g_static_mutex_lock(&main_loop_io_workers_idmap_lock);
/* NOTE: this algorithm limits the number of I/O worker threads to 64,
* since the ID map is stored in a single 64 bit integer. If we ever need
diff --git a/lib/scratch-buffers.c b/lib/scratch-buffers.c
index 2debca9..481ce73 100644
--- a/lib/scratch-buffers.c
+++ b/lib/scratch-buffers.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2011-2012 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2011-2012 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2011-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011-2013 Gergely Nagy <algernon at balabit.hu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -28,42 +28,86 @@
TLS_BLOCK_START
{
- GTrashStack *scratch_buffers;
+ GTrashStack *sb_gstrings;
+ GList *sb_registry;
}
TLS_BLOCK_END;
-#define local_scratch_buffers __tls_deref(scratch_buffers)
+/* GStrings */
-ScratchBuffer *
-scratch_buffer_acquire(void)
+#define local_sb_gstrings __tls_deref(sb_gstrings)
+
+GTrashStack *
+sb_gstring_acquire_buffer (void)
{
- ScratchBuffer *sb;
+ SBGString *sb;
- sb = g_trash_stack_pop(&local_scratch_buffers);
+ sb = g_trash_stack_pop(&local_sb_gstrings);
if (!sb)
{
- sb = g_new(ScratchBuffer, 1);
- g_string_steal(sb_string(sb));
+ sb = g_new(SBGString, 1);
+ g_string_steal(sb_gstring_string(sb));
}
else
- g_string_set_size(sb_string(sb), 0);
- return sb;
+ g_string_set_size(sb_gstring_string(sb), 0);
+
+ return (GTrashStack *)sb;
}
void
-scratch_buffer_release(ScratchBuffer *sb)
+sb_gstring_release_buffer(GTrashStack *s)
{
- g_trash_stack_push(&local_scratch_buffers, sb);
+ SBGString *sb = (SBGString *)s;
+
+ g_trash_stack_push(&local_sb_gstrings, sb);
}
void
-scratch_buffers_free(void)
+sb_gstring_free_stack(void)
{
- ScratchBuffer *sb;
+ SBGString *sb;
- while ((sb = g_trash_stack_pop(&local_scratch_buffers)) != NULL)
+ while ((sb = g_trash_stack_pop(&local_sb_gstrings)) != NULL)
{
- g_free(sb_string(sb)->str);
+ g_free(sb_gstring_string(sb)->str);
g_free(sb);
}
}
+
+ScratchBufferStack SBGStringStack = {
+ .acquire_buffer = sb_gstring_acquire_buffer,
+ .release_buffer = sb_gstring_release_buffer,
+ .free_stack = sb_gstring_free_stack
+};
+
+/* Global API */
+
+#define local_sb_registry __tls_deref(sb_registry)
+
+void
+scratch_buffers_register(ScratchBufferStack *stack)
+{
+ local_sb_registry = g_list_append (local_sb_registry, stack);
+}
+
+void
+scratch_buffers_init(void)
+{
+ local_sb_registry = NULL;
+ scratch_buffers_register(&SBGStringStack);
+}
+
+static void
+scratch_buffers_free_stack(gpointer data, gpointer user_data)
+{
+ ScratchBufferStack *s = (ScratchBufferStack *)data;
+
+ s->free_stack();
+}
+
+void
+scratch_buffers_free(void)
+{
+ g_list_foreach(local_sb_registry, scratch_buffers_free_stack, NULL);
+ g_list_free(local_sb_registry);
+}
diff --git a/lib/scratch-buffers.h b/lib/scratch-buffers.h
index c61e518..72ab40a 100644
--- a/lib/scratch-buffers.h
+++ b/lib/scratch-buffers.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2011 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2011 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2011-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011-2013 Gergely Nagy <algernon at balabit.hu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,17 +27,44 @@
#include <glib.h>
+/* Global API */
+
+typedef struct
+{
+ GTrashStack *(*acquire_buffer) (void);
+ void (*release_buffer) (GTrashStack *stack);
+ void (*free_stack) (void);
+} ScratchBufferStack;
+
+static inline GTrashStack *
+scratch_buffer_acquire (ScratchBufferStack *stack)
+{
+ return stack->acquire_buffer ();
+}
+
+static inline void
+scratch_buffer_release (ScratchBufferStack *stack, GTrashStack *buffer)
+{
+ stack->release_buffer (buffer);
+}
+
+void scratch_buffers_register(ScratchBufferStack *stack);
+void scratch_buffers_init(void);
+void scratch_buffers_free(void);
+
+/* GStrings */
+
typedef struct
{
GTrashStack stackp;
GString s;
-} ScratchBuffer;
+} SBGString;
-ScratchBuffer *scratch_buffer_acquire(void);
-void scratch_buffer_release(ScratchBuffer *sb);
+extern ScratchBufferStack SBGStringStack;
-#define sb_string(buffer) (&buffer->s)
+#define sb_gstring_acquire() ((SBGString *)scratch_buffer_acquire(&SBGStringStack))
+#define sb_gstring_release(b) (scratch_buffer_release(&SBGStringStack, (GTrashStack *)b))
-void scratch_buffers_free(void);
+#define sb_gstring_string(buffer) (&buffer->s)
#endif
diff --git a/lib/value-pairs.c b/lib/value-pairs.c
index ee22b73..e78fc58 100644
--- a/lib/value-pairs.c
+++ b/lib/value-pairs.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2011-2012 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2011-2012 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2011-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011-2013 Gergely Nagy <algernon at balabit.hu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -193,22 +193,22 @@ vp_pairs_foreach(gpointer data, gpointer user_data)
LogMessage *msg = ((gpointer *)user_data)[2];
gint32 seq_num = GPOINTER_TO_INT (((gpointer *)user_data)[3]);
GTree *scope_set = ((gpointer *)user_data)[5];
- ScratchBuffer *sb = scratch_buffer_acquire();
+ SBGString *sb = sb_gstring_acquire();
VPPairConf *vpc = (VPPairConf *)data;
log_template_format((LogTemplate *)vpc->template, msg, NULL, LTZ_LOCAL,
- seq_num, NULL, sb_string(sb));
+ seq_num, NULL, sb_gstring_string(sb));
- if (!sb_string(sb)->str[0])
+ if (!sb_gstring_string(sb)->str[0])
{
- scratch_buffer_release(sb);
+ sb_gstring_release(sb);
return;
}
g_tree_insert(scope_set, vp_transform_apply(vp, vpc->name),
- sb_string(sb)->str);
- g_string_steal(sb_string(sb));
- scratch_buffer_release(sb);
+ sb_gstring_string(sb)->str);
+ g_string_steal(sb_gstring_string(sb));
+ sb_gstring_release(sb);
}
/* runs over the LogMessage nv-pairs, and inserts them unless excluded */
@@ -246,7 +246,7 @@ static void
vp_merge_set(ValuePairs *vp, LogMessage *msg, gint32 seq_num, ValuePairSpec *set, GTree *dest)
{
gint i;
- ScratchBuffer *sb = scratch_buffer_acquire();
+ SBGString *sb = sb_gstring_acquire();
for (i = 0; set[i].name; i++)
{
@@ -265,7 +265,8 @@ vp_merge_set(ValuePairs *vp, LogMessage *msg, gint32 seq_num, ValuePairSpec *set
switch (set[i].type)
{
case VPT_MACRO:
- log_macro_expand(sb_string(sb), set[i].id, FALSE, NULL, LTZ_LOCAL, seq_num, NULL, msg);
+ log_macro_expand(sb_gstring_string(sb), set[i].id, FALSE,
+ NULL, LTZ_LOCAL, seq_num, NULL, msg);
break;
case VPT_NVPAIR:
{
@@ -273,20 +274,21 @@ vp_merge_set(ValuePairs *vp, LogMessage *msg, gint32 seq_num, ValuePairSpec *set
gssize len;
nv = log_msg_get_value(msg, (NVHandle) set[i].id, &len);
- g_string_append_len(sb_string(sb), nv, len);
+ g_string_append_len(sb_gstring_string(sb), nv, len);
break;
}
default:
g_assert_not_reached();
}
- if (!sb_string(sb)->str[0])
+ if (!sb_gstring_string(sb)->str[0])
continue;
- g_tree_insert(dest, vp_transform_apply(vp, set[i].name), sb_string(sb)->str);
- g_string_steal(sb_string(sb));
+ g_tree_insert(dest, vp_transform_apply(vp, set[i].name),
+ sb_gstring_string(sb)->str);
+ g_string_steal(sb_gstring_string(sb));
}
- scratch_buffer_release(sb);
+ sb_gstring_release(sb);
}
void
diff --git a/lib/vptransform.c b/lib/vptransform.c
index 43699a0..89f71bc 100644
--- a/lib/vptransform.c
+++ b/lib/vptransform.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2011-2012 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2011-2012 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2011-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011-2013 Gergely Nagy <algernon at balabit.hu>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,7 @@
#include <string.h>
-typedef void (*VPTransFunc)(ValuePairsTransform *t, ScratchBuffer *name);
+typedef void (*VPTransFunc)(ValuePairsTransform *t, SBGString *name);
typedef void (*VPTransDestroyFunc)(ValuePairsTransform *t);
struct _ValuePairsTransformSet
@@ -92,7 +92,7 @@ value_pairs_transform_free(ValuePairsTransform *t)
}
static inline void
-value_pairs_transform_apply(ValuePairsTransform *t, ScratchBuffer *key)
+value_pairs_transform_apply(ValuePairsTransform *t, SBGString *key)
{
t->transform(t, key);
}
@@ -100,11 +100,11 @@ value_pairs_transform_apply(ValuePairsTransform *t, ScratchBuffer *key)
/* add_prefix() */
static void
-vp_trans_add_prefix(ValuePairsTransform *t, ScratchBuffer *key)
+vp_trans_add_prefix(ValuePairsTransform *t, SBGString *key)
{
VPTransAddPrefix *self = (VPTransAddPrefix *)t;
- g_string_prepend(sb_string(key), self->prefix);
+ g_string_prepend(sb_gstring_string(key), self->prefix);
}
static void
@@ -132,11 +132,11 @@ value_pairs_new_transform_add_prefix (const gchar *prefix)
/* shift() */
static void
-vp_trans_shift(ValuePairsTransform *t, ScratchBuffer* key)
+vp_trans_shift(ValuePairsTransform *t, SBGString* key)
{
VPTransShift *self = (VPTransShift *)t;
- g_string_erase(sb_string(key), 0, self->amount);
+ g_string_erase(sb_gstring_string(key), 0, self->amount);
}
ValuePairsTransform *
@@ -156,15 +156,17 @@ value_pairs_new_transform_shift (gint amount)
/* replace() */
static void
-vp_trans_replace(ValuePairsTransform *t, ScratchBuffer *key)
+vp_trans_replace(ValuePairsTransform *t, SBGString *key)
{
VPTransReplace *self = (VPTransReplace *)t;
- if (strncmp(self->old_prefix, sb_string(key)->str, self->old_prefix_len) != 0)
+ if (strncmp(self->old_prefix, sb_gstring_string(key)->str,
+ self->old_prefix_len) != 0)
return;
- g_string_erase(sb_string(key), 0, self->old_prefix_len);
- g_string_prepend_len(sb_string(key), self->new_prefix, self->new_prefix_len);
+ g_string_erase(sb_gstring_string(key), 0, self->old_prefix_len);
+ g_string_prepend_len(sb_gstring_string(key),
+ self->new_prefix, self->new_prefix_len);
}
static void
@@ -238,11 +240,11 @@ value_pairs_transform_set_apply(ValuePairsTransformSet *vpts, gchar *key)
if (g_pattern_match_string(vpts->pattern, key))
{
GList *l;
- ScratchBuffer *sb;
+ SBGString *sb;
gchar *new_key;
- sb = scratch_buffer_acquire ();
- g_string_assign(sb_string(sb), key);
+ sb = sb_gstring_acquire ();
+ g_string_assign(sb_gstring_string(sb), key);
l = vpts->transforms;
while (l)
@@ -251,9 +253,9 @@ value_pairs_transform_set_apply(ValuePairsTransformSet *vpts, gchar *key)
l = l->next;
}
- new_key = sb_string(sb)->str;
- g_string_steal(sb_string(sb));
- scratch_buffer_release (sb);
+ new_key = sb_gstring_string(sb)->str;
+ g_string_steal(sb_gstring_string(sb));
+ sb_gstring_release (sb);
return new_key;
}
diff --git a/modules/afamqp/afamqp.c b/modules/afamqp/afamqp.c
index 70fd3e8..923f90b 100644
--- a/modules/afamqp/afamqp.c
+++ b/modules/afamqp/afamqp.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2012 Nagy, Attila <bra at fsn.hu>
- * Copyright (c) 2012 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2012 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2012-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2012-2013 Gergely Nagy <algernon at balabit.hu>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
@@ -403,8 +403,8 @@ afamqp_worker_publish(AMQPDestDriver *self, LogMessage *msg)
amqp_table_t table;
amqp_basic_properties_t props;
gboolean success = TRUE;
- ScratchBuffer *routing_key = scratch_buffer_acquire();
- ScratchBuffer *body = scratch_buffer_acquire();
+ SBGString *routing_key = sb_gstring_acquire();
+ SBGString *body = sb_gstring_acquire();
amqp_bytes_t body_bytes = amqp_cstring_bytes("");
gpointer user_data[] = { &self->entries, &pos, &self->max_entries };
@@ -422,21 +422,21 @@ afamqp_worker_publish(AMQPDestDriver *self, LogMessage *msg)
props.headers = table;
log_template_format(self->routing_key_template, msg, NULL, LTZ_LOCAL,
- self->seq_num, NULL, sb_string(routing_key));
+ self->seq_num, NULL, sb_gstring_string(routing_key));
if (self->body_template)
{
log_template_format(self->body_template, msg, NULL, LTZ_LOCAL,
- self->seq_num, NULL, sb_string(body));
- body_bytes = amqp_cstring_bytes(sb_string(body)->str);
+ self->seq_num, NULL, sb_gstring_string(body));
+ body_bytes = amqp_cstring_bytes(sb_gstring_string(body)->str);
}
ret = amqp_basic_publish(self->conn, 1, amqp_cstring_bytes(self->exchange),
- amqp_cstring_bytes(sb_string(routing_key)->str),
+ amqp_cstring_bytes(sb_gstring_string(routing_key)->str),
0, 0, &props, body_bytes);
- scratch_buffer_release(routing_key);
- scratch_buffer_release(body);
+ sb_gstring_release(routing_key);
+ sb_gstring_release(body);
if (ret < 0)
{
diff --git a/modules/json/jsonparser.c b/modules/json/jsonparser.c
index 6246fe0..82c7d1f 100644
--- a/modules/json/jsonparser.c
+++ b/modules/json/jsonparser.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2011-2012 BalaBit IT Ltd, Budapest, Hungary
- * Copyright (c) 2011-2012 Gergely Nagy <algernon at balabit.hu>
+ * Copyright (c) 2011-2013 BalaBit IT Ltd, Budapest, Hungary
+ * Copyright (c) 2011-2013 Gergely Nagy <algernon at balabit.hu>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
@@ -67,58 +67,58 @@ log_json_parser_process_single (struct json_object *jso,
const gchar *obj_key,
LogMessage *msg)
{
- ScratchBuffer *key, *value;
+ SBGString *key, *value;
gboolean parsed = FALSE;
- key = scratch_buffer_acquire ();
- value = scratch_buffer_acquire ();
+ key = sb_gstring_acquire ();
+ value = sb_gstring_acquire ();
switch (json_object_get_type (jso))
{
case json_type_boolean:
parsed = TRUE;
if (json_object_get_boolean (jso))
- g_string_assign (sb_string (value), "true");
+ g_string_assign (sb_gstring_string (value), "true");
else
- g_string_assign (sb_string (value), "false");
+ g_string_assign (sb_gstring_string (value), "false");
break;
case json_type_double:
parsed = TRUE;
- g_string_printf (sb_string (value), "%f",
+ g_string_printf (sb_gstring_string (value), "%f",
json_object_get_double (jso));
break;
case json_type_int:
parsed = TRUE;
- g_string_printf (sb_string (value), "%i",
+ g_string_printf (sb_gstring_string (value), "%i",
json_object_get_int (jso));
break;
case json_type_string:
parsed = TRUE;
- g_string_assign (sb_string (value),
+ g_string_assign (sb_gstring_string (value),
json_object_get_string (jso));
break;
case json_type_object:
if (prefix)
- g_string_assign (sb_string (key), prefix);
- g_string_append (sb_string (key), obj_key);
- g_string_append_c (sb_string (key), '.');
- log_json_parser_process_object (jso, sb_string (key)->str, msg);
+ g_string_assign (sb_gstring_string (key), prefix);
+ g_string_append (sb_gstring_string (key), obj_key);
+ g_string_append_c (sb_gstring_string (key), '.');
+ log_json_parser_process_object (jso, sb_gstring_string (key)->str, msg);
break;
case json_type_array:
{
gint i, plen;
- g_string_assign (sb_string (key), obj_key);
+ g_string_assign (sb_gstring_string (key), obj_key);
- plen = sb_string (key)->len;
+ plen = sb_gstring_string (key)->len;
for (i = 0; i < json_object_array_length (jso); i++)
{
- g_string_truncate (sb_string (key), plen);
- g_string_append_printf (sb_string (key), "[%d]", i);
+ g_string_truncate (sb_gstring_string (key), plen);
+ g_string_append_printf (sb_gstring_string (key), "[%d]", i);
log_json_parser_process_single (json_object_array_get_idx (jso, i),
prefix,
- sb_string (key)->str, msg);
+ sb_gstring_string (key)->str, msg);
}
break;
}
@@ -132,20 +132,22 @@ log_json_parser_process_single (struct json_object *jso,
{
if (prefix)
{
- g_string_assign (sb_string (key), prefix);
- g_string_append (sb_string (key), obj_key);
+ g_string_assign (sb_gstring_string (key), prefix);
+ g_string_append (sb_gstring_string (key), obj_key);
log_msg_set_value (msg,
- log_msg_get_value_handle (sb_string (key)->str),
- sb_string (value)->str, sb_string (value)->len);
+ log_msg_get_value_handle (sb_gstring_string (key)->str),
+ sb_gstring_string (value)->str,
+ sb_gstring_string (value)->len);
}
else
log_msg_set_value (msg,
log_msg_get_value_handle (obj_key),
- sb_string (value)->str, sb_string (value)->len);
+ sb_gstring_string (value)->str,
+ sb_gstring_string (value)->len);
}
- scratch_buffer_release (key);
- scratch_buffer_release (value);
+ sb_gstring_release (key);
+ sb_gstring_release (value);
}
static void
--
1.7.10.4
More information about the syslog-ng
mailing list