svn commit: samba r21076 - in branches/SAMBA_3_0/source: include lib

vlendec at samba.org vlendec at samba.org
Wed Jan 31 12:01:53 GMT 2007


Author: vlendec
Date: 2007-01-31 12:01:52 +0000 (Wed, 31 Jan 2007)
New Revision: 21076

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21076

Log:
Two pieces of infrastructure from Samba4: An API-compatible messaging wrapper
and tdb_wrap_open.

Volker

Modified:
   branches/SAMBA_3_0/source/include/util_tdb.h
   branches/SAMBA_3_0/source/lib/messages.c
   branches/SAMBA_3_0/source/lib/util_tdb.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/util_tdb.h
===================================================================
--- branches/SAMBA_3_0/source/include/util_tdb.h	2007-01-31 11:54:01 UTC (rev 21075)
+++ branches/SAMBA_3_0/source/include/util_tdb.h	2007-01-31 12:01:52 UTC (rev 21076)
@@ -35,6 +35,11 @@
 	TDB_DATA node_key;
 } TDB_LIST_NODE;
 
+struct tdb_wrap {
+	struct tdb_context *tdb;
+	const char *name;
+	struct tdb_wrap *next, *prev;
+};
 
 TDB_LIST_NODE *tdb_search_keys(struct tdb_context*, const char*);
 void tdb_search_list_free(TDB_LIST_NODE*);

Modified: branches/SAMBA_3_0/source/lib/messages.c
===================================================================
--- branches/SAMBA_3_0/source/lib/messages.c	2007-01-31 11:54:01 UTC (rev 21075)
+++ branches/SAMBA_3_0/source/lib/messages.c	2007-01-31 12:01:52 UTC (rev 21076)
@@ -678,4 +678,125 @@
 {
 	BlockSignals(False, SIGUSR1);
 }
+
+/*
+ * Samba4 API wrapper around the Samba3 implementation. Yes, I know, we could
+ * import the whole Samba4 thing, but I want notify.c from Samba4 in first.
+ */
+
+struct messaging_callback {
+	struct messaging_callback *prev, *next;
+	uint32 msg_type;
+	void (*fn)(struct messaging_context *msg, void *private_data, 
+		   uint32_t msg_type, 
+		   struct server_id server_id, DATA_BLOB *data);
+	void *private_data;
+};
+
+struct messaging_context {
+	struct server_id id;
+	struct messaging_callback *callbacks;
+};
+
+static int messaging_context_destructor(struct messaging_context *ctx)
+{
+	struct messaging_callback *cb;
+
+	for (cb = ctx->callbacks; cb; cb = cb->next) {
+		/*
+		 * We unconditionally remove all instances of our callback
+		 * from the tdb basis.
+		 */
+		message_deregister(cb->msg_type);
+	}
+	return 0;
+}
+
+struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, 
+					 struct server_id server_id, 
+					 struct event_context *ev)
+{
+	struct messaging_context *ctx;
+
+	if (!(ctx = TALLOC_ZERO_P(mem_ctx, struct messaging_context))) {
+		return NULL;
+	}
+
+	ctx->id = server_id;
+	talloc_set_destructor(ctx, messaging_context_destructor);
+	return ctx;
+}
+
+static void messaging_callback(int msg_type, struct process_id pid,
+			       void *buf, size_t len, void *private_data)
+{
+	struct messaging_context *ctx =	talloc_get_type_abort(
+		private_data, struct messaging_context);
+	struct messaging_callback *cb, *next;
+
+	for (cb = ctx->callbacks; cb; cb = next) {
+		/*
+		 * Allow a callback to remove itself
+		 */
+		next = cb->next;
+
+		if (msg_type == cb->msg_type) {
+			DATA_BLOB blob;
+			struct server_id id;
+
+			blob.data = (uint8 *)buf;
+			blob.length = len;
+			id.id = pid;
+
+			cb->fn(ctx, cb->private_data, msg_type, id, &blob);
+		}
+	}
+}
+
+/*
+ * Register a dispatch function for a particular message type. Allow multiple
+ * registrants
+*/
+NTSTATUS messaging_register(struct messaging_context *ctx, void *private_data,
+			    uint32_t msg_type,
+			    void (*fn)(struct messaging_context *msg,
+				       void *private_data, 
+				       uint32_t msg_type, 
+				       struct server_id server_id,
+				       DATA_BLOB *data))
+{
+	struct messaging_callback *cb;
+
+	if (!(cb = talloc(ctx, struct messaging_callback))) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	cb->msg_type = msg_type;
+	cb->fn = fn;
+	cb->private_data = private_data;
+
+	DLIST_ADD(ctx->callbacks, cb);
+	message_register(msg_type, messaging_callback, ctx);
+	return NT_STATUS_OK;
+}
+
+/*
+  De-register the function for a particular message type.
+*/
+void messaging_deregister(struct messaging_context *ctx, uint32_t msg_type,
+			  void *private_data)
+{
+	struct messaging_callback *cb, *next;
+
+	for (cb = ctx->callbacks; cb; cb = next) {
+		next = cb->next;
+		if ((cb->msg_type == msg_type)
+		    && (cb->private_data == private_data)) {
+			DLIST_REMOVE(ctx->callbacks, cb);
+			TALLOC_FREE(cb);
+		}
+	}
+}
+
+
 /** @} **/

