[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-493-ge95d0b5

Stefan Metzmacher metze at samba.org
Tue Mar 17 19:31:19 GMT 2009


The branch, master has been updated
       via  e95d0b548e344dbc8cb3dd0a0f29854711bd0cac (commit)
       via  7d07266ca26f7069269601043b713a91f1a4693c (commit)
       via  9eaf53d98eced9ea70f411b9936b475c42e4d490 (commit)
       via  3a831e46204979550dc6ee7652cea6b8296f10c1 (commit)
       via  4bdf299385220988a4fe16f82aab528283204c7f (commit)
       via  a78cd2a24b818bc7d843a8e56ffaafc9f6578662 (commit)
       via  6c290586e41b3f5f7748a5b8c782be67cafe6c57 (commit)
       via  66886f8966dff8a980a5b9d2daa3fbb20fe5ca8e (commit)
       via  d27be1d5fa3fdcaac07b527ad14b0d10ef27c0bb (commit)
       via  940e61846e97ba62153d5b977b0823f196607743 (commit)
       via  0139befb915006d6ec9fec2734057c5c50b3c383 (commit)
       via  3af7db3dce0e5529114f6969e9905c6d4c65dfe8 (commit)
      from  77d2cd1ff7dab3a7a76449bfb3fe1d6e80df292b (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit e95d0b548e344dbc8cb3dd0a0f29854711bd0cac
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 20:18:31 2009 +0100

    s4:build: require tevent 0.9.5
    
    metze

commit 7d07266ca26f7069269601043b713a91f1a4693c
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 20:18:01 2009 +0100

    tevent: change version to 0.9.5 after the ABI has changed
    
    metze

commit 9eaf53d98eced9ea70f411b9936b475c42e4d490
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 20:13:34 2009 +0100

    tevent: store the location where a request was finished
    
    This is very useful to find bugs.
    You can use 'p *req' in gdb to show where
    tevent_req_done(), tevent_req_error() or tevent_req_nomem()
    was called.
    
    metze

commit 3a831e46204979550dc6ee7652cea6b8296f10c1
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 10:42:55 2009 +0100

    tevent: use an immediate event as trigger for tevent_queue
    
    metze

commit 4bdf299385220988a4fe16f82aab528283204c7f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 10:18:34 2009 +0100

    tevent: use an immediate event fot tevent_req_post()
    
    Now tevent_req_post() never fails
    
    metze

commit a78cd2a24b818bc7d843a8e56ffaafc9f6578662
Author: Stefan Metzmacher <metze at samba.org>
Date:   Tue Mar 17 10:17:50 2009 +0100

    tevent: use TALLOC_FREE() in tevent_req.c
    
    metze

commit 6c290586e41b3f5f7748a5b8c782be67cafe6c57
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 16 15:06:52 2009 +0100

    s3:events: add support for immediate events
    
    metze

commit 66886f8966dff8a980a5b9d2daa3fbb20fe5ca8e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Mar 13 15:47:33 2009 +0100

    tevent: add support for immediate events
    
    They're like directly triggered timed events,
    but you can preallocated them and scheduling them
    will not fail.
    
    metze

commit d27be1d5fa3fdcaac07b527ad14b0d10ef27c0bb
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 16 14:45:42 2009 +0100

    s3:events: make use of tevent_common_loop_wait()
    
    metze

commit 940e61846e97ba62153d5b977b0823f196607743
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 16 14:15:07 2009 +0100

    tevent: add tevent_common_loop_wait() helper function and use it
    
    tevent_loop_wait should do the same for all backends.
    It should loop as long as we have pending events.
    
    metze

commit 0139befb915006d6ec9fec2734057c5c50b3c383
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 16 12:45:48 2009 +0100

    tevent: check signal events first in event_loop_once
    
    We also check for signal events directly before and after
    the select/epoll calls.
    
    metze

commit 3af7db3dce0e5529114f6969e9905c6d4c65dfe8
Author: Stefan Metzmacher <metze at samba.org>
Date:   Mon Mar 16 12:34:23 2009 +0100

    tevent: let tevent_loop_once() just run one fd event
    
    This makes the logic much simpler for the callers,
    and matches the samba3 behavior.
    
    If needed we can add performance tunning for tevent_loop_wait()
    later.
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 lib/tevent/configure.ac       |    2 +-
 lib/tevent/libtevent.m4       |    3 +-
 lib/tevent/tevent.c           |   77 +++++++++++++++++++++++
 lib/tevent/tevent.h           |   41 ++++++++++--
 lib/tevent/tevent_epoll.c     |   62 +++++++------------
 lib/tevent/tevent_immediate.c |  139 +++++++++++++++++++++++++++++++++++++++++
 lib/tevent/tevent_internal.h  |   53 +++++++++++++++-
 lib/tevent/tevent_queue.c     |   99 +++++++++++++++++------------
 lib/tevent/tevent_req.c       |   74 +++++++++++-----------
 lib/tevent/tevent_select.c    |   60 +++++++-----------
 lib/tevent/tevent_standard.c  |   69 +++++++--------------
 source3/lib/events.c          |   35 +++++------
 source4/min_versions.m4       |    2 +-
 13 files changed, 482 insertions(+), 234 deletions(-)
 create mode 100644 lib/tevent/tevent_immediate.c


Changeset truncated at 500 lines:

diff --git a/lib/tevent/configure.ac b/lib/tevent/configure.ac
index 69f65c6..171a408 100644
--- a/lib/tevent/configure.ac
+++ b/lib/tevent/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.50)
-AC_INIT(tevent, 0.9.4)
+AC_INIT(tevent, 0.9.5)
 AC_CONFIG_SRCDIR([tevent.c])
 AC_CONFIG_HEADER(config.h)
 
diff --git a/lib/tevent/libtevent.m4 b/lib/tevent/libtevent.m4
index c316823..20730b1 100644
--- a/lib/tevent/libtevent.m4
+++ b/lib/tevent/libtevent.m4
@@ -26,7 +26,8 @@ AC_SUBST(TEVENT_LIBS)
 
 TEVENT_CFLAGS="-I$teventdir"
 
-TEVENT_OBJ="tevent.o tevent_fd.o tevent_timed.o tevent_signal.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="tevent.o tevent_debug.o tevent_util.o"
+TEVENT_OBJ="$TEVENT_OBJ tevent_fd.o tevent_timed.o tevent_immediate.o tevent_signal.o"
 TEVENT_OBJ="$TEVENT_OBJ tevent_req.o tevent_wakeup.o tevent_queue.o"
 TEVENT_OBJ="$TEVENT_OBJ tevent_standard.o tevent_select.o"
 
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index 867cfc0..ba2d93f 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -143,6 +143,7 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 {
 	struct tevent_fd *fd, *fn;
 	struct tevent_timer *te, *tn;
+	struct tevent_immediate *ie, *in;
 	struct tevent_signal *se, *sn;
 
 	if (ev->pipe_fde) {
@@ -162,6 +163,13 @@ int tevent_common_context_destructor(struct tevent_context *ev)
 		DLIST_REMOVE(ev->timer_events, te);
 	}
 
+	for (ie = ev->immediate_events; ie; ie = in) {
+		in = ie->next;
+		ie->event_ctx = NULL;
+		ie->cancel_fn = NULL;
+		DLIST_REMOVE(ev->immediate_events, ie);
+	}
+
 	for (se = ev->signal_events; se; se = sn) {
 		sn = se->next;
 		se->event_ctx = NULL;
@@ -350,6 +358,47 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
 }
 
 /*
+  allocate an immediate event
+  return NULL on failure (memory allocation error)
+*/
+struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
+						  const char *location)
+{
+	struct tevent_immediate *im;
+
+	im = talloc(mem_ctx, struct tevent_immediate);
+	if (im == NULL) return NULL;
+
+	im->prev		= NULL;
+	im->next		= NULL;
+	im->event_ctx		= NULL;
+	im->create_location	= location;
+	im->handler		= NULL;
+	im->private_data	= NULL;
+	im->handler_name	= NULL;
+	im->schedule_location	= NULL;
+	im->cancel_fn		= NULL;
+	im->additional_data	= NULL;
+
+	return im;
+}
+
+/*
+  schedule an immediate event
+  return NULL on failure
+*/
+void _tevent_schedule_immediate(struct tevent_immediate *im,
+				struct tevent_context *ev,
+				tevent_immediate_handler_t handler,
+				void *private_data,
+				const char *handler_name,
+				const char *location)
+{
+	ev->ops->schedule_immediate(im, ev, handler, private_data,
+				    handler_name, location);
+}
+
+/*
   add a signal event
 
   sa_flags are flags to sigaction(2)
@@ -514,6 +563,34 @@ done:
 /*
   return on failure or (with 0) if all fd events are removed
 */
+int tevent_common_loop_wait(struct tevent_context *ev,
+			    const char *location)
+{
+	/*
+	 * loop as long as we have events pending
+	 */
+	while (ev->fd_events ||
+	       ev->timer_events ||
+	       ev->immediate_events ||
+	       ev->signal_events) {
+		int ret;
+		ret = _tevent_loop_once(ev, location);
+		if (ret != 0) {
+			tevent_debug(ev, TEVENT_DEBUG_FATAL,
+				     "_tevent_loop_once() failed: %d - %s\n",
+				     ret, strerror(errno));
+			return ret;
+		}
+	}
+
+	tevent_debug(ev, TEVENT_DEBUG_WARNING,
+		     "tevent_common_loop_wait() out of events\n");
+	return 0;
+}
+
+/*
+  return on failure or (with 0) if all fd events are removed
+*/
 int _tevent_loop_wait(struct tevent_context *ev, const char *location)
 {
 	return ev->ops->loop_wait(ev, location);
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 4a3f51a..6c5df63 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -37,6 +37,7 @@ struct tevent_context;
 struct tevent_ops;
 struct tevent_fd;
 struct tevent_timer;
+struct tevent_immediate;
 struct tevent_signal;
 
 /* event handler types */
@@ -52,6 +53,9 @@ typedef void (*tevent_timer_handler_t)(struct tevent_context *ev,
 				       struct tevent_timer *te,
 				       struct timeval current_time,
 				       void *private_data);
+typedef void (*tevent_immediate_handler_t)(struct tevent_context *ctx,
+					   struct tevent_immediate *im,
+					   void *private_data);
 typedef void (*tevent_signal_handler_t)(struct tevent_context *ev,
 					struct tevent_signal *se,
 					int signum,
@@ -87,6 +91,21 @@ struct tevent_timer *_tevent_add_timer(struct tevent_context *ev,
 	_tevent_add_timer(ev, mem_ctx, next_event, handler, private_data, \
 			  #handler, __location__)
 
+struct tevent_immediate *_tevent_create_immediate(TALLOC_CTX *mem_ctx,
+						  const char *location);
+#define tevent_create_immediate(mem_ctx) \
+	_tevent_create_immediate(mem_ctx, __location__)
+
+void _tevent_schedule_immediate(struct tevent_immediate *im,
+				struct tevent_context *ctx,
+				tevent_immediate_handler_t handler,
+				void *private_data,
+				const char *handler_name,
+				const char *location);
+#define tevent_schedule_immediate(im, ctx, handler, private_data) \
+	_tevent_schedule_immediate(im, ctx, handler, private_data, \
+				   #handler, __location__);
+
 struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
 					 TALLOC_CTX *mem_ctx,
 					 int signum,
@@ -233,13 +252,22 @@ bool tevent_req_set_endtime(struct tevent_req *req,
 			    struct tevent_context *ev,
 			    struct timeval endtime);
 
-void tevent_req_done(struct tevent_req *req);
+void _tevent_req_done(struct tevent_req *req,
+		      const char *location);
+#define tevent_req_done(req) \
+	_tevent_req_done(req, __location__)
 
-bool tevent_req_error(struct tevent_req *req,
-		      uint64_t error);
+bool _tevent_req_error(struct tevent_req *req,
+		       uint64_t error,
+		       const char *location);
+#define tevent_req_error(req, error) \
+	_tevent_req_error(req, error, __location__)
 
-bool tevent_req_nomem(const void *p,
-		      struct tevent_req *req);
+bool _tevent_req_nomem(const void *p,
+		       struct tevent_req *req,
+		       const char *location);
+#define tevent_req_nomem(p, req) \
+	_tevent_req_nomem(p, req, __location__)
 
 struct tevent_req *tevent_req_post(struct tevent_req *req,
 				   struct tevent_context *ev);
@@ -295,8 +323,7 @@ bool tevent_queue_add(struct tevent_queue *queue,
 		      struct tevent_req *req,
 		      tevent_queue_trigger_fn_t trigger,
 		      void *private_data);
-bool tevent_queue_start(struct tevent_queue *queue,
-			struct tevent_context *ev);
+void tevent_queue_start(struct tevent_queue *queue);
 void tevent_queue_stop(struct tevent_queue *queue);
 
 size_t tevent_queue_length(struct tevent_queue *queue);
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index b63d299..7c7f389 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -35,14 +35,6 @@ struct epoll_event_context {
 	/* a pointer back to the generic event_context */
 	struct tevent_context *ev;
 
-	/* this is changed by the destructors for the fd event
-	   type. It is used to detect event destruction by event
-	   handlers, which means the code that is calling the event
-	   handler needs to assume that the linked list is no longer
-	   valid
-	*/
-	uint32_t destruction_count;
-
 	/* when using epoll this is the handle from epoll_create */
 	int epoll_fd;
 
@@ -242,9 +234,8 @@ static void epoll_change_event(struct epoll_event_context *epoll_ev, struct teve
 static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval *tvalp)
 {
 	int ret, i;
-#define MAXEVENTS 32
+#define MAXEVENTS 1
 	struct epoll_event events[MAXEVENTS];
-	uint32_t destruction_count = ++epoll_ev->destruction_count;
 	int timeout = -1;
 
 	if (epoll_ev->epoll_fd == -1) return -1;
@@ -305,9 +296,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
 		if (events[i].events & EPOLLOUT) flags |= TEVENT_FD_WRITE;
 		if (flags) {
 			fde->handler(epoll_ev->ev, fde, flags, fde->private_data);
-			if (destruction_count != epoll_ev->destruction_count) {
-				break;
-			}
+			break;
 		}
 	}
 
@@ -351,8 +340,6 @@ static int epoll_event_fd_destructor(struct tevent_fd *fde)
 
 		epoll_check_reopen(epoll_ev);
 
-		epoll_ev->destruction_count++;
-
 		epoll_del_event(epoll_ev, fde);
 	}
 
@@ -417,6 +404,16 @@ static int epoll_event_loop_once(struct tevent_context *ev, const char *location
 		 					   struct epoll_event_context);
 	struct timeval tval;
 
+	if (ev->signal_events &&
+	    tevent_common_check_signal(ev)) {
+		return 0;
+	}
+
+	if (ev->immediate_events &&
+	    tevent_common_loop_immediate(ev)) {
+		return 0;
+	}
+
 	tval = tevent_common_loop_timer_delay(ev);
 	if (tevent_timeval_is_zero(&tval)) {
 		return 0;
@@ -427,32 +424,17 @@ static int epoll_event_loop_once(struct tevent_context *ev, const char *location
 	return epoll_event_loop(epoll_ev, &tval);
 }
 
-/*
-  return on failure or (with 0) if all fd events are removed
-*/
-static int epoll_event_loop_wait(struct tevent_context *ev, const char *location)
-{
-	struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data,
-							   struct epoll_event_context);
-	while (epoll_ev->ev->fd_events) {
-		if (epoll_event_loop_once(ev, location) != 0) {
-			break;
-		}
-	}
-
-	return 0;
-}
-
 static const struct tevent_ops epoll_event_ops = {
-	.context_init	= epoll_event_context_init,
-	.add_fd		= epoll_event_add_fd,
-	.set_fd_close_fn= tevent_common_fd_set_close_fn,
-	.get_fd_flags	= tevent_common_fd_get_flags,
-	.set_fd_flags	= epoll_event_set_fd_flags,
-	.add_timer	= tevent_common_add_timer,
-	.add_signal	= tevent_common_add_signal,
-	.loop_once	= epoll_event_loop_once,
-	.loop_wait	= epoll_event_loop_wait,
+	.context_init		= epoll_event_context_init,
+	.add_fd			= epoll_event_add_fd,
+	.set_fd_close_fn	= tevent_common_fd_set_close_fn,
+	.get_fd_flags		= tevent_common_fd_get_flags,
+	.set_fd_flags		= epoll_event_set_fd_flags,
+	.add_timer		= tevent_common_add_timer,
+	.schedule_immediate	= tevent_common_schedule_immediate,
+	.add_signal		= tevent_common_add_signal,
+	.loop_once		= epoll_event_loop_once,
+	.loop_wait		= tevent_common_loop_wait,
 };
 
 bool tevent_epoll_init(void)
diff --git a/lib/tevent/tevent_immediate.c b/lib/tevent/tevent_immediate.c
new file mode 100644
index 0000000..1ac293e
--- /dev/null
+++ b/lib/tevent/tevent_immediate.c
@@ -0,0 +1,139 @@
+/*
+   Unix SMB/CIFS implementation.
+
+   common events code for immediate events
+
+   Copyright (C) Stefan Metzmacher 2009
+
+     ** NOTE! The following LGPL license applies to the tevent
+     ** library. This does NOT imply that all of Samba is released
+     ** under the LGPL
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "tevent.h"
+#include "tevent_internal.h"
+#include "tevent_util.h"
+
+static void tevent_common_immediate_cancel(struct tevent_immediate *im)
+{
+	if (!im->event_ctx) {
+		return;
+	}
+
+	tevent_debug(im->event_ctx, TEVENT_DEBUG_TRACE,
+		     "Cancel immediate event %p \"%s\"\n",
+		     im, im->handler_name);
+
+	/* let the backend free im->additional_data */
+	if (im->cancel_fn) {
+		im->cancel_fn(im);
+	}
+
+	DLIST_REMOVE(im->event_ctx->immediate_events, im);
+	im->event_ctx		= NULL;
+	im->handler		= NULL;
+	im->private_data	= NULL;
+	im->handler_name	= NULL;
+	im->schedule_location	= NULL;
+	im->cancel_fn		= NULL;
+	im->additional_data	= NULL;
+
+	talloc_set_destructor(im, NULL);
+}
+
+/*
+  destroy an immediate event
+*/
+static int tevent_common_immediate_destructor(struct tevent_immediate *im)
+{
+	tevent_common_immediate_cancel(im);
+	return 0;
+}
+
+/*
+ * schedule an immediate event on
+ */
+void tevent_common_schedule_immediate(struct tevent_immediate *im,
+				      struct tevent_context *ev,
+				      tevent_immediate_handler_t handler,
+				      void *private_data,
+				      const char *handler_name,
+				      const char *location)
+{
+	tevent_common_immediate_cancel(im);
+
+	if (!handler) {
+		return;
+	}
+
+	im->event_ctx		= ev;
+	im->handler		= handler;
+	im->private_data	= private_data;
+	im->handler_name	= handler_name;
+	im->schedule_location	= location;
+	im->cancel_fn		= NULL;
+	im->additional_data	= NULL;
+
+	DLIST_ADD_END(ev->immediate_events, im, struct tevent_immediate *);
+	talloc_set_destructor(im, tevent_common_immediate_destructor);
+
+	tevent_debug(ev, TEVENT_DEBUG_TRACE,
+		     "Schedule immediate event \"%s\": %p\n",
+		     handler_name, im);
+}
+
+/*
+  trigger the first immediate event and return true
+  if no event was triggered return false
+*/
+bool tevent_common_loop_immediate(struct tevent_context *ev)
+{
+	struct tevent_immediate *im = ev->immediate_events;
+	tevent_immediate_handler_t handler;
+	void *private_data;
+
+	if (!im) {
+		return false;
+	}
+
+	tevent_debug(ev, TEVENT_DEBUG_TRACE,
+		     "Run immediate event \"%s\": %p\n",
+		     im->handler_name, im);
+
+	/*
+	 * remember the handler and then clear the event
+	 * the handler might reschedule the event
+	 */
+	handler = im->handler;
+	private_data = im->private_data;
+
+	DLIST_REMOVE(im->event_ctx->immediate_events, im);
+	im->event_ctx		= NULL;
+	im->handler		= NULL;
+	im->private_data	= NULL;
+	im->handler_name	= NULL;
+	im->schedule_location	= NULL;
+	im->cancel_fn		= NULL;
+	im->additional_data	= NULL;
+
+	talloc_set_destructor(im, NULL);
+
+	handler(ev, im, private_data);
+
+	return true;
+}
+
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index f104853..eebf767 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -85,7 +85,17 @@ struct tevent_req {
 		 *
 		 * This for debugging only.
 		 */
-		const char *location;
+		const char *create_location;
+
+		/**
+		 * @brief The location where the request was finished
+		 *
+		 * This uses the __location__ macro via the tevent_req_done(),
+		 * tevent_req_error() or tevent_req_nomem() macro.
+		 *
+		 * This for debugging only.
+		 */
+		const char *finish_location;
 
 		/**
 		 * @brief The external state - will be queried by the caller
@@ -105,10 +115,10 @@ struct tevent_req {
 		uint64_t error;
 
 		/**
-		 * @brief the timer event if tevent_req_post was used
+		 * @brief the immediate event used by tevent_req_post


-- 
Samba Shared Repository


More information about the samba-cvs mailing list