From 12d8469e69da98d14bd15d4e3aa225b2ca5e96b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Sep 2017 12:08:38 -0700 Subject: [PATCH 1/2] lib: tevent: Remove select backend. select() is no longer useful on modern systems. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Sat Sep 16 08:35:39 CEST 2017 on sn-devel-144 (cherry picked from commit 2a003b1a576dcbbba0d60bae90427776a5c27867) --- lib/tevent/tevent.c | 1 - lib/tevent/tevent_internal.h | 1 - lib/tevent/tevent_select.c | 280 ------------------------------------------- lib/tevent/wscript | 2 +- source3/selftest/tests.py | 2 +- source3/torture/torture.c | 10 +- 6 files changed, 7 insertions(+), 289 deletions(-) delete mode 100644 lib/tevent/tevent_select.c diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c index 5f44b03..a2d2003 100644 --- a/lib/tevent/tevent.c +++ b/lib/tevent/tevent.c @@ -128,7 +128,6 @@ static void tevent_backend_init(void) done = true; - tevent_select_init(); tevent_poll_init(); tevent_poll_mt_init(); #if defined(HAVE_EPOLL) diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h index a5f1ebde..47ea39b 100644 --- a/lib/tevent/tevent_internal.h +++ b/lib/tevent/tevent_internal.h @@ -377,7 +377,6 @@ int tevent_common_check_signal(struct tevent_context *ev); void tevent_cleanup_pending_signal_handlers(struct tevent_signal *se); bool tevent_standard_init(void); -bool tevent_select_init(void); bool tevent_poll_init(void); void tevent_poll_event_add_fd_internal(struct tevent_context *ev, struct tevent_fd *fde); diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c deleted file mode 100644 index 55dd0b6..0000000 --- a/lib/tevent/tevent_select.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - Unix SMB/CIFS implementation. - main select loop and event handling - Copyright (C) Andrew Tridgell 2003-2005 - Copyright (C) Stefan Metzmacher 2005-2009 - - ** NOTE! The following LGPL license applies to the tevent - ** library. This does NOT imply that all of Samba is released - ** under the LGPL - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 3 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, see . -*/ - -#include "replace.h" -#include "system/filesys.h" -#include "system/select.h" -#include "tevent.h" -#include "tevent_util.h" -#include "tevent_internal.h" - -struct select_event_context { - /* a pointer back to the generic event_context */ - struct tevent_context *ev; - - /* the maximum file descriptor number in fd_events */ - int maxfd; -}; - -/* - create a select_event_context structure. -*/ -static int select_event_context_init(struct tevent_context *ev) -{ - struct select_event_context *select_ev; - - /* - * We might be called during tevent_re_initialise() - * which means we need to free our old additional_data. - */ - TALLOC_FREE(ev->additional_data); - - select_ev = talloc_zero(ev, struct select_event_context); - if (!select_ev) return -1; - select_ev->ev = ev; - - ev->additional_data = select_ev; - return 0; -} - -/* - recalculate the maxfd -*/ -static void calc_maxfd(struct select_event_context *select_ev) -{ - struct tevent_fd *fde; - - select_ev->maxfd = 0; - for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { - if (fde->fd > select_ev->maxfd) { - select_ev->maxfd = fde->fd; - } - } -} - - -/* to mark the ev->maxfd invalid - * this means we need to recalculate it - */ -#define EVENT_INVALID_MAXFD (-1) - -/* - destroy an fd_event -*/ -static int select_event_fd_destructor(struct tevent_fd *fde) -{ - struct tevent_context *ev = fde->event_ctx; - struct select_event_context *select_ev = NULL; - - if (ev) { - 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; - } - } - - return tevent_common_fd_destructor(fde); -} - -/* - add a fd based event - return NULL on failure (memory allocation error) -*/ -static struct tevent_fd *select_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 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) { - errno = EBADF; - return NULL; - } - - fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, - handler, private_data, - handler_name, location); - if (!fde) return NULL; - - if ((select_ev->maxfd != EVENT_INVALID_MAXFD) - && (fde->fd > select_ev->maxfd)) { - select_ev->maxfd = fde->fd; - } - talloc_set_destructor(fde, select_event_fd_destructor); - - return fde; -} - -/* - event loop handling using select() -*/ -static int select_event_loop_select(struct select_event_context *select_ev, struct timeval *tvalp) -{ - fd_set r_fds, w_fds; - struct tevent_fd *fde; - int selrtn; - int select_errno; - - /* we maybe need to recalculate the maxfd */ - if (select_ev->maxfd == EVENT_INVALID_MAXFD) { - calc_maxfd(select_ev); - } - - FD_ZERO(&r_fds); - FD_ZERO(&w_fds); - - /* setup any fd events */ - for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { - if (fde->fd < 0 || fde->fd >= FD_SETSIZE) { - tevent_debug(select_ev->ev, TEVENT_DEBUG_FATAL, - "ERROR: EBADF fd[%d] >= %d " - "select_event_loop_once\n", - fde->fd, FD_SETSIZE); - errno = EBADF; - return -1; - } - - if (fde->flags & TEVENT_FD_READ) { - FD_SET(fde->fd, &r_fds); - } - if (fde->flags & TEVENT_FD_WRITE) { - FD_SET(fde->fd, &w_fds); - } - } - - if (select_ev->ev->signal_events && - tevent_common_check_signal(select_ev->ev)) { - return 0; - } - - tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_BEFORE_WAIT); - selrtn = select(select_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp); - select_errno = errno; - tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_AFTER_WAIT); - - if (selrtn == -1 && select_errno == EINTR && - select_ev->ev->signal_events) { - tevent_common_check_signal(select_ev->ev); - return 0; - } - - if (selrtn == -1 && select_errno == EBADF) { - /* the socket is dead! this should never - happen as the socket should have first been - made readable and that should have removed - the event, so this must be a bug. This is a - fatal error. */ - tevent_debug(select_ev->ev, TEVENT_DEBUG_FATAL, - "ERROR: EBADF on select_event_loop_once\n"); - errno = select_errno; - return -1; - } - - if (selrtn == 0 && tvalp) { - /* we don't care about a possible delay here */ - tevent_common_loop_timer_delay(select_ev->ev); - return 0; - } - - if (selrtn > 0) { - /* at least one file descriptor is ready - check - which ones and call the handler, being careful to allow - the handler to remove itself when called */ - for (fde = select_ev->ev->fd_events; fde; fde = fde->next) { - uint16_t flags = 0; - - if (FD_ISSET(fde->fd, &r_fds) && (fde->flags & TEVENT_FD_READ)) { - flags |= TEVENT_FD_READ; - } - if (FD_ISSET(fde->fd, &w_fds) && (fde->flags & TEVENT_FD_WRITE)) { - flags |= TEVENT_FD_WRITE; - } - if (flags) { - DLIST_DEMOTE(select_ev->ev->fd_events, fde); - fde->handler(select_ev->ev, fde, flags, fde->private_data); - break; - } - } - } - - return 0; -} - -/* - do a single event loop using the events defined in ev -*/ -static int select_event_loop_once(struct tevent_context *ev, const char *location) -{ - struct select_event_context *select_ev = - talloc_get_type_abort(ev->additional_data, - struct select_event_context); - struct timeval tval; - - if (ev->signal_events && - tevent_common_check_signal(ev)) { - return 0; - } - - if (ev->threaded_contexts != NULL) { - tevent_common_threaded_activate_immediate(ev); - } - - 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; - } - - return select_event_loop_select(select_ev, &tval); -} - -static const struct tevent_ops select_event_ops = { - .context_init = select_event_context_init, - .add_fd = select_event_add_fd, - .set_fd_close_fn = tevent_common_fd_set_close_fn, - .get_fd_flags = tevent_common_fd_get_flags, - .set_fd_flags = tevent_common_fd_set_flags, - .add_timer = tevent_common_add_timer_v2, - .schedule_immediate = tevent_common_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = select_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -_PRIVATE_ bool tevent_select_init(void) -{ - return tevent_register_backend("select", &select_event_ops); -} diff --git a/lib/tevent/wscript b/lib/tevent/wscript index bc874bb..91880738 100644 --- a/lib/tevent/wscript +++ b/lib/tevent/wscript @@ -77,7 +77,7 @@ def build(bld): bld.RECURSE('lib/talloc') SRC = '''tevent.c tevent_debug.c tevent_fd.c tevent_immediate.c - tevent_queue.c tevent_req.c tevent_select.c + tevent_queue.c tevent_req.c tevent_poll.c tevent_threads.c tevent_signal.c tevent_standard.c tevent_timed.c tevent_util.c tevent_wakeup.c''' diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 56b94c4..d11f596 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -133,7 +133,7 @@ local_tests = [ "LOCAL-sid_to_string", "LOCAL-binary_to_sid", "LOCAL-DBTRANS", - "LOCAL-TEVENT-SELECT", + "LOCAL-TEVENT-POLL", "LOCAL-CONVERT-STRING", "LOCAL-CONV-AUTH-INFO", "LOCAL-IDMAP-TDB-COMMON", diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 31e2bcc..1d89041 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -11114,17 +11114,17 @@ static bool run_local_dbtrans(int dummy) /* * Just a dummy test to be run under a debugger. There's no real way - * to inspect the tevent_select specific function from outside of - * tevent_select.c. + * to inspect the tevent_poll specific function from outside of + * tevent_poll.c. */ -static bool run_local_tevent_select(int dummy) +static bool run_local_tevent_poll(int dummy) { struct tevent_context *ev; struct tevent_fd *fd1, *fd2; bool result = false; - ev = tevent_context_init_byname(NULL, "select"); + ev = tevent_context_init_byname(NULL, "poll"); if (ev == NULL) { d_fprintf(stderr, "tevent_context_init_byname failed\n"); goto fail; @@ -11677,7 +11677,7 @@ static struct { { "LOCAL-sid_to_string", run_local_sid_to_string, 0}, { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0}, { "LOCAL-DBTRANS", run_local_dbtrans, 0}, - { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0}, + { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0}, { "LOCAL-CONVERT-STRING", run_local_convert_string, 0}, { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0}, { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0}, -- 1.9.1 From 42c2b46ffd3f69ccf064307ea263873d13f9560f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Nov 2017 11:05:04 +0100 Subject: [PATCH 2/2] tevent: version 0.9.34 * Remove unused select backend * Fix a race condition in tevent_threaded_schedule_immediate() (bug #13130) Signed-off-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Mon Nov 13 18:02:46 CET 2017 on sn-devel-144 (cherry picked from commit 2e573eead96b2e98dd8a15c9c8e470679e530392) --- lib/tevent/ABI/tevent-0.9.34.sigs | 99 +++++++++++++++++++++++++++++++++++++++ lib/tevent/wscript | 2 +- 2 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 lib/tevent/ABI/tevent-0.9.34.sigs diff --git a/lib/tevent/ABI/tevent-0.9.34.sigs b/lib/tevent/ABI/tevent-0.9.34.sigs new file mode 100644 index 0000000..7a6a236 --- /dev/null +++ b/lib/tevent/ABI/tevent-0.9.34.sigs @@ -0,0 +1,99 @@ +_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_threaded_schedule_immediate: void (struct tevent_threaded_context *, struct tevent_immediate *, 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_have_events: bool (struct tevent_context *) +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_common_threaded_activate_immediate: void (struct tevent_context *) +tevent_common_wakeup: int (struct tevent_context *) +tevent_common_wakeup_fd: int (int) +tevent_common_wakeup_init: int (struct tevent_context *) +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_reset_endtime: 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_thread_proxy_create: struct tevent_thread_proxy *(struct tevent_context *) +tevent_thread_proxy_schedule: void (struct tevent_thread_proxy *, struct tevent_immediate **, tevent_immediate_handler_t, void *) +tevent_threaded_context_create: struct tevent_threaded_context *(TALLOC_CTX *, 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_update_timer: void (struct tevent_timer *, struct timeval) +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 91880738..31f7ee7 100644 --- a/lib/tevent/wscript +++ b/lib/tevent/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'tevent' -VERSION = '0.9.33' +VERSION = '0.9.34' blddir = 'bin' -- 1.9.1