The Samba-Bugzilla – Attachment 11160 Details for
Bug 11330
Backport tevent-0.9.25
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Backport on top of v4-1-test, but not for v4-1-test
tmp41.diff.txt (text/plain), 184.88 KB, created by
Stefan Metzmacher
on 2015-06-16 13:35:58 UTC
(
hide
)
Description:
Backport on top of v4-1-test, but not for v4-1-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2015-06-16 13:35:58 UTC
Size:
184.88 KB
patch
obsolete
>From 6903c6909acaffd896baf56f08ca1869c83dab97 Mon Sep 17 00:00:00 2001 >From: David Disseldorp <ddiss@samba.org> >Date: Mon, 8 Jul 2013 15:11:25 +0200 >Subject: [PATCH 01/55] tevent: document tevent_req_create state zeroing > >Signed-off-by: David Disseldorp <ddiss@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> > >Autobuild-User(master): Volker Lendecke <vl@samba.org> >Autobuild-Date(master): Mon Jul 8 20:43:49 CEST 2013 on sn-devel-104 > >(cherry picked from commit e6f79b94891c3fe432739a479fde753002500938) >--- > lib/tevent/tevent.h | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > >diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h >index 6b4d371..2bc4e2d 100644 >--- a/lib/tevent/tevent.h >+++ b/lib/tevent/tevent.h >@@ -919,9 +919,9 @@ bool _tevent_req_cancel(struct tevent_req *req, const char *location); > * req = tevent_req_create(mem_ctx, &state, struct computation_state); > * @endcode > * >- * Tevent_req_create() creates the state variable as a talloc child of >- * its result. The state variable should be used as the talloc parent >- * for all temporary variables that are allocated during the async >+ * Tevent_req_create() allocates and zeros the state variable as a talloc >+ * child of its result. The state variable should be used as the talloc >+ * parent for all temporary variables that are allocated during the async > * computation. This way, when the user of the async computation frees > * the request, the state as a talloc child will be free'd along with > * all the temporary variables hanging off the state. >-- >1.9.1 > > >From d58205f913e30b705ad2f1b30cf89c095046f293 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Wed, 31 Jul 2013 11:31:57 +0200 >Subject: [PATCH 02/55] tevent: Remove the signal pipe if no signal events are > around > >It makes adding/removing the first/last sigevents a bit more expensive, but it >will fix tevent_loop_wait not finishing when one signal event was added and >removed. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10012 > >Signed-off-by: Volker Lendecke <vl@samba.org> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andreas Schneider <asn@samba.org> >(cherry picked from commit 066a642f10cae7980eefb2d8ada3a6c3f5220542) >--- > lib/tevent/tevent_signal.c | 14 +++++++++++++- > 1 file changed, 13 insertions(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index 95a099d..fd321ff 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -181,7 +181,19 @@ static int tevent_signal_destructor(struct tevent_signal *se) > struct tevent_common_signal_list); > > if (se->event_ctx) { >- DLIST_REMOVE(se->event_ctx->signal_events, se); >+ struct tevent_context *ev = se->event_ctx; >+ >+ DLIST_REMOVE(ev->signal_events, se); >+ >+ if (ev->signal_events == NULL && ev->pipe_fde != NULL) { >+ /* >+ * This was the last signal. Destroy the pipe. >+ */ >+ TALLOC_FREE(ev->pipe_fde); >+ >+ close(ev->pipe_fds[0]); >+ close(ev->pipe_fds[1]); >+ } > } > > talloc_free(sl); >-- >1.9.1 > > >From 5996b885e2d748c6d8e4d1f0d2f5ae195866ebd5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 1 Aug 2013 13:13:04 +0200 >Subject: [PATCH 03/55] tevent: change version to 0.9.19 > >* Fix tevent testsuite issue on Solaris. >* Add tevent tuturial and documentation updates >* Fix Coverity ID 989236 Operands don't affect result >* Bug: https://bugzilla.samba.org/show_bug.cgi?id=10012 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Thu Aug 1 17:05:02 CEST 2013 on sn-devel-104 > >(cherry picked from commit 8f98f5d85ae30361f6bb9f6f42d6a7fd279301e1) >--- > lib/tevent/ABI/tevent-0.9.19.sigs | 83 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 84 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.19.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.19.sigs b/lib/tevent/ABI/tevent-0.9.19.sigs >new file mode 100644 >index 0000000..70d20b6 >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.19.sigs >@@ -0,0 +1,83 @@ >+_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_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_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_endtime: bool (struct tevent_req *, struct tevent_context *, struct timeval) >+tevent_req_set_print_fn: void (struct tevent_req *, tevent_req_print_fn) >+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 02bddb8..39f2ae4 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.18' >+VERSION = '0.9.19' > > blddir = 'bin' > >-- >1.9.1 > > >From 45c5c977e4151c85b4085474d421c4ae60fe7d73 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 23 Jul 2013 10:08:38 +0200 >Subject: [PATCH 04/55] tevent: Add echo server sample code > >This is under a deliberately permissive license. I would like people to start >using libtevent and tevent_req (LGPL) without any worries about where to start >from. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> > >Autobuild-User(master): Amitay Isaacs <amitay@samba.org> >Autobuild-Date(master): Mon Aug 5 04:07:58 CEST 2013 on sn-devel-104 > >(cherry picked from commit cae48e9a36d7e37ec18791439b30a876bde0c775) >--- > lib/tevent/echo_server.c | 664 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 664 insertions(+) > create mode 100644 lib/tevent/echo_server.c > >diff --git a/lib/tevent/echo_server.c b/lib/tevent/echo_server.c >new file mode 100644 >index 0000000..a1da0d8 >--- /dev/null >+++ b/lib/tevent/echo_server.c >@@ -0,0 +1,664 @@ >+/** >+ ** NOTE! The following liberal license applies to this sample file only. >+ ** This does NOT imply that all of Samba is released under this license. >+ ** >+ ** This file is meant as a starting point for libtevent users to be used >+ ** in any program linking against the LGPL licensed libtevent. >+ **/ >+ >+/* >+ * This file is being made available by the Samba Team under the following >+ * license: >+ * >+ * Permission to use, copy, modify, and distribute this sample file for any >+ * purpose is hereby granted without fee. >+ * >+ * This work 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. >+ */ >+ >+#include <stdio.h> >+#include <stdlib.h> >+#include <string.h> >+#include <netinet/in.h> >+#include <sys/types.h> >+#include <sys/socket.h> >+#include <errno.h> >+#include <unistd.h> >+#include "tevent.h" >+#include "talloc.h" >+ >+/** >+ * @brief Helper function to get a useful unix error from tevent_req >+ */ >+ >+static bool tevent_req_is_unix_error(struct tevent_req *req, int *perrno) >+{ >+ enum tevent_req_state state; >+ uint64_t err; >+ >+ if (!tevent_req_is_error(req, &state, &err)) { >+ return false; >+ } >+ switch (state) { >+ case TEVENT_REQ_TIMED_OUT: >+ *perrno = ETIMEDOUT; >+ break; >+ case TEVENT_REQ_NO_MEMORY: >+ *perrno = ENOMEM; >+ break; >+ case TEVENT_REQ_USER_ERROR: >+ *perrno = err; >+ break; >+ default: >+ *perrno = EINVAL; >+ break; >+ } >+ return true; >+} >+ >+/** >+ * @brief Wrapper around accept(2) >+ */ >+ >+struct accept_state { >+ struct tevent_fd *fde; >+ int listen_sock; >+ socklen_t addrlen; >+ struct sockaddr addr; >+ int sock; >+}; >+ >+static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data); >+ >+static struct tevent_req *accept_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int listen_sock) >+{ >+ struct tevent_req *req; >+ struct accept_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, struct accept_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ state->listen_sock = listen_sock; >+ >+ state->fde = tevent_add_fd(ev, state, listen_sock, TEVENT_FD_READ, >+ accept_handler, req); >+ if (tevent_req_nomem(state->fde, req)) { >+ return tevent_req_post(req, ev); >+ } >+ return req; >+} >+ >+static void accept_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data) >+{ >+ struct tevent_req *req = talloc_get_type_abort( >+ private_data, struct tevent_req); >+ struct accept_state *state = tevent_req_data(req, struct accept_state); >+ int ret; >+ >+ TALLOC_FREE(state->fde); >+ >+ if ((flags & TEVENT_FD_READ) == 0) { >+ tevent_req_error(req, EIO); >+ return; >+ } >+ state->addrlen = sizeof(state->addr); >+ >+ ret = accept(state->listen_sock, &state->addr, &state->addrlen); >+ if (ret == -1) { >+ tevent_req_error(req, errno); >+ return; >+ } >+ state->sock = ret; >+ tevent_req_done(req); >+} >+ >+static int accept_recv(struct tevent_req *req, struct sockaddr *paddr, >+ socklen_t *paddrlen, int *perr) >+{ >+ struct accept_state *state = tevent_req_data(req, struct accept_state); >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ if (perr != NULL) { >+ *perr = err; >+ } >+ return -1; >+ } >+ if (paddr != NULL) { >+ *paddr = state->addr; >+ } >+ if (paddrlen != NULL) { >+ *paddrlen = state->addrlen; >+ } >+ return state->sock; >+} >+ >+/** >+ * @brief Wrapper around read(2) >+ */ >+ >+struct read_state { >+ struct tevent_fd *fde; >+ int fd; >+ void *buf; >+ size_t count; >+ >+ ssize_t nread; >+}; >+ >+static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data); >+ >+static struct tevent_req *read_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int fd, void *buf, size_t count) >+{ >+ struct tevent_req *req; >+ struct read_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, struct read_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ state->fd = fd; >+ state->buf = buf; >+ state->count = count; >+ >+ state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_READ, >+ read_handler, req); >+ if (tevent_req_nomem(state->fde, req)) { >+ return tevent_req_post(req, ev); >+ } >+ return req; >+} >+ >+static void read_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data) >+{ >+ struct tevent_req *req = talloc_get_type_abort( >+ private_data, struct tevent_req); >+ struct read_state *state = tevent_req_data(req, struct read_state); >+ ssize_t ret; >+ >+ TALLOC_FREE(state->fde); >+ >+ if ((flags & TEVENT_FD_READ) == 0) { >+ tevent_req_error(req, EIO); >+ return; >+ } >+ >+ ret = read(state->fd, state->buf, state->count); >+ if (ret == -1) { >+ tevent_req_error(req, errno); >+ return; >+ } >+ state->nread = ret; >+ tevent_req_done(req); >+} >+ >+static ssize_t read_recv(struct tevent_req *req, int *perr) >+{ >+ struct read_state *state = tevent_req_data(req, struct read_state); >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ if (perr != NULL) { >+ *perr = err; >+ } >+ return -1; >+ } >+ return state->nread; >+} >+ >+/** >+ * @brief Wrapper around write(2) >+ */ >+ >+struct write_state { >+ struct tevent_fd *fde; >+ int fd; >+ const void *buf; >+ size_t count; >+ >+ ssize_t nwritten; >+}; >+ >+static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data); >+ >+static struct tevent_req *write_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int fd, const void *buf, size_t count) >+{ >+ struct tevent_req *req; >+ struct write_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, struct write_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ state->fd = fd; >+ state->buf = buf; >+ state->count = count; >+ >+ state->fde = tevent_add_fd(ev, state, fd, TEVENT_FD_WRITE, >+ write_handler, req); >+ if (tevent_req_nomem(state->fde, req)) { >+ return tevent_req_post(req, ev); >+ } >+ return req; >+} >+ >+static void write_handler(struct tevent_context *ev, struct tevent_fd *fde, >+ uint16_t flags, void *private_data) >+{ >+ struct tevent_req *req = talloc_get_type_abort( >+ private_data, struct tevent_req); >+ struct write_state *state = tevent_req_data(req, struct write_state); >+ ssize_t ret; >+ >+ TALLOC_FREE(state->fde); >+ >+ if ((flags & TEVENT_FD_WRITE) == 0) { >+ tevent_req_error(req, EIO); >+ return; >+ } >+ >+ ret = write(state->fd, state->buf, state->count); >+ if (ret == -1) { >+ tevent_req_error(req, errno); >+ return; >+ } >+ state->nwritten = ret; >+ tevent_req_done(req); >+} >+ >+static ssize_t write_recv(struct tevent_req *req, int *perr) >+{ >+ struct write_state *state = tevent_req_data(req, struct write_state); >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ if (perr != NULL) { >+ *perr = err; >+ } >+ return -1; >+ } >+ return state->nwritten; >+} >+ >+/** >+ * @brief Wrapper function that deals with short writes >+ */ >+ >+struct writeall_state { >+ struct tevent_context *ev; >+ int fd; >+ const void *buf; >+ size_t count; >+ size_t nwritten; >+}; >+ >+static void writeall_done(struct tevent_req *subreq); >+ >+static struct tevent_req *writeall_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int fd, const void *buf, size_t count) >+{ >+ struct tevent_req *req, *subreq; >+ struct writeall_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, struct writeall_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->ev = ev; >+ state->fd = fd; >+ state->buf = buf; >+ state->count = count; >+ state->nwritten = 0; >+ >+ subreq = write_send(state, state->ev, state->fd, >+ ((char *)state->buf)+state->nwritten, >+ state->count - state->nwritten); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, writeall_done, req); >+ return req; >+} >+ >+static void writeall_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct writeall_state *state = tevent_req_data( >+ req, struct writeall_state); >+ ssize_t nwritten; >+ int err = 0; >+ >+ nwritten = write_recv(subreq, &err); >+ TALLOC_FREE(subreq); >+ if (nwritten == -1) { >+ tevent_req_error(req, err); >+ return; >+ } >+ >+ state->nwritten += nwritten; >+ >+ if (state->nwritten < state->count) { >+ subreq = write_send(state, state->ev, state->fd, >+ ((char *)state->buf)+state->nwritten, >+ state->count - state->nwritten); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, writeall_done, req); >+ return; >+ } >+ tevent_req_done(req); >+} >+ >+static ssize_t writeall_recv(struct tevent_req *req, int *perr) >+{ >+ struct writeall_state *state = tevent_req_data( >+ req, struct writeall_state); >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ if (perr != NULL) { >+ *perr = err; >+ } >+ return -1; >+ } >+ return state->nwritten; >+} >+ >+/** >+ * @brief Async echo handler code dealing with one client >+ */ >+ >+struct echo_state { >+ struct tevent_context *ev; >+ int fd; >+ uint8_t *buf; >+}; >+ >+static int echo_state_destructor(struct echo_state *s); >+static void echo_read_done(struct tevent_req *subreq); >+static void echo_writeall_done(struct tevent_req *subreq); >+ >+static struct tevent_req *echo_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int fd, size_t bufsize) >+{ >+ struct tevent_req *req, *subreq; >+ struct echo_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, struct echo_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->ev = ev; >+ state->fd = fd; >+ >+ talloc_set_destructor(state, echo_state_destructor); >+ >+ state->buf = talloc_array(state, uint8_t, bufsize); >+ if (tevent_req_nomem(state->buf, req)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ subreq = read_send(state, state->ev, state->fd, >+ state->buf, talloc_get_size(state->buf)); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, echo_read_done, req); >+ return req; >+} >+ >+static int echo_state_destructor(struct echo_state *s) >+{ >+ if (s->fd != -1) { >+ printf("Closing client fd %d\n", s->fd); >+ close(s->fd); >+ s->fd = -1; >+ } >+ return 0; >+} >+ >+static void echo_read_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct echo_state *state = tevent_req_data( >+ req, struct echo_state); >+ ssize_t nread; >+ int err; >+ >+ nread = read_recv(subreq, &err); >+ TALLOC_FREE(subreq); >+ if (nread == -1) { >+ tevent_req_error(req, err); >+ return; >+ } >+ if (nread == 0) { >+ tevent_req_done(req); >+ return; >+ } >+ >+ subreq = writeall_send(state, state->ev, state->fd, state->buf, nread); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, echo_writeall_done, req); >+} >+ >+static void echo_writeall_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct echo_state *state = tevent_req_data( >+ req, struct echo_state); >+ ssize_t nwritten; >+ int err; >+ >+ nwritten = writeall_recv(subreq, &err); >+ TALLOC_FREE(subreq); >+ if (nwritten == -1) { >+ if (err == EPIPE) { >+ tevent_req_done(req); >+ return; >+ } >+ tevent_req_error(req, err); >+ return; >+ } >+ >+ subreq = read_send(state, state->ev, state->fd, >+ state->buf, talloc_get_size(state->buf)); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, echo_read_done, req); >+} >+ >+static bool echo_recv(struct tevent_req *req, int *perr) >+{ >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ *perr = err; >+ return false; >+ } >+ return true; >+} >+ >+/** >+ * @brief Full echo handler code accepting and handling clients >+ */ >+ >+struct echo_server_state { >+ struct tevent_context *ev; >+ int listen_sock; >+}; >+ >+static void echo_server_accepted(struct tevent_req *subreq); >+static void echo_server_client_done(struct tevent_req *subreq); >+ >+static struct tevent_req *echo_server_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ int listen_sock) >+{ >+ struct tevent_req *req, *subreq; >+ struct echo_server_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct echo_server_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ state->ev = ev; >+ state->listen_sock = listen_sock; >+ >+ subreq = accept_send(state, state->ev, state->listen_sock); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, echo_server_accepted, req); >+ return req; >+} >+ >+static void echo_server_accepted(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct echo_server_state *state = tevent_req_data( >+ req, struct echo_server_state); >+ int sock, err; >+ >+ sock = accept_recv(subreq, NULL, NULL, &err); >+ TALLOC_FREE(subreq); >+ if (sock == -1) { >+ tevent_req_error(req, err); >+ return; >+ } >+ >+ printf("new client fd %d\n", sock); >+ >+ subreq = echo_send(state, state->ev, sock, 100); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, echo_server_client_done, req); >+ >+ subreq = accept_send(state, state->ev, state->listen_sock); >+ if (tevent_req_nomem(subreq, req)) { >+ return; >+ } >+ tevent_req_set_callback(subreq, echo_server_accepted, req); >+} >+ >+static void echo_server_client_done(struct tevent_req *subreq) >+{ >+ bool ret; >+ int err; >+ >+ ret = echo_recv(subreq, &err); >+ TALLOC_FREE(subreq); >+ >+ if (ret) { >+ printf("Client done\n"); >+ } else { >+ printf("Client failed: %s\n", strerror(err)); >+ } >+} >+ >+static bool echo_server_recv(struct tevent_req *req, int *perr) >+{ >+ int err; >+ >+ if (tevent_req_is_unix_error(req, &err)) { >+ *perr = err; >+ return false; >+ } >+ return true; >+} >+ >+int main(int argc, const char **argv) >+{ >+ int ret, port, listen_sock, err; >+ struct tevent_context *ev; >+ struct sockaddr_in addr; >+ struct tevent_req *req; >+ bool result; >+ >+ if (argc != 2) { >+ fprintf(stderr, "Usage: %s <port>\n", argv[0]); >+ exit(1); >+ } >+ >+ port = atoi(argv[1]); >+ >+ printf("listening on port %d\n", port); >+ >+ listen_sock = socket(AF_INET, SOCK_STREAM, 0); >+ >+ if (listen_sock == -1) { >+ perror("socket() failed"); >+ exit(1); >+ } >+ >+ memset(&addr, 0, sizeof(addr)); >+ >+ addr.sin_family = AF_INET; >+ addr.sin_port = htons(port); >+ >+ ret = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); >+ if (ret == -1) { >+ perror("bind() failed"); >+ exit(1); >+ } >+ >+ ret = listen(listen_sock, 5); >+ if (ret == -1) { >+ perror("listen() failed"); >+ exit(1); >+ } >+ >+ ev = tevent_context_init(NULL); >+ if (ev == NULL) { >+ fprintf(stderr, "tevent_context_init failed\n"); >+ exit(1); >+ } >+ >+ req = echo_server_send(ev, ev, listen_sock); >+ if (req == NULL) { >+ fprintf(stderr, "echo_server_send failed\n"); >+ exit(1); >+ } >+ >+ if (!tevent_req_poll(req, ev)) { >+ perror("tevent_req_poll() failed"); >+ exit(1); >+ } >+ >+ result = echo_server_recv(req, &err); >+ TALLOC_FREE(req); >+ if (!result) { >+ fprintf(stderr, "echo_server failed: %s\n", strerror(err)); >+ exit(1); >+ } >+ >+ return 0; >+} >-- >1.9.1 > > >From f214ead72de83249214621c964a55ebabad776c4 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 30 Jul 2013 14:37:16 +0200 >Subject: [PATCH 05/55] tevent: Fix tutorial reference > >Signed-off-by: Volker Lendecke <vl@samba.org> > >Reviewed-by: Andrew Bartlett <abartlet@samba.org> > >Autobuild-User(master): Andrew Bartlett <abartlet@samba.org> >Autobuild-Date(master): Mon Aug 12 09:17:10 CEST 2013 on sn-devel-104 > >(cherry picked from commit 6a081e991923b7d089be4a5cdb1a351c2e863db1) >--- > lib/tevent/doc/tevent_request.dox | 8 +++----- > 1 file changed, 3 insertions(+), 5 deletions(-) > >diff --git a/lib/tevent/doc/tevent_request.dox b/lib/tevent/doc/tevent_request.dox >index 3358cfb..7fcfb55 100644 >--- a/lib/tevent/doc/tevent_request.dox >+++ b/lib/tevent/doc/tevent_request.dox >@@ -182,10 +182,8 @@ tevent_wakeup_recv() ) > > @image html tevent_subrequest.png > >-Comprehensive example containing features from this chapter is especially by >-reason of nested subrequests very long and therefore it is located as an >-example on the attached CD. Description and explanation is placed within the >-source code itself (subrequest.c) and enclosed file README. The example is >-available <a href="subrequest_example.zip">here</a>. >+A comprehensive example of nested subrequests can be found in the file >+echo_server.c. It implements a complete, self-contained echo server with no >+dependencies but libevent and libtalloc. > > */ >-- >1.9.1 > > >From 8004b1ed2c89361657c5fc4d55dbd8af7b1f0b7e Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 16 Aug 2013 11:32:08 +0000 >Subject: [PATCH 06/55] tevent: Remove a pointless goto > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 6c0758219a8d3dc0c6673f8c7b38386dbbc75559) >--- > lib/tevent/tevent_wakeup.c | 5 +---- > 1 file changed, 1 insertion(+), 4 deletions(-) > >diff --git a/lib/tevent/tevent_wakeup.c b/lib/tevent/tevent_wakeup.c >index 82c3942..e217f33 100644 >--- a/lib/tevent/tevent_wakeup.c >+++ b/lib/tevent/tevent_wakeup.c >@@ -46,12 +46,9 @@ struct tevent_req *tevent_wakeup_send(TALLOC_CTX *mem_ctx, > state->wakeup_time = wakeup_time; > > if (!tevent_req_set_endtime(req, ev, wakeup_time)) { >- goto post; >+ return tevent_req_post(req, ev); > } >- > return req; >-post: >- return tevent_req_post(req, ev); > } > > bool tevent_wakeup_recv(struct tevent_req *req) >-- >1.9.1 > > >From c77574adaf759b84f6defafd8f427d872507a3cf Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 6 Sep 2013 15:37:56 -0700 >Subject: [PATCH 07/55] tevent: Use talloc_pooled_object for tevent_req_create > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Volker Lendecke <vl@samba.org> >Autobuild-Date(master): Sun Sep 8 13:39:25 CEST 2013 on sn-devel-104 > >(cherry picked from commit 8f4069c7cd10a143286c7a32c1b612380afd7c72) >--- > lib/tevent/tevent_req.c | 5 ++++- > 1 file changed, 4 insertions(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c >index d8d0c5f..556d984 100644 >--- a/lib/tevent/tevent_req.c >+++ b/lib/tevent/tevent_req.c >@@ -61,10 +61,13 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, > void **ppdata = (void **)pdata; > void *data; > >- req = talloc_zero(mem_ctx, struct tevent_req); >+ req = talloc_pooled_object( >+ mem_ctx, struct tevent_req, 2, >+ sizeof(struct tevent_immediate) + data_size); > if (req == NULL) { > return NULL; > } >+ ZERO_STRUCTP(req); > req->internal.private_type = type; > req->internal.create_location = location; > req->internal.finish_location = NULL; >-- >1.9.1 > > >From 3c7b4a2fcae43086a6ec7e5b6c6f85c91d1cddbf Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 17 Sep 2011 19:53:55 +0200 >Subject: [PATCH 08/55] tevent: cancel the timeout timer when the request is > finished > >As we might defer the callback with tevent_req_defer_callback() >when calling tevent_req_done(), we should cancel the timeout directly. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 577afba8b3b75d8ebf8bc496802974b834a53f83) >--- > lib/tevent/tevent_req.c | 6 ++++++ > 1 file changed, 6 insertions(+) > >diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c >index 556d984..4a3b8b1 100644 >--- a/lib/tevent/tevent_req.c >+++ b/lib/tevent/tevent_req.c >@@ -109,6 +109,12 @@ static void tevent_req_finish(struct tevent_req *req, > enum tevent_req_state state, > const char *location) > { >+ /* >+ * make sure we do not timeout after >+ * the request was already finished >+ */ >+ TALLOC_FREE(req->internal.timer); >+ > req->internal.state = state; > _tevent_req_notify_callback(req, location); > } >-- >1.9.1 > > >From a4467815bf441e915146f86ffd65b9a9101cfcef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 02:59:22 +0200 >Subject: [PATCH 09/55] tevent: let tevent_req_received() clear the > private_cancel function > >This makes sure it's not called when the private state is already gone. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 39888fd4a3960f3f6a52aad76507faf030888d57) >--- > lib/tevent/tevent_req.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c >index 4a3b8b1..a324418 100644 >--- a/lib/tevent/tevent_req.c >+++ b/lib/tevent/tevent_req.c >@@ -203,6 +203,7 @@ void tevent_req_received(struct tevent_req *req) > { > TALLOC_FREE(req->data); > req->private_print = NULL; >+ req->private_cancel = NULL; > > TALLOC_FREE(req->internal.trigger); > TALLOC_FREE(req->internal.timer); >-- >1.9.1 > > >From f7cbb57731d35c7ccbd67e99959fcace0a27de43 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 03:02:24 +0200 >Subject: [PATCH 10/55] tevent: tevent_req_create() already uses > ZERO_STRUCT(req) > >There's no need to zero individual members. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7a97d4c4c36d27e2c0732d70345d1766a4a86e94) >--- > lib/tevent/tevent_req.c | 2 -- > 1 file changed, 2 deletions(-) > >diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c >index a324418..581b818 100644 >--- a/lib/tevent/tevent_req.c >+++ b/lib/tevent/tevent_req.c >@@ -70,14 +70,12 @@ struct tevent_req *_tevent_req_create(TALLOC_CTX *mem_ctx, > ZERO_STRUCTP(req); > req->internal.private_type = type; > req->internal.create_location = location; >- req->internal.finish_location = NULL; > req->internal.state = TEVENT_REQ_IN_PROGRESS; > req->internal.trigger = tevent_create_immediate(req); > if (!req->internal.trigger) { > talloc_free(req); > return NULL; > } >- req->internal.defer_callback_ev = NULL; > > data = talloc_zero_size(req, data_size); > if (data == NULL) { >-- >1.9.1 > > >From 747708db9dc153ab83943f225171e8bae76e811f Mon Sep 17 00:00:00 2001 >From: Gregor Beck <gbeck@sernet.de> >Date: Thu, 19 Sep 2013 15:14:25 +0200 >Subject: [PATCH 11/55] tevent: add tevent_queue_wait_send/recv() > >Pair-Programmed-With: Stefan Metzmacher <metze@samba.org> > >Signed-off-by: Gregor Beck <gbeck@sernet.de> >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 8e44c2f96397a4f8cf945bcc810e3a1776d86a08) >--- > lib/tevent/tevent.h | 33 ++++++++++++++++++++++++++++++ > lib/tevent/tevent_queue.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 85 insertions(+) > >diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h >index 2bc4e2d..0705ff3 100644 >--- a/lib/tevent/tevent.h >+++ b/lib/tevent/tevent.h >@@ -1592,6 +1592,39 @@ size_t tevent_queue_length(struct tevent_queue *queue); > */ > bool tevent_queue_running(struct tevent_queue *queue); > >+/** >+ * @brief Create a tevent subrequest that waits in a tevent_queue >+ * >+ * The idea is that always the same syntax for tevent requests. >+ * >+ * @param[in] mem_ctx The talloc memory context to use. >+ * >+ * @param[in] ev The event handle to setup the request. >+ * >+ * @param[in] queue The queue to wait in. >+ * >+ * @return The new subrequest, NULL on error. >+ * >+ * @see tevent_queue_wait_recv() >+ */ >+struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct tevent_queue *queue); >+ >+/** >+ * @brief Check if we no longer need to wait in the queue. >+ * >+ * This function needs to be called in the callback function set after calling >+ * tevent_queue_wait_send(). >+ * >+ * @param[in] req The tevent request to check. >+ * >+ * @return True on success, false otherwise. >+ * >+ * @see tevent_queue_wait_send() >+ */ >+bool tevent_queue_wait_recv(struct tevent_req *req); >+ > typedef int (*tevent_nesting_hook)(struct tevent_context *ev, > void *private_data, > uint32_t level, >diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c >index eeb922f..ebd7147 100644 >--- a/lib/tevent/tevent_queue.c >+++ b/lib/tevent/tevent_queue.c >@@ -302,3 +302,55 @@ bool tevent_queue_running(struct tevent_queue *queue) > { > return queue->running; > } >+ >+struct tevent_queue_wait_state { >+ uint8_t dummy; >+}; >+ >+static void tevent_queue_wait_trigger(struct tevent_req *req, >+ void *private_data); >+ >+struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct tevent_queue *queue) >+{ >+ struct tevent_req *req; >+ struct tevent_queue_wait_state *state; >+ bool ok; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct tevent_queue_wait_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ ok = tevent_queue_add(queue, ev, req, >+ tevent_queue_wait_trigger, >+ NULL); >+ if (!ok) { >+ tevent_req_nomem(NULL, req); >+ return tevent_req_post(req, ev); >+ } >+ >+ return req; >+} >+ >+static void tevent_queue_wait_trigger(struct tevent_req *req, >+ void *private_data) >+{ >+ tevent_req_done(req); >+} >+ >+bool tevent_queue_wait_recv(struct tevent_req *req) >+{ >+ enum tevent_req_state state; >+ uint64_t err; >+ >+ if (tevent_req_is_error(req, &state, &err)) { >+ tevent_req_received(req); >+ return false; >+ } >+ >+ tevent_req_received(req); >+ return true; >+} >-- >1.9.1 > > >From b4a677fe16467480af9054db370b0904ef56f6ad Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:46:47 +0100 >Subject: [PATCH 12/55] tevent: use talloc_get_type_abort() in the > documentation examples > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit fb06f0e3d38a0cd2d6a55e93c993763adb7cf278) >--- > lib/tevent/doc/tevent_events.dox | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/tevent/doc/tevent_events.dox b/lib/tevent/doc/tevent_events.dox >index 8e350d2..d56af25 100644 >--- a/lib/tevent/doc/tevent_events.dox >+++ b/lib/tevent/doc/tevent_events.dox >@@ -45,7 +45,7 @@ struct state { > static void callback(struct tevent_context *ev, struct tevent_timer *tim, > struct timeval current_time, void *private_data) > { >- struct state *data = talloc_get_type(private_data, struct state); >+ struct state *data = talloc_get_type_abort(private_data, struct state); > struct tevent_timer *time_event; > struct timeval schedule; > >@@ -153,7 +153,7 @@ struct info_struct { > static void foo(struct tevent_context *ev, struct tevent_immediate *im, > void *private_data) > { >- struct info_struct *data = talloc_get_type(private_data, struct info_struct); >+ struct info_struct *data = talloc_get_type_abort(private_data, struct info_struct); > printf("Data value: %d\n", data->counter); > } > >-- >1.9.1 > > >From c77a80219a66660604f6acd21031871c06e11644 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:47:27 +0100 >Subject: [PATCH 13/55] tevent: make use of talloc_get_type_abort() in > tevent_queue.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 982bf3c082893bbf59a76ed0e7f670d8932102b1) >--- > lib/tevent/tevent_queue.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > >diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c >index ebd7147..9c5d469 100644 >--- a/lib/tevent/tevent_queue.c >+++ b/lib/tevent/tevent_queue.c >@@ -133,8 +133,9 @@ static void tevent_queue_immediate_trigger(struct tevent_context *ev, > struct tevent_immediate *im, > void *private_data) > { >- struct tevent_queue *q = talloc_get_type(private_data, >- struct tevent_queue); >+ struct tevent_queue *q = >+ talloc_get_type_abort(private_data, >+ struct tevent_queue); > > if (!q->running) { > return; >-- >1.9.1 > > >From e719001e6aed8e57f1f86c206470819515415cdc Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:47:27 +0100 >Subject: [PATCH 14/55] tevent: make use of talloc_get_type_abort() in > tevent_req.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 99910b67d267732ac088d9b2b96cd08d367f2cec) >--- > lib/tevent/tevent_req.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > >diff --git a/lib/tevent/tevent_req.c b/lib/tevent/tevent_req.c >index 581b818..edb8550 100644 >--- a/lib/tevent/tevent_req.c >+++ b/lib/tevent/tevent_req.c >@@ -167,8 +167,9 @@ static void tevent_req_trigger(struct tevent_context *ev, > struct tevent_immediate *im, > void *private_data) > { >- struct tevent_req *req = talloc_get_type(private_data, >- struct tevent_req); >+ struct tevent_req *req = >+ talloc_get_type_abort(private_data, >+ struct tevent_req); > > tevent_req_finish(req, req->internal.state, > req->internal.finish_location); >@@ -242,8 +243,9 @@ static void tevent_req_timedout(struct tevent_context *ev, > struct timeval now, > void *private_data) > { >- struct tevent_req *req = talloc_get_type(private_data, >- struct tevent_req); >+ struct tevent_req *req = >+ talloc_get_type_abort(private_data, >+ struct tevent_req); > > TALLOC_FREE(req->internal.timer); > >-- >1.9.1 > > >From b3d8e85c211dd8487e2e83862aeb3d3a18d5bd2b Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:47:27 +0100 >Subject: [PATCH 15/55] tevent: make use of talloc_get_type_abort() in > tevent_select.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit fbdaf7481b81f021a560e366276c79be6680bce6) >--- > lib/tevent/tevent_select.c | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > >diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c >index bfce246..73f27b7 100644 >--- a/lib/tevent/tevent_select.c >+++ b/lib/tevent/tevent_select.c >@@ -91,8 +91,8 @@ static int select_event_fd_destructor(struct tevent_fd *fde) > struct select_event_context *select_ev = NULL; > > if (ev) { >- select_ev = talloc_get_type(ev->additional_data, >- struct select_event_context); >+ select_ev = talloc_get_type_abort(ev->additional_data, >+ struct select_event_context); > > if (select_ev->maxfd == fde->fd) { > select_ev->maxfd = EVENT_INVALID_MAXFD; >@@ -113,8 +113,9 @@ static struct tevent_fd *select_event_add_fd(struct tevent_context *ev, TALLOC_C > const char *handler_name, > const char *location) > { >- struct select_event_context *select_ev = talloc_get_type(ev->additional_data, >- struct select_event_context); >+ struct select_event_context *select_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct select_event_context); > struct tevent_fd *fde; > > if (fd < 0 || fd >= FD_SETSIZE) { >@@ -236,8 +237,9 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru > */ > static int select_event_loop_once(struct tevent_context *ev, const char *location) > { >- struct select_event_context *select_ev = talloc_get_type(ev->additional_data, >- struct select_event_context); >+ struct select_event_context *select_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct select_event_context); > struct timeval tval; > > if (ev->signal_events && >-- >1.9.1 > > >From 42ab61a893d6f793b9eff69c769048635400f5ee Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:47:27 +0100 >Subject: [PATCH 16/55] tevent: make use of talloc_get_type_abort() in > tevent_signal.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7bf5e6b181cc4ea23103ac3fc4f183ba183476b6) >--- > lib/tevent/tevent_signal.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index fd321ff..3f157c4 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -176,9 +176,9 @@ static int tevent_common_signal_list_destructor(struct tevent_common_signal_list > */ > static int tevent_signal_destructor(struct tevent_signal *se) > { >- struct tevent_common_signal_list *sl; >- sl = talloc_get_type(se->additional_data, >- struct tevent_common_signal_list); >+ struct tevent_common_signal_list *sl = >+ talloc_get_type_abort(se->additional_data, >+ struct tevent_common_signal_list); > > if (se->event_ctx) { > struct tevent_context *ev = se->event_ctx; >@@ -486,9 +486,9 @@ int tevent_common_check_signal(struct tevent_context *ev) > > void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se) > { >- struct tevent_common_signal_list *sl; >- sl = talloc_get_type(se->additional_data, >- struct tevent_common_signal_list); >+ struct tevent_common_signal_list *sl = >+ talloc_get_type_abort(se->additional_data, >+ struct tevent_common_signal_list); > > tevent_common_signal_list_destructor(sl); > >-- >1.9.1 > > >From d9e8589914a9af21a8168ddf1753159aed08d5f2 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 5 Dec 2013 08:47:27 +0100 >Subject: [PATCH 17/55] tevent: make use of talloc_get_type_abort() in > tevent_epoll.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 4cc02d7c84e6c6a07ecde02fc6792ed041bdbe3a) >--- > lib/tevent/tevent_epoll.c | 26 +++++++++++--------------- > 1 file changed, 11 insertions(+), 15 deletions(-) > >diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c >index 599c190..951fa42 100644 >--- a/lib/tevent/tevent_epoll.c >+++ b/lib/tevent/tevent_epoll.c >@@ -120,17 +120,10 @@ _PRIVATE_ bool tevent_epoll_set_panic_fallback(struct tevent_context *ev, > bool (*panic_fallback)(struct tevent_context *ev, > bool replay)) > { >- struct epoll_event_context *epoll_ev; >- >- if (ev->additional_data == NULL) { >- return false; >- } >+ struct epoll_event_context *epoll_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct epoll_event_context); > >- epoll_ev = talloc_get_type(ev->additional_data, >- struct epoll_event_context); >- if (epoll_ev == NULL) { >- return false; >- } > epoll_ev->panic_fallback = panic_fallback; > return true; > } >@@ -843,8 +836,9 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT > const char *handler_name, > const char *location) > { >- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, >- struct epoll_event_context); >+ struct epoll_event_context *epoll_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct epoll_event_context); > struct tevent_fd *fde; > bool panic_triggered = false; > >@@ -879,7 +873,8 @@ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) > if (fde->flags == flags) return; > > ev = fde->event_ctx; >- epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context); >+ epoll_ev = talloc_get_type_abort(ev->additional_data, >+ struct epoll_event_context); > > fde->flags = flags; > >@@ -898,8 +893,9 @@ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) > */ > static int epoll_event_loop_once(struct tevent_context *ev, const char *location) > { >- struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, >- struct epoll_event_context); >+ struct epoll_event_context *epoll_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct epoll_event_context); > struct timeval tval; > bool panic_triggered = false; > >-- >1.9.1 > > >From 422190d7438d48f0dee73c5f8ed33e243269b743 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 11 Dec 2013 18:58:41 +0100 >Subject: [PATCH 18/55] tevent: tevent_epoll_set_panic_fallback() can be a void > function > >There's no case where this could return an error. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 36345d44c8f5ac614f40a9b5bd4b421ffa6cd49a) >--- > lib/tevent/tevent_epoll.c | 2 +- > lib/tevent/tevent_internal.h | 2 +- > lib/tevent/tevent_standard.c | 5 +---- > 3 files changed, 3 insertions(+), 6 deletions(-) > >diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c >index 951fa42..b0d15c8 100644 >--- a/lib/tevent/tevent_epoll.c >+++ b/lib/tevent/tevent_epoll.c >@@ -116,7 +116,7 @@ static int epoll_wait_panic_fallback(struct epoll_event_context *epoll_ev, > /* > called to set the panic fallback function. > */ >-_PRIVATE_ bool tevent_epoll_set_panic_fallback(struct tevent_context *ev, >+_PRIVATE_ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, > bool (*panic_fallback)(struct tevent_context *ev, > bool replay)) > { >diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h >index b239e74..df73288 100644 >--- a/lib/tevent/tevent_internal.h >+++ b/lib/tevent/tevent_internal.h >@@ -335,7 +335,7 @@ void tevent_poll_event_add_fd_internal(struct tevent_context *ev, > bool tevent_poll_mt_init(void); > #ifdef HAVE_EPOLL > bool tevent_epoll_init(void); >-bool tevent_epoll_set_panic_fallback(struct tevent_context *ev, >+void tevent_epoll_set_panic_fallback(struct tevent_context *ev, > bool (*panic_fallback)(struct tevent_context *ev, > bool replay)); > #endif >diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c >index 2584994..785d68d 100644 >--- a/lib/tevent/tevent_standard.c >+++ b/lib/tevent/tevent_standard.c >@@ -206,10 +206,7 @@ static int std_event_context_init(struct tevent_context *ev) > goto fallback; > } > #ifdef HAVE_EPOLL >- if (!tevent_epoll_set_panic_fallback(ev, std_fallback_to_poll)) { >- TALLOC_FREE(ev->additional_data); >- goto fallback; >- } >+ tevent_epoll_set_panic_fallback(ev, std_fallback_to_poll); > #endif > > return ret; >-- >1.9.1 > > >From 35eddff534e2b36350e1aa20f5fd7fc197afd8b4 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 9 Dec 2013 10:29:45 +0100 >Subject: [PATCH 19/55] tevent: change TEVENT_SA_INFO_QUEUE_COUNT from 64 to > 256 > >There are some existing callers which assume the old >SA_INFO_QUEUE_COUNT 100 value. > >256 should give room for the future. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10214 >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit cbb93f5442776fbe9810d242f7fe6759adfe3194) >--- > lib/tevent/tevent_signal.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index 3f157c4..bc58459 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -35,7 +35,7 @@ > wrap to work correctly. Thanks to Petr Vandrovec <petr@vandrovec.name> > for this. */ > >-#define TEVENT_SA_INFO_QUEUE_COUNT 64 >+#define TEVENT_SA_INFO_QUEUE_COUNT 256 > > struct tevent_sigcounter { > uint32_t count; >-- >1.9.1 > > >From 2fa1daefb955b03930eab03090fab65849a408fe Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 9 Dec 2013 10:32:00 +0100 >Subject: [PATCH 20/55] tevent: give the user the chance to ask for > TEVENT_NUM_SIGNALS and TEVENT_SA_INFO_QUEUE_COUNT > >This way the caller can change use the supported limits without using hardcoded >values. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=10214 >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 4b330ba0a83e17205c851e83097ec8c1dab02a5c) >--- > lib/tevent/tevent_signal.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index bc58459..b54da2e 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -37,6 +37,16 @@ > > #define TEVENT_SA_INFO_QUEUE_COUNT 256 > >+size_t tevent_num_signals(void) >+{ >+ return TEVENT_NUM_SIGNALS; >+} >+ >+size_t tevent_sa_info_queue_count(void) >+{ >+ return TEVENT_SA_INFO_QUEUE_COUNT; >+} >+ > struct tevent_sigcounter { > uint32_t count; > uint32_t seen; >-- >1.9.1 > > >From e071db52734bb679094e3534092f0e6be1e19776 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 04:06:00 +0200 >Subject: [PATCH 21/55] tevent: version 0.9.20 > >This adds the following new features: > >- tevent_queue_wait_send/recv() >- tevent_num_signals() >- tevent_sa_info_queue_count() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Thu Dec 12 00:39:35 CET 2013 on sn-devel-104 > >(cherry picked from commit e26736dcc25a204bf21a367462d0c10060bee1ad) >--- > lib/tevent/ABI/tevent-0.9.20.sigs | 87 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 88 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.20.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.20.sigs b/lib/tevent/ABI/tevent-0.9.20.sigs >new file mode 100644 >index 0000000..7b9c77d >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.20.sigs >@@ -0,0 +1,87 @@ >+_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_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 39f2ae4..3fc87f5 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.19' >+VERSION = '0.9.20' > > blddir = 'bin' > >-- >1.9.1 > > >From 41614d19244399ae67e831c9a17a82ce2bab3c24 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 15 Dec 2013 20:40:06 +0100 >Subject: [PATCH 22/55] tevent: Fix CID 1138326 Unchecked return value > >For this case we explicitly have added tevent_req_oom > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 91ef262c633aebd0da8ab7c4b51e2aa9d55b7ddb) >--- > lib/tevent/tevent_queue.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_queue.c b/lib/tevent/tevent_queue.c >index 9c5d469..35742e5 100644 >--- a/lib/tevent/tevent_queue.c >+++ b/lib/tevent/tevent_queue.c >@@ -329,7 +329,7 @@ struct tevent_req *tevent_queue_wait_send(TALLOC_CTX *mem_ctx, > tevent_queue_wait_trigger, > NULL); > if (!ok) { >- tevent_req_nomem(NULL, req); >+ tevent_req_oom(req); > return tevent_req_post(req, ev); > } > >-- >1.9.1 > > >From 8f9f64e5775beba803a31b1fd46d4617ee0b4101 Mon Sep 17 00:00:00 2001 >From: Simo Sorce <idra@samba.org> >Date: Wed, 25 Dec 2013 23:20:58 -0500 >Subject: [PATCH 23/55] Do not return a value from a void function. > >Reported by herwin <samba@herwinw.nl> >Resolves: https://bugzilla.samba.org/show_bug.cgi?id=10346 > >Signed-off-by: Simo Sorce <idra@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit ec499c3d668d0788c64276bf9a0f58ce9a915bd6) >--- > lib/tevent/tevent_epoll.c | 1 - > 1 file changed, 1 deletion(-) > >diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c >index b0d15c8..01fcde6 100644 >--- a/lib/tevent/tevent_epoll.c >+++ b/lib/tevent/tevent_epoll.c >@@ -125,7 +125,6 @@ _PRIVATE_ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, > struct epoll_event_context); > > epoll_ev->panic_fallback = panic_fallback; >- return true; > } > > /* >-- >1.9.1 > > >From 647c87a3b81fca6a409b317452c92d608f6cf8ff Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 13 Dec 2013 11:59:43 +0100 >Subject: [PATCH 24/55] tevent: Only build "std_fallback_to_poll" when epoll is > around > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit e7d4b7deda2fac7a7dd86dad84bafcae8085ff80) >--- > 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.9.1 > > >From bc68dcd58f00cb5e1882c7e2b105fb7de9236b4a Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 13 Dec 2013 11:59:04 +0100 >Subject: [PATCH 25/55] tevent: Add prototypes > >... doxygen docs to be filled in :-) > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit fd80e544169db5fb86288b7b22da4e98a88f4477) >--- > 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.9.1 > > >From ccab0c4c74f3b441e5cb090865b387df4ccd80a8 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 8 Jan 2014 10:01:56 +0100 >Subject: [PATCH 26/55] tevent: add doxygen comments for tevent_num_signals() > and tevent_sa_info_queue_count() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 7502a309e8b817036c1ddc38740c214ae416bf29) >--- > 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.9.1 > > >From 0714e66c2241806adbe94d6e8a217df8b0228f4a Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 03:41:29 +0200 >Subject: [PATCH 27/55] 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@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 0ed93e099af833045d9d00b9a8faeb5b93b6ef2e) >--- > 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.9.1 > > >From 6a00b5906ad935ce06bf4e61cde2fb7fe49899eb Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 02:29:57 +0200 >Subject: [PATCH 28/55] 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@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit 50b9f154d22f5c356e66bba341e9ee0292218cfd) >--- > 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.9.1 > > >From c115250052987cbb79c5e5344d2bb41e492165f6 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 27 Sep 2013 04:06:00 +0200 >Subject: [PATCH 29/55] 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@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >(cherry picked from commit c4c88d1ee8960ae0d8a392821cf4f218725ab660) >--- > 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.9.1 > > >From 8e1a47a840d9bd2156a64f11bb93cad9e23d5a8f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 27 Feb 2014 09:08:17 +0100 >Subject: [PATCH 30/55] lib/tevent/tests: add missing #include > "torture/local/proto.h" > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 4e5404967ecfd865d8554acfde8fa45c94702eb6) >--- > lib/tevent/testsuite.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c >index 7851c6c..34d13bb 100644 >--- a/lib/tevent/testsuite.c >+++ b/lib/tevent/testsuite.c >@@ -30,6 +30,7 @@ > #include "system/select.h" > #include "system/network.h" > #include "torture/torture.h" >+#include "torture/local/proto.h" > #ifdef HAVE_PTHREAD > #include <pthread.h> > #include <assert.h> >-- >1.9.1 > > >From 680e44b89ec879228ca7447c9dba43ebfa405195 Mon Sep 17 00:00:00 2001 >From: Lukas Slebodnik <lslebodn@redhat.com> >Date: Fri, 4 Apr 2014 13:27:35 +0200 >Subject: [PATCH 31/55] tevent: Update flags in tevent pkgconfig file > >After exapnding, @LIB_RPATH@ will be -Wl,-rpatch,/usr/local/lib if rpath is >used on install. But "-Wl," will be passed to linker and should not be among >CFLAGS. Other pkgconfig files have @LIB_RPATH@ in the right place. > @see commit 735c1cd2da15167748e92ba6de48fdb5169db587 > >Signed-off-by: Lukas Slebodnik <lslebodn@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> >(cherry picked from commit a83c5240b1332d5a97dd21ecd3666a9c2ff38643) >--- > lib/tevent/tevent.pc.in | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/tevent/tevent.pc.in b/lib/tevent/tevent.pc.in >index 1091ff0..eb0e564 100644 >--- a/lib/tevent/tevent.pc.in >+++ b/lib/tevent/tevent.pc.in >@@ -7,6 +7,6 @@ Name: tevent > Description: An event system library > Version: @PACKAGE_VERSION@ > Requires: talloc >-Libs: -L${libdir} -ltevent >-Cflags: @LIB_RPATH@ -I${includedir} >+Libs: @LIB_RPATH@ -L${libdir} -ltevent >+Cflags: -I${includedir} > URL: http://samba.org/ >-- >1.9.1 > > >From aeb9ae4122ff3a8b9606882f46d697f6f1c353ea Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Fri, 20 Jun 2014 18:04:13 +0200 >Subject: [PATCH 32/55] tevent:build: improve detection of srcdir > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Amitay Isaacs <amitay@gmail.com> >(cherry picked from commit befb39441f6919624df475c6495e822e5acc42ff) >--- > lib/tevent/wscript | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/tevent/wscript b/lib/tevent/wscript >index bd19780..8d29e04 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -10,7 +10,7 @@ import sys, os > # find the buildtools directory > srcdir = '.' > while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5: >- srcdir = '../' + srcdir >+ srcdir = srcdir + '/..' > sys.path.insert(0, srcdir + '/buildtools/wafsamba') > > import wafsamba, samba_dist, Options, Logs >-- >1.9.1 > > >From 1f9dcdf5273a5e321702d08441957169b59bb16c Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Sun, 14 Sep 2014 20:45:31 +0200 >Subject: [PATCH 33/55] lib: Polish echo_server > >Samba has a lot of struct assignments now, in a lot of cases it simplifies the >code. Use it in the sample code. > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Martin Schwenke <martin@meltin.net> > >Autobuild-User(master): Volker Lendecke <vl@samba.org> >Autobuild-Date(master): Thu Sep 18 23:02:38 CEST 2014 on sn-devel-104 >--- > lib/tevent/echo_server.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > >diff --git a/lib/tevent/echo_server.c b/lib/tevent/echo_server.c >index a1da0d8..102f7b4 100644 >--- a/lib/tevent/echo_server.c >+++ b/lib/tevent/echo_server.c >@@ -619,10 +619,10 @@ int main(int argc, const char **argv) > exit(1); > } > >- memset(&addr, 0, sizeof(addr)); >- >- addr.sin_family = AF_INET; >- addr.sin_port = htons(port); >+ addr = (struct sockaddr_in) { >+ .sin_family = AF_INET, >+ .sin_port = htons(port) >+ }; > > ret = bind(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); > if (ret == -1) { >-- >1.9.1 > > >From 0ed076081f8066eae3bac1cf121c38c33742de9f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 22 Jul 2014 14:54:11 +0200 >Subject: [PATCH 34/55] tevent: remove unused exit_code in tevent_poll.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 1ea3364721522dcd68fee629b017e72ab35ff6e1) >--- > lib/tevent/tevent_poll.c | 3 --- > 1 file changed, 3 deletions(-) > >diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c >index 75d0ced..573ba93 100644 >--- a/lib/tevent/tevent_poll.c >+++ b/lib/tevent/tevent_poll.c >@@ -58,9 +58,6 @@ struct poll_event_context { > * Signal fd to wake the poll() thread > */ > int signal_fd; >- >- /* information for exiting from the event loop */ >- int exit_code; > }; > > static int poll_event_context_destructor(struct poll_event_context *poll_ev) >-- >1.9.1 > > >From c8ae741ac82734d125b2306511cab46a1fce26ac Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 22 Jul 2014 14:54:11 +0200 >Subject: [PATCH 35/55] tevent: remove unused exit_code in tevent_select.c > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit a65df7e8c0ce687625a18de5769bf38f92118eca) >--- > lib/tevent/tevent_select.c | 5 +---- > 1 file changed, 1 insertion(+), 4 deletions(-) > >diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c >index 73f27b7..40a4dc0 100644 >--- a/lib/tevent/tevent_select.c >+++ b/lib/tevent/tevent_select.c >@@ -35,9 +35,6 @@ struct select_event_context { > > /* the maximum file descriptor number in fd_events */ > int maxfd; >- >- /* information for exiting from the event loop */ >- int exit_code; > }; > > /* >@@ -198,7 +195,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru > fatal error. */ > tevent_debug(select_ev->ev, TEVENT_DEBUG_FATAL, > "ERROR: EBADF on select_event_loop_once\n"); >- select_ev->exit_code = EBADF; >+ errno = select_errno; > return -1; > } > >-- >1.9.1 > > >From 71314b59a7c15e585e791c03b809162897765dbe Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 30 Sep 2014 14:44:30 +0200 >Subject: [PATCH 36/55] tevent: version 0.9.22 > >* pkgconfig fixes >* Bug #10640 - smbd is not responding - tevent_common_signal_handler() > increments non-atomic variables. > https://bugzilla.samba.org/show_bug.cgi?id=10640 >* Minor compile fixes > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 1dbd0bec040060193f1d2f1b5a97db1bd340c1ca) >--- > lib/tevent/ABI/tevent-0.9.22.sigs | 88 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 89 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.22.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.22.sigs b/lib/tevent/ABI/tevent-0.9.22.sigs >new file mode 100644 >index 0000000..d8b9f4b >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.22.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 8d29e04..a991fed 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.21' >+VERSION = '0.9.22' > > blddir = 'bin' > >-- >1.9.1 > > >From 653f00bced0c729558e9539ca93176afd64b9c98 Mon Sep 17 00:00:00 2001 >From: Richard Sharpe <rsharpe@samba.org> >Date: Fri, 23 Jan 2015 21:56:19 -0800 >Subject: [PATCH 37/55] Update the tevent_data.dox tutrial stuff to fix some > errors, including white space problems. > >Signed-off-by: Richard Sharpe <rsharpe@samba.org> >Reviewed-by: Ralph Boehme <rb@sernet.de> > >Autobuild-User(master): Richard Sharpe <sharpe@samba.org> >Autobuild-Date(master): Sat Jan 24 09:33:03 CET 2015 on sn-devel-104 > >(cherry picked from commit 6a56bdf9869162e57c816c067598552bd33c2910) >(cherry picked from commit 2f50cd2554ac400ea1fc2e6aa5c7127d8b5f876f) >--- > lib/tevent/doc/tevent_data.dox | 30 +++++++++++++++++------------- > 1 file changed, 17 insertions(+), 13 deletions(-) > >diff --git a/lib/tevent/doc/tevent_data.dox b/lib/tevent/doc/tevent_data.dox >index 4ee4ac2..dbe7a04 100644 >--- a/lib/tevent/doc/tevent_data.dox >+++ b/lib/tevent/doc/tevent_data.dox >@@ -46,18 +46,19 @@ struct testA { > > > static void foo_done(struct tevent_req *req) { >-// a->x contains 9 >-struct foo_state *a = tevent_req_data(req, struct foo_state); >+ // a->x contains 10 since it came from foo_send >+ struct foo_state *a = tevent_req_data(req, struct foo_state); > >-// b->y contains 10 >-struct testA *b = tevent_req_callback_data(req, struct testA); >+ // b->y contains 9 since it came from run >+ struct testA *b = tevent_req_callback_data(req, struct testA); > >-// c->y contains 10 >-struct testA *c = (struct testA *)tevent_req_callback_data_void(req); >+ // c->y contains 9 since it came from run we just used a different way >+ // of getting it. >+ struct testA *c = (struct testA *)tevent_req_callback_data_void(req); > >-printf("a->x: %d\n", a->x); >-printf("b->y: %d\n", b->y); >-printf("c->y: %d\n", c->y); >+ printf("a->x: %d\n", a->x); >+ printf("b->y: %d\n", b->y); >+ printf("c->y: %d\n", c->y); > } > > >@@ -77,6 +78,9 @@ static void run(struct tevent_context *ev, struct tevent_timer *te, > struct timeval current_time, void *private_data) { > struct tevent_req *req; > struct testA *tmp = talloc(ev, struct testA); >+ >+ // Note that we did not use the private data passed in >+ > tmp->y = 9; > req = foo_send(ev, ev); > >@@ -101,7 +105,7 @@ int main (int argc, char **argv) { > return EXIT_FAILURE; > > data = talloc(mem_ctx, struct testA); >- data->y = 10; >+ data->y = 11; > > time_event = tevent_add_timer(event_ctx, > mem_ctx, >@@ -125,9 +129,9 @@ int main (int argc, char **argv) { > Output of this example is: > > @code >-a->x: 9 >-b->y: 10 >-c->y: 10 >+a->x: 10 >+b->y: 9 >+c->y: 9 > @endcode > > */ >-- >1.9.1 > > >From ebdc50018b6613eb58a8fd6e35f23b70596e5947 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 22 Jul 2013 14:23:33 -0700 >Subject: [PATCH 38/55] Add Solaris ports as a tevent backend. > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: David Disseldorp <ddiss@samba.org> > >Autobuild-User(master): David Disseldorp <ddiss@samba.org> >Autobuild-Date(master): Sun Feb 15 23:25:07 CET 2015 on sn-devel-104 > >(cherry picked from commit 88c1eb4ae10a9f69d2e828b4e5543915c1d990c6) >(cherry picked from commit bc8585b0120eb5956a0b9397fe07902c76fea072) >--- > lib/replace/system/select.h | 4 + > lib/replace/wscript | 5 + > lib/tevent/tevent.c | 5 +- > lib/tevent/tevent_internal.h | 3 + > lib/tevent/tevent_port.c | 779 +++++++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 3 + > 6 files changed, 798 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/tevent_port.c > >diff --git a/lib/replace/system/select.h b/lib/replace/system/select.h >index 11c5390..9e945c3 100644 >--- a/lib/replace/system/select.h >+++ b/lib/replace/system/select.h >@@ -34,6 +34,10 @@ > #include <sys/epoll.h> > #endif > >+#ifdef HAVE_SOLARIS_PORTS >+#include <port.h> >+#endif >+ > #ifndef SELECT_CAST > #define SELECT_CAST > #endif >diff --git a/lib/replace/wscript b/lib/replace/wscript >index f0040b1..e64d849 100644 >--- a/lib/replace/wscript >+++ b/lib/replace/wscript >@@ -76,6 +76,7 @@ struct foo bar = { .y = 'X', .x = 1 }; > conf.CHECK_HEADERS('libaio.h locale.h ndir.h pwd.h') > conf.CHECK_HEADERS('shadow.h sys/acl.h') > conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h') >+ conf.CHECK_HEADERS('port.h') > conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h sys/fs/vx/quota.h') > conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h') > conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h') >@@ -317,6 +318,7 @@ struct foo bar = { .y = 'X', .x = 1 }; > conf.CHECK_FUNCS('timegm getifaddrs freeifaddrs mmap setgroups syscall setsid') > conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize') > conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create') >+ conf.CHECK_FUNCS('port_create') > > conf.SET_TARGET_TYPE('attr', 'EMPTY') > >@@ -457,6 +459,9 @@ removeea setea > if conf.CONFIG_SET('HAVE_EPOLL_CREATE') and conf.CONFIG_SET('HAVE_SYS_EPOLL_H'): > conf.DEFINE('HAVE_EPOLL', 1) > >+ if conf.CONFIG_SET('HAVE_PORT_CREATE') and conf.CONFIG_SET('HAVE_PORT_H'): >+ conf.DEFINE('HAVE_SOLARIS_PORTS', 1) >+ > conf.CHECK_HEADERS('poll.h') > conf.CHECK_FUNCS('poll') > >diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c >index be0afd4..843cf05 100644 >--- a/lib/tevent/tevent.c >+++ b/lib/tevent/tevent.c >@@ -123,9 +123,12 @@ static void tevent_backend_init(void) > tevent_select_init(); > tevent_poll_init(); > tevent_poll_mt_init(); >-#ifdef HAVE_EPOLL >+#if defined(HAVE_EPOLL) > tevent_epoll_init(); >+#elif defined(HAVE_SOLARIS_PORTS) >+ tevent_port_init(); > #endif >+ > tevent_standard_init(); > } > >diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h >index d25dc05..10cc4a4 100644 >--- a/lib/tevent/tevent_internal.h >+++ b/lib/tevent/tevent_internal.h >@@ -351,6 +351,9 @@ void tevent_epoll_set_panic_fallback(struct tevent_context *ev, > bool (*panic_fallback)(struct tevent_context *ev, > bool replay)); > #endif >+#ifdef HAVE_SOLARIS_PORTS >+bool tevent_port_init(void); >+#endif > > > void tevent_trace_point_callback(struct tevent_context *ev, >diff --git a/lib/tevent/tevent_port.c b/lib/tevent/tevent_port.c >new file mode 100644 >index 0000000..93e94b2 >--- /dev/null >+++ b/lib/tevent/tevent_port.c >@@ -0,0 +1,779 @@ >+/* >+ Unix SMB/CIFS implementation. >+ >+ Main select loop and event handling - Solaris port implementation. >+ Losely based on the Linux epoll backend. >+ >+ Copyright (C) Jeremy Allison 2013 >+ >+ ** 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 "system/filesys.h" >+#include "system/select.h" >+#include "tevent.h" >+#include "tevent_internal.h" >+#include "tevent_util.h" >+ >+struct port_associate_vals { >+ struct port_associate_vals *prev, *next; >+ struct port_event_context *port_ev; >+ int events; >+ struct tevent_fd *fde; >+ bool associated_event; >+}; >+ >+struct port_event_context { >+ /* a pointer back to the generic event_context */ >+ struct tevent_context *ev; >+ >+ /* This is the handle from port_create */ >+ int port_fd; >+ >+ pid_t pid; >+ >+ /* List of associations. */ >+ struct port_associate_vals *po_vals; >+}; >+ >+#define PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION (1<<0) >+#define PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1) >+#define PORT_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2) >+#define PORT_ADDITIONAL_FD_FLAG_HAS_MPX (1<<3) >+ >+/* >+ Map from TEVENT_FD_* to POLLIN/POLLOUT >+*/ >+static int port_map_flags(uint16_t flags) >+{ >+ int ret = 0; >+ if (flags & TEVENT_FD_READ) ret |= (POLLIN | POLLERR | POLLHUP); >+ if (flags & TEVENT_FD_WRITE) ret |= (POLLOUT | POLLERR | POLLHUP); >+ return ret; >+} >+ >+/* >+ Free the port fd >+*/ >+static int port_ctx_destructor(struct port_event_context *port_ev) >+{ >+ close(port_ev->port_fd); >+ port_ev->port_fd = -1; >+ return 0; >+} >+ >+/* >+ Init the port fd >+*/ >+static int port_init_ctx(struct port_event_context *port_ev) >+{ >+ port_ev->port_fd = port_create(); >+ if (port_ev->port_fd == -1) { >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, >+ "Failed to create port handle.\n"); >+ return -1; >+ } >+ >+ if (!ev_set_close_on_exec(port_ev->port_fd)) { >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, >+ "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); >+ } >+ >+ port_ev->pid = getpid(); >+ talloc_set_destructor(port_ev, port_ctx_destructor); >+ >+ return 0; >+} >+ >+/* >+ Functions to manage the lower level cache of associated events on the port_fd. >+*/ >+ >+static int port_associate_vals_destructor(struct port_associate_vals *val) >+{ >+ DLIST_REMOVE(val->port_ev->po_vals, val); >+ memset(val, '\0', sizeof(struct port_associate_vals)); >+ return 0; >+} >+ >+/* >+ * TODO: As the port_association is per-fde, it should be possible to store it >+ * directly in fde->additional_data, alongside any multiplexed-fde. That way the >+ * lookup on store and delete would be avoided, and associate_all_events() could >+ * walk the ev->fd_events list. >+ */ >+static bool store_port_association(struct port_event_context *port_ev, >+ struct tevent_fd *fde, >+ int events) >+{ >+ struct port_associate_vals *val; >+ >+ for (val = port_ev->po_vals; val; val = val->next) { >+ if (val->fde->fd == fde->fd) { >+ /* Association already attached to fd. */ >+ if (val->events != events) { >+ val->events = events; >+ val->associated_event = false; >+ } >+ return true; >+ } >+ } >+ >+ val = talloc_zero(port_ev, struct port_associate_vals); >+ if (val == NULL) { >+ return false; >+ } >+ >+ val->port_ev = port_ev; >+ val->fde = fde; >+ val->events = events; >+ val->associated_event = false; >+ >+ DLIST_ADD(port_ev->po_vals, val); >+ talloc_set_destructor(val, port_associate_vals_destructor); >+ >+ return true; >+} >+ >+static void delete_port_association(struct port_event_context *port_ev, >+ struct tevent_fd *fde) >+{ >+ struct port_associate_vals *val; >+ >+ for (val = port_ev->po_vals; val; val = val->next) { >+ if (val->fde == fde) { >+ if (val->associated_event) { >+ (void)port_dissociate(port_ev->port_fd, >+ PORT_SOURCE_FD, >+ fde->fd); >+ } >+ talloc_free(val); >+ return; >+ } >+ } >+} >+ >+static int associate_all_events(struct port_event_context *port_ev) >+{ >+ struct port_associate_vals *val; >+ >+ for (val = port_ev->po_vals; val; val = val->next) { >+ if (val->associated_event) { >+ continue; >+ } >+ int ret = port_associate(port_ev->port_fd, >+ PORT_SOURCE_FD, >+ (uintptr_t)val->fde->fd, >+ val->events, >+ (void *)val); >+ if (ret != 0) { >+ return -1; >+ } >+ val->associated_event = true; >+ } >+ return 0; >+} >+ >+static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde); >+ >+/* >+ Reopen the port handle when our pid changes. >+ */ >+static int port_check_reopen(struct port_event_context *port_ev) >+{ >+ struct tevent_fd *fde; >+ >+ if (port_ev->pid == getpid()) { >+ return 0; >+ } >+ >+ close(port_ev->port_fd); >+ port_ev->port_fd = port_create(); >+ if (port_ev->port_fd == -1) { >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, >+ "port_create() failed"); >+ return -1; >+ } >+ >+ if (!ev_set_close_on_exec(port_ev->port_fd)) { >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_WARNING, >+ "Failed to set close-on-exec, file descriptor may be leaked to children.\n"); >+ } >+ >+ port_ev->pid = getpid(); >+ for (fde=port_ev->ev->fd_events;fde;fde=fde->next) { >+ fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ if (port_update_event(port_ev, fde) != 0) { >+ return -1; >+ } >+ } >+ return 0; >+} >+ >+/* >+ * Solaris ports cannot add the same file descriptor twice, once >+ * with read, once with write which is allowed by the tevent backend. >+ * Multiplex the existing fde, flag it as such so we can search for the >+ * correct fde on event triggering. >+ */ >+ >+static void port_setup_multiplex_fd(struct port_event_context *port_ev, >+ struct tevent_fd *add_fde, >+ struct tevent_fd *mpx_fde) >+{ >+ /* >+ * Make each fde->additional_data pointers point at each other >+ * so we can look them up from each other. They are now paired. >+ */ >+ mpx_fde->additional_data = add_fde; >+ add_fde->additional_data = mpx_fde; >+ >+ /* Now flag both fde's as being multiplexed. */ >+ mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; >+ add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_MPX; >+ >+ /* We need to keep the GOT_ERROR flag. */ >+ if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR) { >+ add_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; >+ } >+} >+ >+/* >+ Add the port event to the given fd_event, >+ Or modify an existing event. >+*/ >+ >+static int port_add_event(struct port_event_context *port_ev, struct tevent_fd *fde) >+{ >+ int flags = port_map_flags(fde->flags); >+ struct tevent_fd *mpx_fde = NULL; >+ >+ fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ /* >+ * This is already a multiplexed fde, we need to include both >+ * flags in the modified event. >+ */ >+ mpx_fde = talloc_get_type_abort(fde->additional_data, >+ struct tevent_fd); >+ >+ mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ >+ flags |= port_map_flags(mpx_fde->flags); >+ } else { >+ /* >+ * Not (yet) a multiplexed event. See if there >+ * is already an event with the same fd. >+ */ >+ for (mpx_fde = port_ev->ev->fd_events; mpx_fde; mpx_fde = mpx_fde->next) { >+ if (mpx_fde->fd != fde->fd) { >+ continue; >+ } >+ if (mpx_fde == fde) { >+ continue; >+ } >+ /* Same fd. */ >+ break; >+ } >+ if (mpx_fde) { >+ if (mpx_fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ /* Logic error. Can't have more then 2 multiplexed fde's. */ >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, >+ "multiplex fde for fd[%d] is already multiplexed\n", >+ mpx_fde->fd); >+ return -1; >+ } >+ flags |= port_map_flags(mpx_fde->flags); >+ } >+ } >+ >+ if (!store_port_association(port_ev, >+ fde, >+ flags)) { >+ tevent_debug(port_ev->ev, TEVENT_DEBUG_FATAL, >+ "store_port_association failed for fd[%d]\n", >+ fde->fd); >+ return -1; >+ } >+ >+ /* Note we have an association now. */ >+ fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ /* Only if we want to read do we tell the event handler about errors. */ >+ if (fde->flags & TEVENT_FD_READ) { >+ fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ } >+ if (mpx_fde == NULL) { >+ return 0; >+ } >+ /* Set up the multiplex pointer. Does no harm if already multiplexed. */ >+ port_setup_multiplex_fd(port_ev, >+ fde, >+ mpx_fde); >+ >+ mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ /* Only if we want to read do we tell the event handler about errors. */ >+ if (mpx_fde->flags & TEVENT_FD_READ) { >+ mpx_fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ } >+ >+ return 0; >+} >+ >+/* >+ Delete the port association for the given fd_event. >+*/ >+ >+static void port_del_event(struct port_event_context *port_ev, struct tevent_fd *fde) >+{ >+ struct tevent_fd *mpx_fde = NULL; >+ >+ fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ /* >+ * This is a multiplexed fde, we need to remove >+ * both associations. >+ */ >+ mpx_fde = talloc_get_type_abort(fde->additional_data, >+ struct tevent_fd); >+ >+ mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR; >+ mpx_fde->additional_data = NULL; >+ >+ fde->additional_data = NULL; >+ } >+ delete_port_association(port_ev, fde); >+} >+ >+/* >+ Add or remove the port event from the given fd_event >+*/ >+static int port_update_event(struct port_event_context *port_ev, struct tevent_fd *fde) >+{ >+ bool got_error = (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_GOT_ERROR); >+ bool want_read = (fde->flags & TEVENT_FD_READ); >+ bool want_write = (fde->flags & TEVENT_FD_WRITE); >+ struct tevent_fd *mpx_fde = NULL; >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ /* >+ * work out what the multiplexed fde wants. >+ */ >+ mpx_fde = talloc_get_type_abort(fde->additional_data, >+ struct tevent_fd); >+ if (mpx_fde->flags & TEVENT_FD_READ) { >+ want_read = true; >+ } >+ if (mpx_fde->flags & TEVENT_FD_WRITE) { >+ want_write = true; >+ } >+ } >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION) { >+ /* There's already an association. */ >+ if (want_read || (want_write && !got_error)) { >+ return port_add_event(port_ev, fde); >+ } >+ /* >+ * If we want to match the select behavior, we need to remove the port event >+ * when the caller isn't interested in events. >+ */ >+ port_del_event(port_ev, fde); >+ return 0; >+ } >+ >+ /* There's no port event attached to the fde. */ >+ if (want_read || (want_write && !got_error)) { >+ return port_add_event(port_ev, fde); >+ } >+ return 0; >+} >+ >+/* >+ Cope with port_get returning EPOLLHP|EPOLLERR on an association. >+ Return true if there's nothing else to do, false if this event >+ needs further handling. >+*/ >+ >+static bool port_handle_hup_or_err(struct port_event_context *port_ev, >+ struct tevent_fd *fde) >+{ >+ if (fde == NULL) { >+ return true; >+ } >+ >+ fde->additional_flags |= PORT_ADDITIONAL_FD_FLAG_GOT_ERROR; >+ /* >+ * If we only wait for TEVENT_FD_WRITE, we should not tell the >+ * event handler about it, and remove the port association, >+ * as we only report error when waiting for read events, >+ * to match the select() behavior. >+ */ >+ if (!(fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_REPORT_ERROR)) { >+ /* >+ * Do the same as the poll backend and >+ * remove the writable flag. >+ */ >+ fde->flags &= ~TEVENT_FD_WRITE; >+ return true; >+ } >+ /* This has TEVENT_FD_READ set, we're not finished. */ >+ return false; >+} >+ >+/* >+ Event loop handling using Solaris ports. >+*/ >+static int port_event_loop(struct port_event_context *port_ev, struct timeval *tvalp) >+{ >+ int ret; >+#define MAXEVENTS 1 >+ port_event_t events[MAXEVENTS]; >+ uint_t nget = 1; >+ uint_t max_events = MAXEVENTS; >+ uint_t i; >+ int port_errno; >+ struct timespec ts; >+ struct tevent_context *ev = port_ev->ev; >+ >+ if (tvalp) { >+ ts.tv_sec = tvalp->tv_sec; >+ ts.tv_nsec = tvalp->tv_usec * 1000; >+ } >+ >+ if (port_ev->ev->signal_events && >+ tevent_common_check_signal(ev)) { >+ return 0; >+ } >+ >+ /* >+ * Solaris triggers sending the event to the port >+ * at the time the port association is done. Postpone >+ * associating fd's until just before we get the events, >+ * otherwise we can deadlock. >+ */ >+ >+ if (associate_all_events(port_ev) != 0) { >+ return -1; >+ } >+ >+ tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); >+ ret = port_getn(port_ev->port_fd, events, max_events, &nget, &ts); >+ port_errno = errno; >+ tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); >+ >+ if (ret == -1 && port_errno == EINTR && ev->signal_events) { >+ if (tevent_common_check_signal(ev)) { >+ return 0; >+ } >+ } >+ >+ if (ret == -1 && port_errno == ETIME && tvalp) { >+ /* we don't care about a possible delay here */ >+ tevent_common_loop_timer_delay(ev); >+ return 0; >+ } >+ >+ if (ret == -1) { >+ tevent_debug(ev, TEVENT_DEBUG_ERROR, >+ "port_get failed (%s)\n", >+ strerror(errno)); >+ return -1; >+ } >+ >+ for (i = 0; i < nget; i++) { >+ struct tevent_fd *mpx_fde = NULL; >+ struct tevent_fd *fde = NULL; >+ uint16_t flags = 0; >+ struct port_associate_vals *val = talloc_get_type(events[i].portev_user, >+ struct port_associate_vals); >+ if (val == NULL) { >+ tevent_debug(ev, TEVENT_DEBUG_ERROR, >+ "port_getn() gave bad data"); >+ return -1; >+ } >+ >+ /* Mark this event as needing to be re-associated. */ >+ val->associated_event = false; >+ >+ fde = val->fde; >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ /* >+ * Save off the multiplexed event in case we need >+ * to use it to call the handler function. >+ */ >+ mpx_fde = talloc_get_type_abort(fde->additional_data, >+ struct tevent_fd); >+ } >+ >+ if (events[i].portev_events & (POLLHUP|POLLERR)) { >+ bool handled_fde = port_handle_hup_or_err(port_ev, fde); >+ bool handled_mpx = port_handle_hup_or_err(port_ev, mpx_fde); >+ >+ if (handled_fde && handled_mpx) { >+ return port_update_event(port_ev, fde); >+ } >+ >+ if (!handled_mpx) { >+ /* >+ * If the mpx event was the one that needs >+ * further handling, it's the TEVENT_FD_READ >+ * event so switch over and call that handler. >+ */ >+ fde = mpx_fde; >+ mpx_fde = NULL; >+ } >+ flags |= TEVENT_FD_READ; >+ } >+ >+ if (events[i].portev_events & POLLIN) { >+ flags |= TEVENT_FD_READ; >+ } >+ if (events[i].portev_events & POLLOUT) { >+ flags |= TEVENT_FD_WRITE; >+ } >+ >+ if (flags & TEVENT_FD_WRITE) { >+ if (fde->flags & TEVENT_FD_WRITE) { >+ mpx_fde = NULL; >+ } >+ if (mpx_fde && (mpx_fde->flags & TEVENT_FD_WRITE)) { >+ fde = mpx_fde; >+ mpx_fde = NULL; >+ } >+ >+ if (mpx_fde) { >+ /* Ensure we got the right fde. */ >+ if ((flags & fde->flags) == 0) { >+ fde = mpx_fde; >+ mpx_fde = NULL; >+ } >+ } >+ } >+ >+ /* >+ * Make sure we only pass the flags >+ * the handler is expecting. >+ */ >+ flags &= fde->flags; >+ if (flags) { >+ fde->handler(ev, fde, flags, fde->private_data); >+ break; >+ } >+ } >+ >+ return 0; >+} >+ >+ >+/* >+ create a port_event_context structure. >+*/ >+static int port_event_context_init(struct tevent_context *ev) >+{ >+ int ret; >+ struct port_event_context *port_ev; >+ >+ /* >+ * We might be called during tevent_re_initialise() >+ * which means we need to free our old additional_data. >+ */ >+ TALLOC_FREE(ev->additional_data); >+ >+ port_ev = talloc_zero(ev, struct port_event_context); >+ if (!port_ev) { >+ return -1; >+ } >+ port_ev->ev = ev; >+ port_ev->port_fd = -1; >+ port_ev->pid = (pid_t)-1; >+ >+ ret = port_init_ctx(port_ev); >+ if (ret != 0) { >+ talloc_free(port_ev); >+ return ret; >+ } >+ >+ ev->additional_data = port_ev; >+ return 0; >+} >+ >+/* >+ destroy an fd_event >+*/ >+static int port_event_fd_destructor(struct tevent_fd *fde) >+{ >+ struct tevent_context *ev = fde->event_ctx; >+ struct port_event_context *port_ev = NULL; >+ struct tevent_fd *mpx_fde = NULL; >+ int flags = (int)fde->flags; >+ >+ if (ev == NULL) { >+ return tevent_common_fd_destructor(fde); >+ } >+ >+ port_ev = talloc_get_type_abort(ev->additional_data, >+ struct port_event_context); >+ >+ DLIST_REMOVE(ev->fd_events, fde); >+ >+ if (fde->additional_flags & PORT_ADDITIONAL_FD_FLAG_HAS_MPX) { >+ mpx_fde = talloc_get_type_abort(fde->additional_data, >+ struct tevent_fd); >+ >+ fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; >+ mpx_fde->additional_flags &= ~PORT_ADDITIONAL_FD_FLAG_HAS_MPX; >+ >+ fde->additional_data = NULL; >+ mpx_fde->additional_data = NULL; >+ >+ fde->additional_flags &= PORT_ADDITIONAL_FD_FLAG_HAS_ASSOCIATION; >+ } >+ >+ (void)port_check_reopen(port_ev); >+ >+ if (mpx_fde != NULL) { >+ (void)port_update_event(port_ev, mpx_fde); >+ } >+ >+ fde->flags = 0; >+ (void)port_update_event(port_ev, fde); >+ fde->flags = flags; >+ >+ return tevent_common_fd_destructor(fde); >+} >+ >+/* >+ add a fd based event >+ return NULL on failure (memory allocation error) >+*/ >+static struct tevent_fd *port_event_add_fd(struct tevent_context *ev, TALLOC_CTX *mem_ctx, >+ int fd, uint16_t flags, >+ tevent_fd_handler_t handler, >+ void *private_data, >+ const char *handler_name, >+ const char *location) >+{ >+ struct port_event_context *port_ev = >+ talloc_get_type_abort(ev->additional_data, >+ struct port_event_context); >+ struct tevent_fd *fde; >+ >+ fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, >+ handler, private_data, >+ handler_name, location); >+ if (!fde) { >+ return NULL; >+ } >+ >+ talloc_set_destructor(fde, port_event_fd_destructor); >+ >+ if (port_check_reopen(port_ev) != 0) { >+ TALLOC_FREE(fde); >+ return NULL; >+ } >+ >+ if (port_update_event(port_ev, fde) != 0) { >+ TALLOC_FREE(fde); >+ return NULL; >+ } >+ >+ return fde; >+} >+ >+/* >+ set the fd event flags >+*/ >+static void port_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) >+{ >+ struct tevent_context *ev; >+ struct port_event_context *port_ev; >+ >+ if (fde->flags == flags) { >+ return; >+ } >+ >+ ev = fde->event_ctx; >+ port_ev = talloc_get_type_abort(ev->additional_data, >+ struct port_event_context); >+ >+ fde->flags = flags; >+ >+ (void)port_check_reopen(port_ev); >+ (void)port_update_event(port_ev, fde); >+} >+ >+/* >+ do a single event loop using the events defined in ev >+*/ >+static int port_event_loop_once(struct tevent_context *ev, const char *location) >+{ >+ struct port_event_context *port_ev = talloc_get_type(ev->additional_data, >+ struct port_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; >+ } >+ >+ if (port_check_reopen(port_ev) != 0) { >+ errno = EINVAL; >+ return -1; >+ } >+ return port_event_loop(port_ev, &tval); >+} >+ >+static const struct tevent_ops port_event_ops = { >+ .context_init = port_event_context_init, >+ .add_fd = port_event_add_fd, >+ .set_fd_close_fn = tevent_common_fd_set_close_fn, >+ .get_fd_flags = tevent_common_fd_get_flags, >+ .set_fd_flags = port_event_set_fd_flags, >+ .add_timer = tevent_common_add_timer_v2, >+ .schedule_immediate = tevent_common_schedule_immediate, >+ .add_signal = tevent_common_add_signal, >+ .loop_once = port_event_loop_once, >+ .loop_wait = tevent_common_loop_wait, >+}; >+ >+_PRIVATE_ bool tevent_port_init(void) >+{ >+ if (!tevent_register_backend("port", &port_event_ops)) { >+ return false; >+ } >+ tevent_set_default_backend("port"); >+ return true; >+} >diff --git a/lib/tevent/wscript b/lib/tevent/wscript >index a991fed..45f602c 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -89,6 +89,9 @@ def build(bld): > if bld.CONFIG_SET('HAVE_EPOLL'): > SRC += ' tevent_epoll.c' > >+ if bld.CONFIG_SET('HAVE_SOLARIS_PORTS'): >+ SRC += ' tevent_port.c' >+ > if bld.env.standalone_tevent: > bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig' > private_library = False >-- >1.9.1 > > >From 418d93b2f7699d675b525ea15e84e65a77c6e61a Mon Sep 17 00:00:00 2001 >From: Michael Adam <obnox@samba.org> >Date: Fri, 27 Feb 2015 00:27:29 +0100 >Subject: [PATCH 39/55] tevent: version 0.9.23 > >* Add Solaris ports as tevent backend. >* Improvements to the tevent_data tutorial. >* Remove use of the 'staticforward' macro. > >Signed-off-by: Michael Adam <obnox@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Michael Adam <obnox@samba.org> >Autobuild-Date(master): Fri Feb 27 03:48:57 CET 2015 on sn-devel-104 > >(cherry picked from commit 04b8e19e1708c5670d180f5cd86d8ed139e9e5a4) > >The last 3 patches address >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11118 >Add Solaris Ports as a tevent backend > >(cherry picked from commit d0a5a6f4797efb167086d54b47c61c0e89634f15) >--- > lib/tevent/ABI/tevent-0.9.23.sigs | 88 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 89 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.23.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.23.sigs b/lib/tevent/ABI/tevent-0.9.23.sigs >new file mode 100644 >index 0000000..d8b9f4b >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.23.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 45f602c..489ce31 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.22' >+VERSION = '0.9.23' > > blddir = 'bin' > >-- >1.9.1 > > >From 66f4839d57b79865dd46deb2164ce639b08ec4e4 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 2 Mar 2015 16:17:54 -0800 >Subject: [PATCH 40/55] tevent: Ignore unexpected signal events in the same way > the epoll backend does. > >Bug: https://bugzilla.samba.org/show_bug.cgi?id=11118 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: David Disseldorp <ddiss@samba.org> > >Autobuild-User(master): David Disseldorp <ddiss@samba.org> >Autobuild-Date(master): Tue Mar 3 17:33:06 CET 2015 on sn-devel-104 > >(cherry picked from commit 7be3a5f92ddbb378a3c80e455cb7403f7861efa1) >(cherry picked from commit 5db8d198ad7045d6bcb8e41701d045e92405c108) >--- > lib/tevent/tevent_port.c | 12 +++++++++--- > 1 file changed, 9 insertions(+), 3 deletions(-) > >diff --git a/lib/tevent/tevent_port.c b/lib/tevent/tevent_port.c >index 93e94b2..dd4958e 100644 >--- a/lib/tevent/tevent_port.c >+++ b/lib/tevent/tevent_port.c >@@ -483,10 +483,16 @@ static int port_event_loop(struct port_event_context *port_ev, struct timeval *t > port_errno = errno; > tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); > >- if (ret == -1 && port_errno == EINTR && ev->signal_events) { >- if (tevent_common_check_signal(ev)) { >- return 0; >+ if (ret == -1 && port_errno == EINTR) { >+ if (ev->signal_events) { >+ tevent_common_check_signal(ev); > } >+ /* >+ * If no signal handlers we got an unsolicited >+ * signal wakeup. This can happen with epoll >+ * too. Just return and ignore. >+ */ >+ return 0; > } > > if (ret == -1 && port_errno == ETIME && tvalp) { >-- >1.9.1 > > >From f60675018b886529192754a3731217c8fb9b4077 Mon Sep 17 00:00:00 2001 >From: David Disseldorp <ddiss@samba.org> >Date: Tue, 3 Mar 2015 23:58:09 +0100 >Subject: [PATCH 41/55] tevent: version 0.9.24 > >* Ignore unsolicited signal wakeup in tevent_port event loop. > >Signed-off-by: David Disseldorp <ddiss@samba.org> >Reviewed-by: Stefan Metzmacher <metze@samba.org> > >Autobuild-User(master): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(master): Wed Mar 4 08:33:06 CET 2015 on sn-devel-104 > >(cherry picked from commit 89788dd3193633f5e88ff194219ad838dcdfab96) > >Autobuild-User(v4-2-test): Stefan Metzmacher <metze@samba.org> >Autobuild-Date(v4-2-test): Wed Mar 4 15:07:48 CET 2015 on sn-devel-104 > >(cherry picked from commit 1309af4880eb00cf127aa3c1fc7b590c7000a4ec) >--- > lib/tevent/ABI/tevent-0.9.24.sigs | 88 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 89 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.24.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.24.sigs b/lib/tevent/ABI/tevent-0.9.24.sigs >new file mode 100644 >index 0000000..d8b9f4b >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.24.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 489ce31..0da8232 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.23' >+VERSION = '0.9.24' > > blddir = 'bin' > >-- >1.9.1 > > >From a7eaa1bb3214313c3d9b5611ef80fd9ef4852baf Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Tue, 31 Mar 2015 21:15:53 +0200 >Subject: [PATCH 42/55] tevent: Fix CID 1035381 Unchecked return value > >Signed-off-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 6bcc037b5b636e88a914f1d39a95eb6eb72937e0) >--- > lib/tevent/testsuite.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > >diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c >index 34d13bb..e9d1ef4 100644 >--- a/lib/tevent/testsuite.c >+++ b/lib/tevent/testsuite.c >@@ -121,6 +121,7 @@ static bool test_event_context(struct torture_context *test, > #endif > int finished=0; > struct timeval t; >+ int ret; > > ev_ctx = tevent_context_init_byname(test, backend); > if (ev_ctx == NULL) { >@@ -135,7 +136,8 @@ static bool test_event_context(struct torture_context *test, > fde_count = 0; > > /* create a pipe */ >- pipe(fd); >+ ret = pipe(fd); >+ torture_assert_int_equal(test, ret, 0, "pipe failed"); > > fde_read = tevent_add_fd(ev_ctx, ev_ctx, fd[0], TEVENT_FD_READ, > fde_handler_read, fd); >-- >1.9.1 > > >From b5b8486189556294a0f48c727244fe087734902d Mon Sep 17 00:00:00 2001 >From: Gordon Ross <gordon.w.ross@gmail.com> >Date: Wed, 29 Apr 2015 11:34:10 -0700 >Subject: [PATCH 43/55] lib: tevent: Fix compile error in Solaris ports > backend. > >Signed-off-by: Gordon Ross <gordon.w.ross@gmail.com> >Reviewed-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit a7d41e94603d789bb461b84380a8fba3f837bc4f) >--- > lib/tevent/tevent_port.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_port.c b/lib/tevent/tevent_port.c >index dd4958e..5b487d7 100644 >--- a/lib/tevent/tevent_port.c >+++ b/lib/tevent/tevent_port.c >@@ -174,10 +174,11 @@ static int associate_all_events(struct port_event_context *port_ev) > struct port_associate_vals *val; > > for (val = port_ev->po_vals; val; val = val->next) { >+ int ret; > if (val->associated_event) { > continue; > } >- int ret = port_associate(port_ev->port_fd, >+ ret = port_associate(port_ev->port_fd, > PORT_SOURCE_FD, > (uintptr_t)val->fde->fd, > val->events, >-- >1.9.1 > > >From 179a297fce0369ca62884d5ce77b7a6badcfcc82 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Mon, 18 May 2015 13:25:33 +0200 >Subject: [PATCH 44/55] tevent: add a note to tevent_add_fd() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11141 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 33ca0179ac091c8bb1c2b3fa7999cc5047d09a80) >--- > lib/tevent/tevent.h | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h >index c54cbe2..6861ffb 100644 >--- a/lib/tevent/tevent.h >+++ b/lib/tevent/tevent.h >@@ -176,6 +176,11 @@ void tevent_set_default_backend(const char *backend); > * > * @note To cancel the monitoring of a file descriptor, call talloc_free() > * on the object returned by this function. >+ * >+ * @note The caller should avoid closing the file descriptor before >+ * calling talloc_free()! Otherwise the behaviour is undefined which >+ * might result in crashes. See https://bugzilla.samba.org/show_bug.cgi?id=11141 >+ * for an example. > */ > struct tevent_fd *tevent_add_fd(struct tevent_context *ev, > TALLOC_CTX *mem_ctx, >-- >1.9.1 > > >From 4966dce08e9bee91000c046197d55a96f038c3e0 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Tue, 2 Jun 2015 12:18:22 +0200 >Subject: [PATCH 45/55] tevent: fix access after free in > tevent_common_check_signal() >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >This was reported by Pavel BĂ…ezina <pbrezina@redhat.com>: > > We found a crash in SSSD when a tevent signal is freed in its handler, tevent > than crashes when it access siginfo. > > sig_info is freed in signal destructor: > > > #ifdef SA_SIGINFO > > if (se->sa_flags & SA_SIGINFO) { > > if (sig_state->sig_info[se->signum]) { > > talloc_free(sig_state->sig_info[se->signum]); > > sig_state->sig_info[se->signum] = NULL; > > } > > } > > #endif > > (gdb) bt > #0 0x00007f5d4d86cc74 in tevent_signal_destructor (se=0x7f5d5370f920) at > ../tevent_signal.c:213 > #1 0x00007f5d4d65f233 in _talloc_free_internal () from /lib64/libtalloc.so.2 > #2 0x00007f5d4d6593a3 in _talloc_free () from /lib64/libtalloc.so.2 > #3 0x00007f5d4342f3d4 in proxy_child_init_done (subreq=0x7f5d5370f600) at > src/providers/proxy/proxy_auth.c:436 > #4 0x00007f5d4d86b0c2 in _tevent_req_error (req=req@entry=0x7f5d5370f600, > error=error@entry=5, location=location@entry=0x7f5d43433010 > "src/providers/proxy/proxy_auth.c:356") > at ../tevent_req.c:167 > #5 0x00007f5d4342ef5e in pc_init_sig_handler (ev=<optimized out>, > sige=<optimized out>, signum=<optimized out>, count=<optimized out>, > __siginfo=<optimized out>, pvt=<optimized out>) > at src/providers/proxy/proxy_auth.c:356 > #6 0x00007f5d4d86d48c in tevent_common_check_signal (ev=0x7f5d536de670) at > ../tevent_signal.c:428 > #7 0x00007f5d4d86f28c in epoll_event_loop (tvalp=0x7fff7b568490, > epoll_ev=0x7f5d536de8b0) at ../tevent_epoll.c:647 > #8 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at > ../tevent_epoll.c:926 > #9 0x00007f5d4d86d7d7 in std_event_loop_once (ev=0x7f5d536de670, > location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent_standard.c:114 > #10 0x00007f5d4d869fbd in _tevent_loop_once (ev=ev@entry=0x7f5d536de670, > location=location@entry=0x7f5d50faedc3 "src/util/server.c:668") at > ../tevent.c:530 > #11 0x00007f5d4d86a15b in tevent_common_loop_wait (ev=0x7f5d536de670, > location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent.c:634 > #12 0x00007f5d4d86d777 in std_event_loop_wait (ev=0x7f5d536de670, > location=0x7f5d50faedc3 "src/util/server.c:668") at ../tevent_standard.c:140 > #13 0x00007f5d50f96863 in server_loop (main_ctx=0x7f5d536dfac0) at > src/util/server.c:668 > #14 0x00007f5d5180aa42 in main (argc=8, argv=<optimized out>) at > src/providers/data_provider_be.c:2909 > > But then it is accessed again in tevent_common_check_signal: > > > #ifdef SA_SIGINFO > > if (clear_processed_siginfo) { > > uint32_t j; > > for (j=0;j<count;j++) { > > uint32_t ofs = (counter.seen + j) > > % TEVENT_SA_INFO_QUEUE_COUNT; > > memset((void*)&sig_state->sig_info[i][ofs], > > '\0', > > sizeof(siginfo_t)); > > } > > } > > #endif > > (gdb) bt > #0 0x00007fd7ba400505 in memset (__len=<optimized out>, __ch=<optimized out>, > __dest=<optimized out>) at /usr/include/bits/string3.h:84 > #1 tevent_common_check_signal (ev=0x7fd7bfddf670) at ../tevent_signal.c:459 > #2 0x00007fd7ba40228c in epoll_event_loop (tvalp=0x7fff85536430, > epoll_ev=0x7fd7bfddf8b0) at ../tevent_epoll.c:647 > #3 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at > ../tevent_epoll.c:926 > #4 0x00007fd7ba4007d7 in std_event_loop_once (ev=0x7fd7bfddf670, > location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent_standard.c:114 > #5 0x00007fd7ba3fcfbd in _tevent_loop_once (ev=ev@entry=0x7fd7bfddf670, > location=location@entry=0x7fd7bdb417c3 "src/util/server.c:668") at > ../tevent.c:530 > #6 0x00007fd7ba3fd15b in tevent_common_loop_wait (ev=0x7fd7bfddf670, > location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent.c:634 > #7 0x00007fd7ba400777 in std_event_loop_wait (ev=0x7fd7bfddf670, > location=0x7fd7bdb417c3 "src/util/server.c:668") at ../tevent_standard.c:140 > #8 0x00007fd7bdb29343 in server_loop (main_ctx=0x7fd7bfde0ac0) at > src/util/server.c:668 > #9 0x00007fd7be39ca42 in main (argc=8, argv=<optimized out>) at > src/providers/data_provider_be.c:2909 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11308 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Tue Jun 2 21:02:11 CEST 2015 on sn-devel-104 > >(cherry picked from commit 9d797ffb27bf4be100c900b0373f62b029679de3) >--- > lib/tevent/tevent_signal.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/lib/tevent/tevent_signal.c b/lib/tevent/tevent_signal.c >index b54da2e..924dc05 100644 >--- a/lib/tevent/tevent_signal.c >+++ b/lib/tevent/tevent_signal.c >@@ -457,7 +457,7 @@ int tevent_common_check_signal(struct tevent_context *ev) > } > > #ifdef SA_SIGINFO >- if (clear_processed_siginfo) { >+ if (clear_processed_siginfo && sig_state->sig_info[i] != NULL) { > uint32_t j; > for (j=0;j<count;j++) { > uint32_t ofs = (counter.seen + j) >-- >1.9.1 > > >From 056b13b0a87068491ee3c8ebafc79b0f21941241 Mon Sep 17 00:00:00 2001 >From: Petr Viktorin <pviktori@redhat.com> >Date: Thu, 4 Dec 2014 12:44:56 +0100 >Subject: [PATCH 46/55] pytevent: Better error and reference handling > >py_backend_list: >- Handle cases of PyString_FromString or PyList_Append failing. >- Properly decrease the reference count of the returned strings. > >py_register_backend: >- Decref "name" after use > >Signed-off-by: Petr Viktorin <pviktori@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jelmer Vernooij <jelmer@samba.org> >(cherry picked from commit f5838df58ea36e64cd0295b595df9cbd10d8c757) >--- > lib/tevent/pytevent.c | 31 +++++++++++++++++++++++++------ > 1 file changed, 25 insertions(+), 6 deletions(-) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index 870f5aa..5b8c535 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -177,14 +177,18 @@ static PyObject *py_register_backend(PyObject *self, PyObject *args) > > if (!PyString_Check(name)) { > PyErr_SetNone(PyExc_TypeError); >+ Py_DECREF(name); > return NULL; > } > > if (!tevent_register_backend(PyString_AsString(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ > PyErr_SetNone(PyExc_RuntimeError); >+ Py_DECREF(name); > return NULL; > } > >+ Py_DECREF(name); >+ > Py_RETURN_NONE; > } > >@@ -684,9 +688,10 @@ static PyObject *py_set_default_backend(PyObject *self, PyObject *args) > > static PyObject *py_backend_list(PyObject *self) > { >- PyObject *ret; >- int i; >- const char **backends; >+ PyObject *ret = NULL; >+ PyObject *string = NULL; >+ int i, result; >+ const char **backends = NULL; > > ret = PyList_New(0); > if (ret == NULL) { >@@ -696,16 +701,30 @@ static PyObject *py_backend_list(PyObject *self) > backends = tevent_backend_list(NULL); > if (backends == NULL) { > PyErr_SetNone(PyExc_RuntimeError); >- Py_DECREF(ret); >- return NULL; >+ goto err; > } > for (i = 0; backends[i]; i++) { >- PyList_Append(ret, PyString_FromString(backends[i])); >+ string = PyString_FromString(backends[i]); >+ if (!string) { >+ goto err; >+ } >+ result = PyList_Append(ret, string); >+ if (result) { >+ goto err; >+ } >+ Py_DECREF(string); >+ string = NULL; > } > > talloc_free(backends); > > return ret; >+ >+err: >+ Py_XDECREF(ret); >+ Py_XDECREF(string); >+ talloc_free(backends); >+ return NULL; > } > > static PyMethodDef tevent_methods[] = { >-- >1.9.1 > > >From 189aef83bb15047bf8cd7760edaae53e0cf62299 Mon Sep 17 00:00:00 2001 >From: Petr Viktorin <pviktori@redhat.com> >Date: Fri, 22 May 2015 13:29:11 +0200 >Subject: [PATCH 47/55] pytevent: Define missing TeventFd_Type object > >The type objects for Fd was declared but never defined, >resulting in segfaults when it was used. >Define it. > >Signed-off-by: Petr Viktorin <pviktori@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jelmer Vernooij <jelmer@samba.org> >(cherry picked from commit 4399dc582fa06b04e1cec1d3aa59cd332e4b5ba2) >--- > lib/tevent/pytevent.c | 13 +++++++++++++ > 1 file changed, 13 insertions(+) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index 5b8c535..ef891d4 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -415,6 +415,19 @@ static void py_fd_handler(struct tevent_context *ev, > Py_XDECREF(ret); > } > >+static void py_tevent_fp_dealloc(TeventFd_Object *self) >+{ >+ talloc_free(self->fd); >+ PyObject_Del(self); >+} >+ >+static PyTypeObject TeventFd_Type = { >+ .tp_name = "tevent.Fd", >+ .tp_basicsize = sizeof(TeventFd_Object), >+ .tp_dealloc = (destructor)py_tevent_fp_dealloc, >+ .tp_flags = Py_TPFLAGS_DEFAULT, >+}; >+ > static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject *args) > { > int fd, flags; >-- >1.9.1 > > >From e2af9e15dfa9af63b066e0acac40ea528e6d0ed4 Mon Sep 17 00:00:00 2001 >From: Petr Viktorin <pviktori@redhat.com> >Date: Tue, 26 May 2015 13:25:12 +0200 >Subject: [PATCH 48/55] pytalloc: Improve timer wrapper, and test it > >Using Context.add_timer resulted in crashes due to missing type object >and bad reference handling. >Add a TeventTimer_Type struct, and introduce a clear ownership/lifetime model. > >Add a "add_timer_offset" to allow adding timers from Python. (add_timer >requires passing struct timeval as a Python integer, which can't really >be done portably). > >Add tests. > >Signed-off-by: Petr Viktorin <pviktori@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jelmer Vernooij <jelmer@samba.org> >(similar to commit 560576217f11b132f9c32de6e41c623dbc152137) >(We don't run the tests in the backport) >--- > lib/tevent/bindings.py | 52 ++++++++++++++++- > lib/tevent/pytevent.c | 147 +++++++++++++++++++++++++++++++++++++++++++------ > 2 files changed, 181 insertions(+), 18 deletions(-) > >diff --git a/lib/tevent/bindings.py b/lib/tevent/bindings.py >index 1060caf..55aafbb 100644 >--- a/lib/tevent/bindings.py >+++ b/lib/tevent/bindings.py >@@ -22,8 +22,10 @@ > # License along with this library; if not, see <http://www.gnu.org/licenses/>. > > import signal >+from unittest import TestCase, TestProgram >+import gc >+ > import _tevent >-from unittest import TestCase > > class BackendListTests(TestCase): > >@@ -60,3 +62,51 @@ class ContextTests(TestCase): > def test_add_signal(self): > sig = self.ctx.add_signal(signal.SIGINT, 0, lambda callback: None) > self.assertTrue(isinstance(sig, _tevent.Signal)) >+ >+ def test_timer(self): >+ """Test a timer is can be scheduled""" >+ collecting_list = [] >+ # time "0" has already passed, callback will be scheduled immediately >+ timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) >+ self.assertTrue(timer.active) >+ self.assertEqual(collecting_list, []) >+ self.ctx.loop_once() >+ self.assertFalse(timer.active) >+ self.assertEqual(collecting_list, [True]) >+ >+ def test_timer_deallocate_timer(self): >+ """Test timer is scheduled even if reference to it isn't held""" >+ collecting_list = [] >+ def callback(t): >+ collecting_list.append(True) >+ timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) >+ gc.collect() >+ self.assertEqual(collecting_list, []) >+ self.ctx.loop_once() >+ self.assertEqual(collecting_list, [True]) >+ >+ def test_timer_deallocate_context(self): >+ """Test timer is unscheduled when context is freed""" >+ collecting_list = [] >+ def callback(t): >+ collecting_list.append(True) >+ timer = self.ctx.add_timer(0, lambda t: collecting_list.append(True)) >+ self.assertTrue(timer.active) >+ del self.ctx >+ gc.collect() >+ self.assertEqual(collecting_list, []) >+ self.assertFalse(timer.active) >+ >+ def test_timer_offset(self): >+ """Test scheduling timer with an offset""" >+ collecting_list = [] >+ self.ctx.add_timer_offset(0.2, lambda t: collecting_list.append(2)) >+ self.ctx.add_timer_offset(0.1, lambda t: collecting_list.append(1)) >+ self.assertEqual(collecting_list, []) >+ self.ctx.loop_once() >+ self.assertEqual(collecting_list, [1]) >+ self.ctx.loop_once() >+ self.assertEqual(collecting_list, [1, 2]) >+ >+if __name__ == '__main__': >+ TestProgram() >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index ef891d4..a25dc93 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -50,6 +50,7 @@ typedef struct { > typedef struct { > PyObject_HEAD > struct tevent_timer *timer; >+ PyObject *callback; > } TeventTimer_Object; > > typedef struct { >@@ -372,38 +373,148 @@ static void py_timer_handler(struct tevent_context *ev, > struct timeval current_time, > void *private_data) > { >- PyObject *callback = private_data, *ret; >- ret = PyObject_CallFunction(callback, "l", te); >+ TeventTimer_Object *self = private_data; >+ PyObject *ret; >+ >+ ret = PyObject_CallFunction(self->callback, "l", te); >+ if (ret == NULL) { >+ /* No Python stack to propagate exception to; just print traceback */ >+ PyErr_PrintEx(0); >+ } > Py_XDECREF(ret); > } > >-static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args) >+static void py_tevent_timer_dealloc(TeventTimer_Object *self) > { >- TeventTimer_Object *ret; >- struct timeval next_event; >- struct tevent_timer *timer; >- PyObject *handler; >- if (!PyArg_ParseTuple(args, "lO", &next_event, &handler)) >- return NULL; >- >- timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler, >- handler); >- if (timer == NULL) { >- PyErr_SetNone(PyExc_RuntimeError); >- return NULL; >+ if (self->timer) { >+ talloc_free(self->timer); > } >+ Py_DECREF(self->callback); >+ PyObject_Del(self); >+} >+ >+static int py_tevent_timer_traverse(TeventTimer_Object *self, visitproc visit, void *arg) >+{ >+ Py_VISIT(self->callback); >+ return 0; >+} >+ >+static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self) { >+ return PyBool_FromLong(self->timer != NULL); >+} >+ >+struct PyGetSetDef py_tevent_timer_getset[] = { >+ { >+ .name = "active", >+ .get = (getter)py_tevent_timer_get_active, >+ .doc = "true if the timer is scheduled to run", >+ }, >+ {NULL}, >+}; >+ >+static PyTypeObject TeventTimer_Type = { >+ .tp_name = "tevent.Timer", >+ .tp_basicsize = sizeof(TeventTimer_Object), >+ .tp_dealloc = (destructor)py_tevent_timer_dealloc, >+ .tp_traverse = (traverseproc)py_tevent_timer_traverse, >+ .tp_getset = py_tevent_timer_getset, >+ .tp_flags = Py_TPFLAGS_DEFAULT, >+}; >+ >+static int timer_destructor(void* ptr) >+{ >+ TeventTimer_Object *obj = *(TeventTimer_Object **)ptr; >+ obj->timer = NULL; >+ Py_DECREF(obj); >+ return 0; >+} >+ >+static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self, >+ struct timeval next_event, >+ PyObject *callback) >+{ >+ /* Ownership notes: >+ * >+ * There are 5 pieces in play; two tevent contexts and 3 Python objects: >+ * - The tevent timer >+ * - The tevent context >+ * - The Python context -- "self" >+ * - The Python timer (TeventTimer_Object) -- "ret" >+ * - The Python callback function -- "callback" >+ * >+ * We only use the Python context for getting the tevent context, >+ * afterwards it can be destroyed. >+ * >+ * The tevent context owns the tevent timer. >+ * >+ * The tevent timer holds a reference to the Python timer, so the Python >+ * timer must always outlive the tevent timer. >+ * The Python timer has a pointer to the tevent timer; a destructor is >+ * used to set this to NULL when the tevent timer is deallocated. >+ * >+ * The tevent timer can be deallocated in these cases: >+ * 1) when the context is destroyed >+ * 2) after the event fires >+ * Posssibly, API might be added to cancel (free the tevent timer). >+ * >+ * The Python timer holds a reference to the callback. >+ */ >+ TeventTimer_Object *ret; >+ TeventTimer_Object **tmp_context; > > ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type); > if (ret == NULL) { > PyErr_NoMemory(); >- talloc_free(timer); > return NULL; > } >- ret->timer = timer; >+ Py_INCREF(callback); >+ ret->callback = callback; >+ ret->timer = tevent_add_timer(self->ev, NULL, next_event, py_timer_handler, >+ ret); >+ if (ret->timer == NULL) { >+ Py_DECREF(ret); >+ PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); >+ return NULL; >+ } >+ tmp_context = talloc(ret->timer, TeventTimer_Object*); >+ if (tmp_context == NULL) { >+ talloc_free(ret->timer); >+ Py_DECREF(ret); >+ PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); >+ return NULL; >+ } >+ Py_INCREF(ret); >+ *tmp_context = ret; >+ talloc_set_destructor(tmp_context, timer_destructor); > > return (PyObject *)ret; > } > >+static PyObject *py_tevent_context_add_timer(TeventContext_Object *self, PyObject *args) >+{ >+ struct timeval next_event; >+ PyObject *callback; >+ if (!PyArg_ParseTuple(args, "lO", &next_event, &callback)) >+ return NULL; >+ >+ return py_tevent_context_add_timer_internal(self, next_event, callback); >+} >+ >+static PyObject *py_tevent_context_add_timer_offset(TeventContext_Object *self, PyObject *args) >+{ >+ struct timeval next_event; >+ double offset; >+ int seconds; >+ PyObject *callback; >+ if (!PyArg_ParseTuple(args, "dO", &offset, &callback)) >+ return NULL; >+ >+ seconds = offset; >+ offset -= seconds; >+ next_event = tevent_timeval_current_ofs(seconds, (int)(offset*1000000)); >+ return py_tevent_context_add_timer_internal(self, next_event, callback); >+} >+ > static void py_fd_handler(struct tevent_context *ev, > struct tevent_fd *fde, > uint16_t flags, >@@ -479,6 +590,8 @@ static PyMethodDef py_tevent_context_methods[] = { > METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" }, > { "add_timer", (PyCFunction)py_tevent_context_add_timer, > METH_VARARGS, "S.add_timer(next_event, handler) -> timer" }, >+ { "add_timer_offset", (PyCFunction)py_tevent_context_add_timer_offset, >+ METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, > { "add_fd", (PyCFunction)py_tevent_context_add_fd, > METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, > #ifdef TEVENT_DEPRECATED >-- >1.9.1 > > >From e483e7a6e874727e1595c9d2b949a7efb8e6ab0b Mon Sep 17 00:00:00 2001 >From: Petr Viktorin <pviktori@redhat.com> >Date: Fri, 22 May 2015 11:47:56 +0200 >Subject: [PATCH 49/55] pytevent: Port to Python 3 > >- Use PyStr (String on py2, Unicode on py3) for text strings >- Use PyLong instead of PyInt on Python 3 >- Use new module initialization > >Signed-off-by: Petr Viktorin <pviktori@redhat.com> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >Reviewed-by: Jelmer Vernooij <jelmer@samba.org> >(cherry picked from commit 8dbdd27526c4d5358bc2614e90f9aca36f41ed1a) >--- > lib/tevent/pytevent.c | 70 +++++++++++++++++++++++++++++++++++++++++---------- > 1 file changed, 57 insertions(+), 13 deletions(-) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index a25dc93..160ea1a 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -25,6 +25,17 @@ > #include <Python.h> > #include <tevent.h> > >+#if PY_MAJOR_VERSION >= 3 >+#define PyStr_Check PyUnicode_Check >+#define PyStr_FromString PyUnicode_FromString >+#define PyStr_AsUTF8 PyUnicode_AsUTF8 >+#define PyInt_FromLong PyLong_FromLong >+#else >+#define PyStr_Check PyString_Check >+#define PyStr_FromString PyString_FromString >+#define PyStr_AsUTF8 PyString_AsString >+#endif >+ > void init_tevent(void); > > typedef struct { >@@ -176,13 +187,13 @@ static PyObject *py_register_backend(PyObject *self, PyObject *args) > return NULL; > } > >- if (!PyString_Check(name)) { >+ if (!PyStr_Check(name)) { > PyErr_SetNone(PyExc_TypeError); > Py_DECREF(name); > return NULL; > } > >- if (!tevent_register_backend(PyString_AsString(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ >+ if (!tevent_register_backend(PyStr_AsUTF8(name), &py_tevent_ops)) { /* FIXME: What to do with backend */ > PyErr_SetNone(PyExc_RuntimeError); > Py_DECREF(name); > return NULL; >@@ -830,7 +841,7 @@ static PyObject *py_backend_list(PyObject *self) > goto err; > } > for (i = 0; backends[i]; i++) { >- string = PyString_FromString(backends[i]); >+ string = PyStr_FromString(backends[i]); > if (!string) { > goto err; > } >@@ -863,31 +874,48 @@ static PyMethodDef tevent_methods[] = { > { NULL }, > }; > >-void init_tevent(void) >+#define MODULE_DOC PyDoc_STR("Python wrapping of talloc-maintained objects.") >+ >+#if PY_MAJOR_VERSION >= 3 >+static struct PyModuleDef moduledef = { >+ PyModuleDef_HEAD_INIT, >+ .m_name = "_tevent", >+ .m_doc = MODULE_DOC, >+ .m_size = -1, >+ .m_methods = tevent_methods, >+}; >+#endif >+ >+PyObject * module_init(void); >+PyObject * module_init(void) > { > PyObject *m; > > if (PyType_Ready(&TeventContext_Type) < 0) >- return; >+ return NULL; > > if (PyType_Ready(&TeventQueue_Type) < 0) >- return; >+ return NULL; > > if (PyType_Ready(&TeventReq_Type) < 0) >- return; >+ return NULL; > > if (PyType_Ready(&TeventSignal_Type) < 0) >- return; >+ return NULL; > > if (PyType_Ready(&TeventTimer_Type) < 0) >- return; >+ return NULL; > > if (PyType_Ready(&TeventFd_Type) < 0) >- return; >+ return NULL; > >- m = Py_InitModule3("_tevent", tevent_methods, "Tevent integration for twisted."); >+#if PY_MAJOR_VERSION >= 3 >+ m = PyModule_Create(&moduledef); >+#else >+ m = Py_InitModule3("_tevent", tevent_methods, MODULE_DOC); >+#endif > if (m == NULL) >- return; >+ return NULL; > > Py_INCREF(&TeventContext_Type); > PyModule_AddObject(m, "Context", (PyObject *)&TeventContext_Type); >@@ -907,5 +935,21 @@ void init_tevent(void) > Py_INCREF(&TeventFd_Type); > PyModule_AddObject(m, "Fd", (PyObject *)&TeventFd_Type); > >- PyModule_AddObject(m, "__version__", PyString_FromString(PACKAGE_VERSION)); >+ PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION); >+ >+ return m; >+} >+ >+#if PY_MAJOR_VERSION >= 3 >+PyMODINIT_FUNC PyInit__tevent(void); >+PyMODINIT_FUNC PyInit__tevent(void) >+{ >+ return module_init(); >+} >+#else >+void init_tevent(void); >+void init_tevent(void) >+{ >+ module_init(); > } >+#endif >-- >1.9.1 > > >From b850c4ea135217700646eb5ad0583b90b62c607f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Sat, 30 May 2015 01:42:08 +0200 >Subject: [PATCH 50/55] tevent/testsuite: make sure we cleanup tevent_fd > structures in the correct order > >First we need to remove the tevent_fd structures without >tevent_fd_set_auto_close(). Closing the fd needs to be the last >thing... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 88971d4870a197f656ef912911ca1e4ff5b56749) >--- > lib/tevent/testsuite.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/tevent/testsuite.c b/lib/tevent/testsuite.c >index e9d1ef4..c63c878 100644 >--- a/lib/tevent/testsuite.c >+++ b/lib/tevent/testsuite.c >@@ -177,10 +177,10 @@ static bool test_event_context(struct torture_context *test, > } > } > >- talloc_free(fde_read); >- talloc_free(fde_write); > talloc_free(fde_read_1); > talloc_free(fde_write_1); >+ talloc_free(fde_read); >+ talloc_free(fde_write); > > while (alarm_count < fde_count+1) { > if (tevent_loop_once(ev_ctx) == -1) { >-- >1.9.1 > > >From 421896dbb7c063edbbcfa2d16af0b9f65e919321 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 28 May 2015 09:32:26 +0200 >Subject: [PATCH 51/55] tevent.h: propose tstream_ versions of > read_packet_send/recv and writev_send/recv > >The functions operating on the raw file descriptor are for advanced callers, >which take extra care and avoid the problems of >https://bugzilla.samba.org/show_bug.cgi?id=11141. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11316 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Volker Lendecke <vl@samba.org> >Reviewed-by: Jeremy Allison <jra@samba.org> >(cherry picked from commit 44584f810720602201a9afaaa087eeb83579eff5) >--- > lib/tevent/tevent.h | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/lib/tevent/tevent.h b/lib/tevent/tevent.h >index 6861ffb..b6c39d1 100644 >--- a/lib/tevent/tevent.h >+++ b/lib/tevent/tevent.h >@@ -616,8 +616,8 @@ void tevent_get_trace_callback(struct tevent_context *ev, > * file descriptor (tevent_add_fd) and timer (tevent_add_timed) events > * are considered too low-level to be used in larger computations. To > * read and write from and to sockets, Samba provides two calls on top >- * of tevent_add_fd: read_packet_send/recv and writev_send/recv. These >- * requests are much easier to compose than the low-level event >+ * of tevent_add_fd: tstream_read_packet_send/recv and tstream_writev_send/recv. >+ * These requests are much easier to compose than the low-level event > * handlers called from tevent_add_fd. > * > * A lot of the simplicity tevent_req has brought to the notoriously >-- >1.9.1 > > >From 465849f686af91171dd4f7c1eee664bc5c791538 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 11 Jun 2015 09:49:18 +0200 >Subject: [PATCH 52/55] pytevent: remove dead code TEVENT_DEPRECATED is never > defined > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 1a8a5ba0d51f9c2c9e84a3400e05327e7059156b) >--- > lib/tevent/pytevent.c | 48 ------------------------------------------------ > 1 file changed, 48 deletions(-) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index 160ea1a..02211ed 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -295,38 +295,6 @@ static PyObject *py_tevent_context_loop_once(TeventContext_Object *self) > Py_RETURN_NONE; > } > >-#ifdef TEVENT_DEPRECATED >-static bool py_tevent_finished(PyObject *callback) >-{ >- PyObject *py_ret; >- bool ret; >- >- py_ret = PyObject_CallFunction(callback, ""); >- if (py_ret == NULL) >- return true; >- ret = PyObject_IsTrue(py_ret); >- Py_DECREF(py_ret); >- return ret; >-} >- >-static PyObject *py_tevent_context_loop_until(TeventContext_Object *self, PyObject *args) >-{ >- PyObject *callback; >- if (!PyArg_ParseTuple(args, "O", &callback)) >- return NULL; >- >- if (tevent_loop_until(self->ev, py_tevent_finished, callback) != 0) { >- PyErr_SetNone(PyExc_RuntimeError); >- return NULL; >- } >- >- if (PyErr_Occurred()) >- return NULL; >- >- Py_RETURN_NONE; >-} >-#endif >- > static void py_tevent_signal_handler(struct tevent_context *ev, > struct tevent_signal *se, > int signum, >@@ -576,14 +544,6 @@ static PyObject *py_tevent_context_add_fd(TeventContext_Object *self, PyObject * > return (PyObject *)ret; > } > >-#ifdef TEVENT_DEPRECATED >-static PyObject *py_tevent_context_set_allow_nesting(TeventContext_Object *self) >-{ >- tevent_loop_allow_nesting(self->ev); >- Py_RETURN_NONE; >-} >-#endif >- > static PyMethodDef py_tevent_context_methods[] = { > { "reinitialise", (PyCFunction)py_tevent_context_reinitialise, METH_NOARGS, > "S.reinitialise()" }, >@@ -593,10 +553,6 @@ static PyMethodDef py_tevent_context_methods[] = { > METH_NOARGS, "S.loop_wait()" }, > { "loop_once", (PyCFunction)py_tevent_context_loop_once, > METH_NOARGS, "S.loop_once()" }, >-#ifdef TEVENT_DEPRECATED >- { "loop_until", (PyCFunction)py_tevent_context_loop_until, >- METH_VARARGS, "S.loop_until(callback)" }, >-#endif > { "add_signal", (PyCFunction)py_tevent_context_add_signal, > METH_VARARGS, "S.add_signal(signum, sa_flags, handler) -> signal" }, > { "add_timer", (PyCFunction)py_tevent_context_add_timer, >@@ -605,10 +561,6 @@ static PyMethodDef py_tevent_context_methods[] = { > METH_VARARGS, "S.add_timer(offset_seconds, handler) -> timer" }, > { "add_fd", (PyCFunction)py_tevent_context_add_fd, > METH_VARARGS, "S.add_fd(fd, flags, handler) -> fd" }, >-#ifdef TEVENT_DEPRECATED >- { "allow_nesting", (PyCFunction)py_tevent_context_set_allow_nesting, >- METH_NOARGS, "Whether to allow nested tevent loops." }, >-#endif > { NULL }, > }; > >-- >1.9.1 > > >From 11a51a615ab783b3239076e104f21f267173fc87 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 11 Jun 2015 09:50:35 +0200 >Subject: [PATCH 53/55] pytevent: remove const warnings using discard_const_p() > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit fb04f0f4190005ff21817b79d02897af23ddc7ee) >--- > lib/tevent/pytevent.c | 36 +++++++++++++++++++++++------------- > 1 file changed, 23 insertions(+), 13 deletions(-) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index 02211ed..a22bf26 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -23,6 +23,7 @@ > */ > > #include <Python.h> >+#include "replace.h" > #include <tevent.h> > > #if PY_MAJOR_VERSION >= 3 >@@ -230,7 +231,7 @@ static void py_queue_trigger(struct tevent_req *req, void *private_data) > { > PyObject *callback = private_data, *ret; > >- ret = PyObject_CallFunction(callback, ""); >+ ret = PyObject_CallFunction(callback, discard_const_p(char, "")); > Py_XDECREF(ret); > } > >@@ -304,7 +305,7 @@ static void py_tevent_signal_handler(struct tevent_context *ev, > { > PyObject *callback = (PyObject *)private_data, *ret; > >- ret = PyObject_CallFunction(callback, "ii", signum, count); >+ ret = PyObject_CallFunction(callback, discard_const_p(char, "ii"), signum, count); > Py_XDECREF(ret); > } > >@@ -355,7 +356,7 @@ static void py_timer_handler(struct tevent_context *ev, > TeventTimer_Object *self = private_data; > PyObject *ret; > >- ret = PyObject_CallFunction(self->callback, "l", te); >+ ret = PyObject_CallFunction(self->callback, discard_const_p(char, "l"), te); > if (ret == NULL) { > /* No Python stack to propagate exception to; just print traceback */ > PyErr_PrintEx(0); >@@ -384,9 +385,9 @@ static PyObject* py_tevent_timer_get_active(TeventTimer_Object *self) { > > struct PyGetSetDef py_tevent_timer_getset[] = { > { >- .name = "active", >+ .name = discard_const_p(char, "active"), > .get = (getter)py_tevent_timer_get_active, >- .doc = "true if the timer is scheduled to run", >+ .doc = discard_const_p(char, "true if the timer is scheduled to run"), > }, > {NULL}, > }; >@@ -501,7 +502,7 @@ static void py_fd_handler(struct tevent_context *ev, > { > PyObject *callback = private_data, *ret; > >- ret = PyObject_CallFunction(callback, "i", flags); >+ ret = PyObject_CallFunction(callback, discard_const_p(char, "i"), flags); > Py_XDECREF(ret); > } > >@@ -595,8 +596,11 @@ static PyObject *py_tevent_req_is_in_progress(PyObject *self) > } > > static PyGetSetDef py_tevent_req_getsetters[] = { >- { "in_progress", (getter)py_tevent_req_is_in_progress, NULL, >- "Whether the request is in progress" }, >+ { >+ .name = discard_const_p(char, "in_progress"), >+ .get = (getter)py_tevent_req_is_in_progress, >+ .doc = discard_const_p(char, "Whether the request is in progress"), >+ }, > { NULL } > }; > >@@ -684,8 +688,11 @@ static PyObject *py_tevent_queue_get_length(TeventQueue_Object *self) > } > > static PyGetSetDef py_tevent_queue_getsetters[] = { >- { "length", (getter)py_tevent_queue_get_length, >- NULL, "The number of elements in the queue." }, >+ { >+ .name = discard_const_p(char, "length"), >+ .get = (getter)py_tevent_queue_get_length, >+ .doc = discard_const_p(char, "The number of elements in the queue."), >+ }, > { NULL }, > }; > >@@ -711,8 +718,11 @@ static PyObject *py_tevent_context_signal_support(PyObject *_self) > } > > static PyGetSetDef py_tevent_context_getsetters[] = { >- { "signal_support", (getter)py_tevent_context_signal_support, >- NULL, "if this platform and tevent context support signal handling" }, >+ { >+ .name = discard_const_p(char, "signal_support"), >+ .get = (getter)py_tevent_context_signal_support, >+ .doc = discard_const_p(char, "if this platform and tevent context support signal handling"), >+ }, > { NULL } > }; > >@@ -729,7 +739,7 @@ static PyObject *py_tevent_context_new(PyTypeObject *type, PyObject *args, PyObj > struct tevent_context *ev; > TeventContext_Object *ret; > >- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwnames, &name)) >+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", discard_const_p(char *, kwnames), &name)) > return NULL; > > if (name == NULL) { >-- >1.9.1 > > >From 2ced4266b00d95db5f28803772977b30e6a542e9 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 11 Jun 2015 09:51:19 +0200 >Subject: [PATCH 54/55] pytevent: add a TeventTimer_Object_ref helper structure > to make the code clearer > >This gives talloc_set_destructor to verify the type, >which removes a compiler warning. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit 93ee074f912da02d4c1f1584df9b107364b639be) >--- > lib/tevent/pytevent.c | 22 +++++++++++++--------- > 1 file changed, 13 insertions(+), 9 deletions(-) > >diff --git a/lib/tevent/pytevent.c b/lib/tevent/pytevent.c >index a22bf26..752e251 100644 >--- a/lib/tevent/pytevent.c >+++ b/lib/tevent/pytevent.c >@@ -401,11 +401,14 @@ static PyTypeObject TeventTimer_Type = { > .tp_flags = Py_TPFLAGS_DEFAULT, > }; > >-static int timer_destructor(void* ptr) >+struct TeventTimer_Object_ref { >+ TeventTimer_Object *obj; >+}; >+ >+static int TeventTimer_Object_ref_destructor(struct TeventTimer_Object_ref *ref) > { >- TeventTimer_Object *obj = *(TeventTimer_Object **)ptr; >- obj->timer = NULL; >- Py_DECREF(obj); >+ ref->obj->timer = NULL; >+ Py_DECREF(ref->obj); > return 0; > } > >@@ -440,7 +443,7 @@ static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self > * The Python timer holds a reference to the callback. > */ > TeventTimer_Object *ret; >- TeventTimer_Object **tmp_context; >+ struct TeventTimer_Object_ref *ref; > > ret = PyObject_New(TeventTimer_Object, &TeventTimer_Type); > if (ret == NULL) { >@@ -456,16 +459,17 @@ static PyObject *py_tevent_context_add_timer_internal(TeventContext_Object *self > PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); > return NULL; > } >- tmp_context = talloc(ret->timer, TeventTimer_Object*); >- if (tmp_context == NULL) { >+ ref = talloc(ret->timer, struct TeventTimer_Object_ref); >+ if (ref == NULL) { > talloc_free(ret->timer); > Py_DECREF(ret); > PyErr_SetString(PyExc_RuntimeError, "Could not initialize timer"); > return NULL; > } > Py_INCREF(ret); >- *tmp_context = ret; >- talloc_set_destructor(tmp_context, timer_destructor); >+ ref->obj = ret; >+ >+ talloc_set_destructor(ref, TeventTimer_Object_ref_destructor); > > return (PyObject *)ret; > } >-- >1.9.1 > > >From 9e2e26aa1017e218d7e3c187841937e6dff6fe3f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 12 Jun 2015 08:58:26 +0200 >Subject: [PATCH 55/55] tevent: version 0.9.25 > >* Fix compile error in Solaris ports backend. >* Fix access after free in tevent_common_check_signal(). bug #11308 >* Improve pytevent bindings. >* Testsuite fixes. >* Improve the documentation of the tevent_add_fd() > assumtions. It must be talloc_free'ed before closing the fd! > See bug #11141 and bug #11316. > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Michael Adam <obnox@samba.org> >(cherry picked from commit d7bdb30cc1731dc84831e323332a85be2bccf6a7) >--- > lib/tevent/ABI/tevent-0.9.25.sigs | 88 +++++++++++++++++++++++++++++++++++++++ > lib/tevent/wscript | 2 +- > 2 files changed, 89 insertions(+), 1 deletion(-) > create mode 100644 lib/tevent/ABI/tevent-0.9.25.sigs > >diff --git a/lib/tevent/ABI/tevent-0.9.25.sigs b/lib/tevent/ABI/tevent-0.9.25.sigs >new file mode 100644 >index 0000000..d8b9f4b >--- /dev/null >+++ b/lib/tevent/ABI/tevent-0.9.25.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 0da8232..9abbd9b 100755 >--- a/lib/tevent/wscript >+++ b/lib/tevent/wscript >@@ -1,7 +1,7 @@ > #!/usr/bin/env python > > APPNAME = 'tevent' >-VERSION = '0.9.24' >+VERSION = '0.9.25' > > blddir = 'bin' > >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 11330
:
11153
| 11160