[PATCHES] some new tevent features
Volker Lendecke
Volker.Lendecke at SerNet.DE
Fri Jan 17 04:20:42 MST 2014
On Fri, Jan 17, 2014 at 11:50:44AM +0100, Volker Lendecke wrote:
> On Mon, Jan 13, 2014 at 09:11:42PM +0100, Stefan (metze) Metzmacher wrote:
> > Hi Volker,
> >
> > >>>> static int smbXcli_req_destructor(struct tevent_req *req)
> > >>>> static int fncall_destructor(struct tevent_req *req)
> > >>>> static int tldap_msg_destructor(struct tevent_req *req)
> > >>>
> > >>> Thanks for checking. Maybe I was a bit worried because 2 of
> > >>> those are mine ... :-)
> > >>
> > >> Can you review the attached patches?
> > >
> > > Please don't push this patches yet, I'm currently debugging a possible
> > > problem...
> >
> > There was a bug in the interaction with tevent_req_defer_callback()
> > and tevent_req_set_cleanup_fn().
> >
> > This bug is fixed in the attached patchset (it's also a bit cleaner this
> > way).
> > We rely the tevent_req_state enum being sorted, we only trigger
> > the cleanup function once per state and remember the last state
> > and skip the cleanup function on the 2nd call.
>
> Pushed to master with a little re-wording in doxygen:
Ok, stopped the autobuild and created a new patchset with
your requested changes.
Feel free to push.
Thanks,
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 3f2a682a28f674eb4e660c6a1a5cc7ec35959848 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Sat, 11 Jan 2014 08:58:05 +0100
Subject: [PATCH 01/11] tevent: fix crash bug in
tevent_queue_immediate_trigger()
Assume we we have a queue with 2 entries (A and B with triggerA() and triggerB()).
If triggerA() removes itself tevent_queue_entry_destructor() will be called
for A, this schedules the immediate event to call triggerB().
If triggerA() then also removes B by an explicit of implizit talloc_free(),
q->list is NULL, but the immediate event is still scheduled and can't be unscheduled.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
lib/tevent/tevent_queue.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c
index 930319c..35742e5 100644
--- a/lib/tevent/tevent_queue.c
+++ b/lib/tevent/tevent_queue.c
@@ -141,6 +141,10 @@ static void tevent_queue_immediate_trigger(struct tevent_context *ev,
return;
}
+ if (!q->list) {
+ return;
+ }
+
q->list->triggered = true;
q->list->trigger(q->list->req, q->list->private_data);
}
--
1.7.9.5
From bfb822b1504538d7d623665238c5bb0809ae758e Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 13 Dec 2013 11:59:43 +0100
Subject: [PATCH 02/11] tevent: Only build "std_fallback_to_poll" when epoll
is around
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
lib/tevent/tevent_standard.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c
index 785d68d..a050901 100644
--- a/lib/tevent/tevent_standard.c
+++ b/lib/tevent/tevent_standard.c
@@ -54,6 +54,7 @@ static const struct tevent_ops std_event_ops = {
Move us to using poll instead. If we return false here,
caller should abort().
*/
+#ifdef HAVE_EPOLL
static bool std_fallback_to_poll(struct tevent_context *ev, bool replay)
{
void *glue_ptr = talloc_parent(ev->ops);
@@ -100,6 +101,7 @@ static bool std_fallback_to_poll(struct tevent_context *ev, bool replay)
return true;
}
+#endif
static int std_event_loop_once(struct tevent_context *ev, const char *location)
{
--
1.7.9.5
From a74531a190f7f7e7dac249773076232f34acf0f3 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 13 Dec 2013 11:59:04 +0100
Subject: [PATCH 03/11] tevent: Add prototypes
... doxygen docs to be filled in :-)
Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
lib/tevent/tevent.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 0705ff3..3f8e081 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -340,6 +340,10 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
#handler, __location__)
#endif
+size_t tevent_num_signals(void);
+
+size_t tevent_sa_info_queue_count(void);
+
#ifdef DOXYGEN
/**
* @brief Pass a single time through the mainloop
--
1.7.9.5
From 1c837003cad3eafcea1fb34f67db2de673d7f9bf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 8 Jan 2014 10:01:56 +0100
Subject: [PATCH 04/11] tevent: add doxygen comments for tevent_num_signals()
and tevent_sa_info_queue_count()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
lib/tevent/tevent.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index 3f8e081..d7d4f19 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -319,6 +319,8 @@ void _tevent_schedule_immediate(struct tevent_immediate *im,
*
* @note To cancel a signal handler, call talloc_free() on the event returned
* from this function.
+ *
+ * @see tevent_num_signals, tevent_sa_info_queue_count
*/
struct tevent_signal *tevent_add_signal(struct tevent_context *ev,
TALLOC_CTX *mem_ctx,
@@ -340,8 +342,29 @@ struct tevent_signal *_tevent_add_signal(struct tevent_context *ev,
#handler, __location__)
#endif
+/**
+ * @brief the number of supported signals
+ *
+ * This returns value of the configure time TEVENT_NUM_SIGNALS constant.
+ *
+ * The 'signum' argument of tevent_add_signal() must be less than
+ * TEVENT_NUM_SIGNALS.
+ *
+ * @see tevent_add_signal
+ */
size_t tevent_num_signals(void);
+/**
+ * @brief the number of pending realtime signals
+ *
+ * This returns value of TEVENT_SA_INFO_QUEUE_COUNT.
+ *
+ * The tevent internals remember the last TEVENT_SA_INFO_QUEUE_COUNT
+ * siginfo_t structures for SA_SIGINFO signals. If the system generates
+ * more some signals get lost.
+ *
+ * @see tevent_add_signal
+ */
size_t tevent_sa_info_queue_count(void);
#ifdef DOXYGEN
--
1.7.9.5
From 573e534d25676f40d726f0ae0c4357267fa76529 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 27 Sep 2013 03:41:29 +0200
Subject: [PATCH 05/11] tevent: add/use tevent_req_destructor
This makes sure we call tevent_req_received(req) on talloc_free()
and cleanup things in a defined order.
Note that some callers used their own destructor for their
tevent_req instance, they'll just overwrite this,
which is not intended, but works without problems.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
lib/tevent/tevent_req.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c
index edb8550..30e91e2 100644
--- a/lib/tevent/tevent_req.c
+++ b/lib/tevent/tevent_req.c
@@ -51,6 +51,8 @@ char *tevent_req_print(TALLOC_CTX *mem_ctx, struct tevent_req *req)
return req->private_print(req, mem_ctx);
}
+static int tevent_req_destructor(struct tevent_req *req);
+
struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
void *pdata,
size_t data_size,
@@ -86,10 +88,18 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx,
req->data = data;
+ talloc_set_destructor(req, tevent_req_destructor);
+
*ppdata = data;
return req;
}
+static int tevent_req_destructor(struct tevent_req *req)
+{
+ tevent_req_received(req);
+ return 0;
+}
+
void _tevent_req_notify_callback(struct tevent_req *req, const char *location)
{
req->internal.finish_location = location;
@@ -200,7 +210,8 @@ bool tevent_req_is_in_progress(struct tevent_req *req)
void tevent_req_received(struct tevent_req *req)
{
- TALLOC_FREE(req->data);
+ talloc_set_destructor(req, NULL);
+
req->private_print = NULL;
req->private_cancel = NULL;
@@ -208,6 +219,8 @@ void tevent_req_received(struct tevent_req *req)
TALLOC_FREE(req->internal.timer);
req->internal.state = TEVENT_REQ_RECEIVED;
+
+ TALLOC_FREE(req->data);
}
bool tevent_req_poll(struct tevent_req *req,
--
1.7.9.5
From 01d95caacfa6b010fd0a2a8740fb8c238e0e3478 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 27 Sep 2013 02:29:57 +0200
Subject: [PATCH 06/11] tevent: add tevent_req_set_cleanup_fn()
Note that some callers used their own destructor for their
tevent_req instance, they'll just overwrite this,
which is not intended, but works without problems.
The intended way is to specify a cleanup function
and handle the TEVENT_REQ_RECEIVED state as destructor.
Note that the TEVENT_REQ_RECEIVED cleanup event might
be triggered by an explicit tevent_req_received()
in the _recv() function. The TEVENT_REQ_RECEIVED event
is only triggered once as tevent_req_received()
will remove the destructor.
So the difference compared to a custom destructor
is that the struct tevent_req itself can continue
to be there, while tevent_req_received() removed
all internal state.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
lib/tevent/tevent.h | 35 +++++++++++++++++++++++++++++++++++
lib/tevent/tevent_internal.h | 12 ++++++++++++
lib/tevent/tevent_req.c | 30 ++++++++++++++++++++++++++++++
3 files changed, 77 insertions(+)
diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h
index d7d4f19..c54cbe2 100644
--- a/lib/tevent/tevent.h
+++ b/lib/tevent/tevent.h
@@ -934,6 +934,41 @@ bool _tevent_req_cancel(struct tevent_req *req, const char *location);
_tevent_req_cancel(req, __location__)
#endif
+/**
+ * @brief A typedef for a cleanup function for a tevent request.
+ *
+ * @param[in] req The tevent request calling this function.
+ *
+ * @param[in] req_state The current tevent_req_state.
+ *
+ */
+typedef void (*tevent_req_cleanup_fn)(struct tevent_req *req,
+ enum tevent_req_state req_state);
+
+/**
+ * @brief This function sets a cleanup function for the given tevent request.
+ *
+ * This function can be used to setup a cleanup function for the given request.
+ * This will be triggered when the tevent_req_done() or tevent_req_error()
+ * function was called, before notifying the callers callback function,
+ * and also before scheduling the deferred trigger.
+ *
+ * This might be useful if more than one tevent_req belong together
+ * and need to finish both requests at the same time.
+ *
+ * The cleanup function is able to call tevent_req_done() or tevent_req_error()
+ * recursively, the cleanup function is only triggered the first time.
+ *
+ * The cleanup function is also called by tevent_req_received()
+ * (possibly triggered from tevent_req_destructor()) before destroying
+ * the private data of the tevent_req.
+ *
+ * @param[in] req The request to use.
+ *
+ * @param[in] fn A pointer to the cancel function.
+ */
+void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn);
+
#ifdef DOXYGEN
/**
* @brief Create an async tevent request.
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index df73288..d25dc05 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -74,6 +74,18 @@ struct tevent_req {
tevent_req_cancel_fn private_cancel;
/**
+ * @brief A function to cleanup the request
+ *
+ * The implementation might want to set a function
+ * that is called before the tevent_req_done() and tevent_req_error()
+ * trigger the callers callback function.
+ */
+ struct {
+ tevent_req_cleanup_fn fn;
+ enum tevent_req_state state;
+ } private_cleanup;
+
+ /**
* @brief Internal state of the request
*
* Callers should only access this via functions and never directly.
diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c
index 30e91e2..c86fb68 100644
--- a/lib/tevent/tevent_req.c
+++ b/lib/tevent/tevent_req.c
@@ -113,6 +113,24 @@ void _tevent_req_notify_callback(struct tevent_req *req, const char *location)
}
}
+static void tevent_req_cleanup(struct tevent_req *req)
+{
+ if (req->private_cleanup.fn == NULL) {
+ return;
+ }
+
+ if (req->private_cleanup.state >= req->internal.state) {
+ /*
+ * Don't call the cleanup_function multiple times for the same
+ * state recursively
+ */
+ return;
+ }
+
+ req->private_cleanup.state = req->internal.state;
+ req->private_cleanup.fn(req, req->internal.state);
+}
+
static void tevent_req_finish(struct tevent_req *req,
enum tevent_req_state state,
const char *location)
@@ -124,6 +142,10 @@ static void tevent_req_finish(struct tevent_req *req,
TALLOC_FREE(req->internal.timer);
req->internal.state = state;
+ req->internal.finish_location = location;
+
+ tevent_req_cleanup(req);
+
_tevent_req_notify_callback(req, location);
}
@@ -220,6 +242,8 @@ void tevent_req_received(struct tevent_req *req)
req->internal.state = TEVENT_REQ_RECEIVED;
+ tevent_req_cleanup(req);
+
TALLOC_FREE(req->data);
}
@@ -315,3 +339,9 @@ bool _tevent_req_cancel(struct tevent_req *req, const char *location)
return req->private_cancel(req);
}
+
+void tevent_req_set_cleanup_fn(struct tevent_req *req, tevent_req_cleanup_fn fn)
+{
+ req->private_cleanup.state = req->internal.state;
+ req->private_cleanup.fn = fn;
+}
--
1.7.9.5
From ad8b682354ae5dfd8a139173f3012cfb1a217480 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 27 Sep 2013 04:06:00 +0200
Subject: [PATCH 07/11] tevent: version 0.9.21
This fixes a the following bugs:
- fix a crash bug in tevent_queue_immediate_trigger()
- add missing tevent_num_signals() and
tevent_sa_info_queue_count() prototypes
including documentation.
This adds the following new features:
- tevent_req_set_cleanup_fn()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
lib/tevent/ABI/tevent-0.9.21.sigs | 88 +++++++++++++++++++++++++++++++++++++
lib/tevent/wscript | 2 +-
2 files changed, 89 insertions(+), 1 deletion(-)
create mode 100644 lib/tevent/ABI/tevent-0.9.21.sigs
diff --git a/lib/tevent/ABI/tevent-0.9.21.sigs b/lib/tevent/ABI/tevent-0.9.21.sigs
new file mode 100644
index 0000000..d8b9f4b
--- /dev/null
+++ b/lib/tevent/ABI/tevent-0.9.21.sigs
@@ -0,0 +1,88 @@
+_tevent_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+_tevent_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+_tevent_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+_tevent_create_immediate: struct tevent_immediate *(TALLOC_CTX *, const char *)
+_tevent_loop_once: int (struct tevent_context *, const char *)
+_tevent_loop_until: int (struct tevent_context *, bool (*)(void *), void *, const char *)
+_tevent_loop_wait: int (struct tevent_context *, const char *)
+_tevent_queue_create: struct tevent_queue *(TALLOC_CTX *, const char *, const char *)
+_tevent_req_callback_data: void *(struct tevent_req *)
+_tevent_req_cancel: bool (struct tevent_req *, const char *)
+_tevent_req_create: struct tevent_req *(TALLOC_CTX *, void *, size_t, const char *, const char *)
+_tevent_req_data: void *(struct tevent_req *)
+_tevent_req_done: void (struct tevent_req *, const char *)
+_tevent_req_error: bool (struct tevent_req *, uint64_t, const char *)
+_tevent_req_nomem: bool (const void *, struct tevent_req *, const char *)
+_tevent_req_notify_callback: void (struct tevent_req *, const char *)
+_tevent_req_oom: void (struct tevent_req *, const char *)
+_tevent_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_backend_list: const char **(TALLOC_CTX *)
+tevent_cleanup_pending_signal_handlers: void (struct tevent_signal *)
+tevent_common_add_fd: struct tevent_fd *(struct tevent_context *, TALLOC_CTX *, int, uint16_t, tevent_fd_handler_t, void *, const char *, const char *)
+tevent_common_add_signal: struct tevent_signal *(struct tevent_context *, TALLOC_CTX *, int, int, tevent_signal_handler_t, void *, const char *, const char *)
+tevent_common_add_timer: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_add_timer_v2: struct tevent_timer *(struct tevent_context *, TALLOC_CTX *, struct timeval, tevent_timer_handler_t, void *, const char *, const char *)
+tevent_common_check_signal: int (struct tevent_context *)
+tevent_common_context_destructor: int (struct tevent_context *)
+tevent_common_fd_destructor: int (struct tevent_fd *)
+tevent_common_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_common_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_common_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_common_loop_immediate: bool (struct tevent_context *)
+tevent_common_loop_timer_delay: struct timeval (struct tevent_context *)
+tevent_common_loop_wait: int (struct tevent_context *, const char *)
+tevent_common_schedule_immediate: void (struct tevent_immediate *, struct tevent_context *, tevent_immediate_handler_t, void *, const char *, const char *)
+tevent_context_init: struct tevent_context *(TALLOC_CTX *)
+tevent_context_init_byname: struct tevent_context *(TALLOC_CTX *, const char *)
+tevent_context_init_ops: struct tevent_context *(TALLOC_CTX *, const struct tevent_ops *, void *)
+tevent_debug: void (struct tevent_context *, enum tevent_debug_level, const char *, ...)
+tevent_fd_get_flags: uint16_t (struct tevent_fd *)
+tevent_fd_set_auto_close: void (struct tevent_fd *)
+tevent_fd_set_close_fn: void (struct tevent_fd *, tevent_fd_close_fn_t)
+tevent_fd_set_flags: void (struct tevent_fd *, uint16_t)
+tevent_get_trace_callback: void (struct tevent_context *, tevent_trace_callback_t *, void *)
+tevent_loop_allow_nesting: void (struct tevent_context *)
+tevent_loop_set_nesting_hook: void (struct tevent_context *, tevent_nesting_hook, void *)
+tevent_num_signals: size_t (void)
+tevent_queue_add: bool (struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_entry: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_add_optimize_empty: struct tevent_queue_entry *(struct tevent_queue *, struct tevent_context *, struct tevent_req *, tevent_queue_trigger_fn_t, void *)
+tevent_queue_length: size_t (struct tevent_queue *)
+tevent_queue_running: bool (struct tevent_queue *)
+tevent_queue_start: void (struct tevent_queue *)
+tevent_queue_stop: void (struct tevent_queue *)
+tevent_queue_wait_recv: bool (struct tevent_req *)
+tevent_queue_wait_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct tevent_queue *)
+tevent_re_initialise: int (struct tevent_context *)
+tevent_register_backend: bool (const char *, const struct tevent_ops *)
+tevent_req_default_print: char *(struct tevent_req *, TALLOC_CTX *)
+tevent_req_defer_callback: void (struct tevent_req *, struct tevent_context *)
+tevent_req_is_error: bool (struct tevent_req *, enum tevent_req_state *, uint64_t *)
+tevent_req_is_in_progress: bool (struct tevent_req *)
+tevent_req_poll: bool (struct tevent_req *, struct tevent_context *)
+tevent_req_post: struct tevent_req *(struct tevent_req *, struct tevent_context *)
+tevent_req_print: char *(TALLOC_CTX *, struct tevent_req *)
+tevent_req_received: void (struct tevent_req *)
+tevent_req_set_callback: void (struct tevent_req *, tevent_req_fn, void *)
+tevent_req_set_cancel_fn: void (struct tevent_req *, tevent_req_cancel_fn)
+tevent_req_set_cleanup_fn: void (struct tevent_req *, tevent_req_cleanup_fn)
+tevent_req_set_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval)
+tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn)
+tevent_sa_info_queue_count: size_t (void)
+tevent_set_abort_fn: void (void (*)(const char *))
+tevent_set_debug: int (struct tevent_context *, void (*)(void *, enum tevent_debug_level, const char *, va_list), void *)
+tevent_set_debug_stderr: int (struct tevent_context *)
+tevent_set_default_backend: void (const char *)
+tevent_set_trace_callback: void (struct tevent_context *, tevent_trace_callback_t, void *)
+tevent_signal_support: bool (struct tevent_context *)
+tevent_timeval_add: struct timeval (const struct timeval *, uint32_t, uint32_t)
+tevent_timeval_compare: int (const struct timeval *, const struct timeval *)
+tevent_timeval_current: struct timeval (void)
+tevent_timeval_current_ofs: struct timeval (uint32_t, uint32_t)
+tevent_timeval_is_zero: bool (const struct timeval *)
+tevent_timeval_set: struct timeval (uint32_t, uint32_t)
+tevent_timeval_until: struct timeval (const struct timeval *, const struct timeval *)
+tevent_timeval_zero: struct timeval (void)
+tevent_trace_point_callback: void (struct tevent_context *, enum tevent_trace_point)
+tevent_wakeup_recv: bool (struct tevent_req *)
+tevent_wakeup_send: struct tevent_req *(TALLOC_CTX *, struct tevent_context *, struct timeval)
diff --git a/lib/tevent/wscript b/lib/tevent/wscript
index 3fc87f5..bd19780 100755
--- a/lib/tevent/wscript
+++ b/lib/tevent/wscript
@@ -1,7 +1,7 @@
#!/usr/bin/env python
APPNAME = 'tevent'
-VERSION = '0.9.20'
+VERSION = '0.9.21'
blddir = 'bin'
--
1.7.9.5
From a451ef9533485556899bff94642a8fb78ee954e3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 8 Jan 2014 10:31:15 +0100
Subject: [PATCH 08/11] libcli/smb: make use of tevent_req_set_cleanup_fn()
This is more better than a custom tevent_req destructor.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
libcli/smb/smbXcli_base.c | 26 ++++++++++++++++----------
1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 082b626..43dd994 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -785,7 +785,7 @@ void smbXcli_req_unset_pending(struct tevent_req *req)
return;
}
- talloc_set_destructor(req, NULL);
+ tevent_req_set_cleanup_fn(req, NULL);
if (num_pending == 1) {
/*
@@ -828,19 +828,25 @@ void smbXcli_req_unset_pending(struct tevent_req *req)
return;
}
-static int smbXcli_req_destructor(struct tevent_req *req)
+static void smbXcli_req_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
{
struct smbXcli_req_state *state =
tevent_req_data(req,
struct smbXcli_req_state);
- /*
- * Make sure we really remove it from
- * the pending array on destruction.
- */
- state->smb1.mid = 0;
- smbXcli_req_unset_pending(req);
- return 0;
+ switch (req_state) {
+ case TEVENT_REQ_RECEIVED:
+ /*
+ * Make sure we really remove it from
+ * the pending array on destruction.
+ */
+ state->smb1.mid = 0;
+ smbXcli_req_unset_pending(req);
+ return;
+ default:
+ return;
+ }
}
static bool smb1cli_req_cancel(struct tevent_req *req);
@@ -893,7 +899,7 @@ bool smbXcli_req_set_pending(struct tevent_req *req)
}
pending[num_pending] = req;
conn->pending = pending;
- talloc_set_destructor(req, smbXcli_req_destructor);
+ tevent_req_set_cleanup_fn(req, smbXcli_req_cleanup);
tevent_req_set_cancel_fn(req, smbXcli_req_cancel);
if (!smbXcli_conn_receive_next(conn)) {
--
1.7.9.5
From 26a52c44b5e74fa7f456d9fbf0249da8c47b9369 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 8 Jan 2014 10:31:15 +0100
Subject: [PATCH 09/11] s3:lib/fncall: make use of tevent_req_set_cleanup_fn()
This is more better than a custom tevent_req destructor.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
source3/lib/fncall.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/source3/lib/fncall.c b/source3/lib/fncall.c
index fb3d5c9..7f728ba 100644
--- a/source3/lib/fncall.c
+++ b/source3/lib/fncall.c
@@ -122,7 +122,8 @@ static int fncall_next_job_id(struct fncall_context *ctx)
}
static void fncall_unset_pending(struct tevent_req *req);
-static int fncall_destructor(struct tevent_req *req);
+static void fncall_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state);
static bool fncall_set_pending(struct tevent_req *req,
struct fncall_context *ctx,
@@ -141,12 +142,12 @@ static bool fncall_set_pending(struct tevent_req *req,
pending[num_pending] = req;
num_pending += 1;
ctx->pending = pending;
- talloc_set_destructor(req, fncall_destructor);
+ tevent_req_set_cleanup_fn(req, fncall_cleanup);
/*
* Make sure that the orphaned array of fncall_state structs has
* enough space. A job can change from pending to orphaned in
- * fncall_destructor, and to fail in a talloc destructor should be
+ * fncall_cleanup, and to fail in a talloc destructor should be
* avoided if possible.
*/
@@ -184,6 +185,8 @@ static void fncall_unset_pending(struct tevent_req *req)
int num_pending = talloc_array_length(ctx->pending);
int i;
+ tevent_req_set_cleanup_fn(req, NULL);
+
if (num_pending == 1) {
TALLOC_FREE(ctx->fde);
TALLOC_FREE(ctx->pending);
@@ -205,16 +208,24 @@ static void fncall_unset_pending(struct tevent_req *req)
num_pending - 1);
}
-static int fncall_destructor(struct tevent_req *req)
+static void fncall_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
{
struct fncall_state *state = tevent_req_data(
req, struct fncall_state);
struct fncall_context *ctx = state->ctx;
+ switch (req_state) {
+ case TEVENT_REQ_RECEIVED:
+ break;
+ default:
+ return;
+ }
+
fncall_unset_pending(req);
if (state->done) {
- return 0;
+ return;
}
/*
@@ -223,8 +234,6 @@ static int fncall_destructor(struct tevent_req *req)
*/
ctx->orphaned[ctx->num_orphaned] = talloc_move(ctx->orphaned, &state);
ctx->num_orphaned += 1;
-
- return 0;
}
struct tevent_req *fncall_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev,
--
1.7.9.5
From fbef6107545c5b04675330ee402e625fb040595e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 8 Jan 2014 19:46:01 +0100
Subject: [PATCH 10/11] s3:lib/tldap: make use of tevent_req_defer_callback()
In tldap_msg_received() we call tevent_req_error() for more than
one request, if we do that we need to use tevent_req_defer_callback()
otherwise we're likely to crash, as a triggered callback may
invalidate our state.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
source3/lib/tldap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index b094c2d..a566a91 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -650,6 +650,8 @@ static void tldap_msg_received(struct tevent_req *subreq)
fail:
while (talloc_array_length(ld->pending) > 0) {
req = ld->pending[0];
+ state = tevent_req_data(req, struct tldap_msg_state);
+ tevent_req_defer_callback(req, state->ev);
talloc_set_destructor(req, NULL);
tldap_msg_destructor(req);
tevent_req_error(req, status);
--
1.7.9.5
From 53cd5d22eb0c2cae8e8f4e023b35026ec98fc910 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 8 Jan 2014 10:31:15 +0100
Subject: [PATCH 11/11] s3:lib/tldap: make use of tevent_req_set_cleanup_fn()
This is more better than a custom tevent_req destructor.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Volker Lendecke <vl at samba.org>
---
source3/lib/tldap.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/source3/lib/tldap.c b/source3/lib/tldap.c
index a566a91..b15ee73 100644
--- a/source3/lib/tldap.c
+++ b/source3/lib/tldap.c
@@ -444,6 +444,8 @@ static void tldap_msg_unset_pending(struct tevent_req *req)
int num_pending = talloc_array_length(ld->pending);
int i;
+ tevent_req_set_cleanup_fn(req, NULL);
+
if (num_pending == 1) {
TALLOC_FREE(ld->pending);
return;
@@ -479,10 +481,17 @@ static void tldap_msg_unset_pending(struct tevent_req *req)
return;
}
-static int tldap_msg_destructor(struct tevent_req *req)
+static void tldap_msg_cleanup(struct tevent_req *req,
+ enum tevent_req_state req_state)
{
- tldap_msg_unset_pending(req);
- return 0;
+ switch (req_state) {
+ case TEVENT_REQ_USER_ERROR:
+ case TEVENT_REQ_RECEIVED:
+ tldap_msg_unset_pending(req);
+ return;
+ default:
+ return;
+ }
}
static bool tldap_msg_set_pending(struct tevent_req *req)
@@ -504,7 +513,7 @@ static bool tldap_msg_set_pending(struct tevent_req *req)
}
pending[num_pending] = req;
ld->pending = pending;
- talloc_set_destructor(req, tldap_msg_destructor);
+ tevent_req_set_cleanup_fn(req, tldap_msg_cleanup);
if (num_pending > 0) {
return true;
@@ -618,7 +627,6 @@ static void tldap_msg_received(struct tevent_req *subreq)
state->inbuf = talloc_move(state, &inbuf);
state->data = talloc_move(state, &data);
- talloc_set_destructor(req, NULL);
tldap_msg_unset_pending(req);
num_pending = talloc_array_length(ld->pending);
@@ -652,8 +660,6 @@ static void tldap_msg_received(struct tevent_req *subreq)
req = ld->pending[0];
state = tevent_req_data(req, struct tldap_msg_state);
tevent_req_defer_callback(req, state->ev);
- talloc_set_destructor(req, NULL);
- tldap_msg_destructor(req);
tevent_req_error(req, status);
}
}
--
1.7.9.5
More information about the samba-technical
mailing list