Modified: branches/SAMBA_3_0/source/lib/util_tdb.c
===================================================================
--- branches/SAMBA_3_0/source/lib/util_tdb.c	2007-01-31 11:54:01 UTC (rev 21075)
+++ branches/SAMBA_3_0/source/lib/util_tdb.c	2007-01-31 12:01:52 UTC (rev 21076)
@@ -846,3 +846,101 @@
 
 	return res;
 }
+
+/*
+ Log tdb messages via DEBUG().
+*/
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
+			 const char *format, ...) PRINTF_ATTRIBUTE(3,4);
+
+static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, 
+			 const char *format, ...)
+{
+	va_list ap;
+	char *ptr = NULL;
+	int debuglevel = 0;
+
+	va_start(ap, format);
+	vasprintf(&ptr, format, ap);
+	va_end(ap);
+	
+	switch (level) {
+	case TDB_DEBUG_FATAL:
+		debug_level = 0;
+		break;
+	case TDB_DEBUG_ERROR:
+		debuglevel = 1;
+		break;
+	case TDB_DEBUG_WARNING:
+		debuglevel = 2;
+		break;
+	case TDB_DEBUG_TRACE:
+		debuglevel = 5;
+		break;
+	default:
+		debuglevel = 0;
+	}		
+
+	if (ptr != NULL) {
+		const char *name = tdb_name(tdb);
+		DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr));
+		free(ptr);
+	}
+}
+
+static struct tdb_wrap *tdb_list;
+
+/* destroy the last connection to a tdb */
+static int tdb_wrap_destructor(struct tdb_wrap *w)
+{
+	tdb_close(w->tdb);
+	DLIST_REMOVE(tdb_list, w);
+	return 0;
+}				 
+
+/*
+  wrapped connection to a tdb database
+  to close just talloc_free() the tdb_wrap pointer
+ */
+struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx,
+			       const char *name, int hash_size, int tdb_flags,
+			       int open_flags, mode_t mode)
+{
+	struct tdb_wrap *w;
+	struct tdb_logging_context log_ctx;
+	log_ctx.log_fn = tdb_wrap_log;
+
+	for (w=tdb_list;w;w=w->next) {
+		if (strcmp(name, w->name) == 0) {
+			/*
+			 * Yes, talloc_reference is exactly what we want
+			 * here. Otherwise we would have to implement our own
+			 * reference counting.
+			 */
+			return talloc_reference(mem_ctx, w);
+		}
+	}
+
+	w = talloc(mem_ctx, struct tdb_wrap);
+	if (w == NULL) {
+		return NULL;
+	}
+
+	if (!(w->name = talloc_strdup(w, name))) {
+		talloc_free(w);
+		return NULL;
+	}
+
+	w->tdb = tdb_open_ex(name, hash_size, tdb_flags, 
+			     open_flags, mode, &log_ctx, NULL);
+	if (w->tdb == NULL) {
+		talloc_free(w);
+		return NULL;
+	}
+
+	talloc_set_destructor(w, tdb_wrap_destructor);
+
+	DLIST_ADD(tdb_list, w);
+
+	return w;
+}



More information about the samba-cvs mailing list