From a992329246c5d48d76d9408e36f78da890d659ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Sep 2016 20:00:33 -0700 Subject: [PATCH] s3: events. Move events.c to util_event.c Remove all tevent internal code. Everything is now stock tevent. Bug: https://bugzilla.samba.org/show_bug.cgi?id=12283 Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke (similar to commit 4ed790ebbf474c4e4ef9b4f0f3aeca65118796df) --- source3/include/includes.h | 4 +- source3/include/{event.h => util_event.h} | 16 +- source3/lib/events.c | 486 ---------------------- source3/lib/util_event.c | 101 +++++ source3/wscript_build | 2 +- 5 files changed, 105 insertions(+), 504 deletions(-) rename source3/include/{event.h => util_event.h} (64%) delete mode 100644 source3/lib/events.c create mode 100644 source3/lib/util_event.c diff --git a/source3/include/includes.h b/source3/include/includes.h index 81bba40e355..234a5644ab4 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -310,8 +310,8 @@ typedef char fstring[FSTRING_LEN]; #include "../lib/util/dlinklist.h" #include - -#include "event.h" +#include +#include "util_event.h" #include "../lib/util/data_blob.h" #include "../lib/util/time.h" diff --git a/source3/include/event.h b/source3/include/util_event.h similarity index 64% rename from source3/include/event.h rename to source3/include/util_event.h index 108026e2f5a..df608a193f9 100644 --- a/source3/include/event.h +++ b/source3/include/util_event.h @@ -18,21 +18,7 @@ along with this program. If not, see . */ -#include - -/* The following definitions come from lib/events.c */ -struct pollfd; -struct timeval *get_timed_events_timeout(struct tevent_context *event_ctx, - struct timeval *to_ret); -void dump_event_list(struct tevent_context *event_ctx); -struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx); - -bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - struct pollfd **pfds, int *num_pfds, - int *ptimeout); -bool run_events_poll(struct tevent_context *ev, int pollrtn, - struct pollfd *pfds, int num_pfds); - +/* The following definitions come from lib/util_event.c */ struct idle_event *event_add_idle(struct tevent_context *event_ctx, TALLOC_CTX *mem_ctx, struct timeval interval, diff --git a/source3/lib/events.c b/source3/lib/events.c deleted file mode 100644 index 0bc56e454ad..00000000000 --- a/source3/lib/events.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Timed event library. - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Volker Lendecke 2005-2007 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "lib/tevent/tevent_internal.h" -#include "../lib/util/select.h" -#include "system/select.h" - -struct tevent_poll_private { - /* - * Index from file descriptor into the pollfd array - */ - int *pollfd_idx; - - /* - * Cache for s3_event_loop_once to avoid reallocs - */ - struct pollfd *pfds; -}; - -static struct tevent_poll_private *tevent_get_poll_private( - struct tevent_context *ev) -{ - struct tevent_poll_private *state; - - state = (struct tevent_poll_private *)ev->additional_data; - if (state == NULL) { - state = talloc_zero(ev, struct tevent_poll_private); - ev->additional_data = (void *)state; - if (state == NULL) { - DEBUG(10, ("talloc failed\n")); - } - } - return state; -} - -static void count_fds(struct tevent_context *ev, - int *pnum_fds, int *pmax_fd) -{ - struct tevent_fd *fde; - int num_fds = 0; - int max_fd = 0; - - for (fde = ev->fd_events; fde != NULL; fde = fde->next) { - if (fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) { - num_fds += 1; - if (fde->fd > max_fd) { - max_fd = fde->fd; - } - } - } - *pnum_fds = num_fds; - *pmax_fd = max_fd; -} - -bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx, - struct pollfd **pfds, int *pnum_pfds, - int *ptimeout) -{ - struct tevent_poll_private *state; - struct tevent_fd *fde; - int i, num_fds, max_fd, num_pollfds, idx_len; - struct pollfd *fds; - struct timeval now, diff; - int timeout; - - state = tevent_get_poll_private(ev); - if (state == NULL) { - return false; - } - count_fds(ev, &num_fds, &max_fd); - - idx_len = max_fd+1; - - if (talloc_array_length(state->pollfd_idx) < idx_len) { - state->pollfd_idx = talloc_realloc( - state, state->pollfd_idx, int, idx_len); - if (state->pollfd_idx == NULL) { - DEBUG(10, ("talloc_realloc failed\n")); - return false; - } - } - - fds = *pfds; - num_pollfds = *pnum_pfds; - - if (talloc_array_length(fds) < num_pollfds + num_fds) { - fds = talloc_realloc(mem_ctx, fds, struct pollfd, - num_pollfds + num_fds); - if (fds == NULL) { - DEBUG(10, ("talloc_realloc failed\n")); - return false; - } - } - - memset(&fds[num_pollfds], 0, sizeof(struct pollfd) * num_fds); - - /* - * This needs tuning. We need to cope with multiple fde's for a file - * descriptor. The problem is that we need to re-use pollfd_idx across - * calls for efficiency. One way would be a direct bitmask that might - * be initialized quicker, but our bitmap_init implementation is - * pretty heavy-weight as well. - */ - for (i=0; ipollfd_idx[i] = -1; - } - - for (fde = ev->fd_events; fde; fde = fde->next) { - struct pollfd *pfd; - - if ((fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) == 0) { - continue; - } - - if (state->pollfd_idx[fde->fd] == -1) { - /* - * We haven't seen this fd yet. Allocate a new pollfd. - */ - state->pollfd_idx[fde->fd] = num_pollfds; - pfd = &fds[num_pollfds]; - num_pollfds += 1; - } else { - /* - * We have already seen this fd. OR in the flags. - */ - pfd = &fds[state->pollfd_idx[fde->fd]]; - } - - pfd->fd = fde->fd; - - if (fde->flags & TEVENT_FD_READ) { - pfd->events |= (POLLIN|POLLHUP); - } - if (fde->flags & TEVENT_FD_WRITE) { - pfd->events |= POLLOUT; - } - } - *pfds = fds; - *pnum_pfds = num_pollfds; - - if (ev->immediate_events != NULL) { - *ptimeout = 0; - return true; - } - if (ev->timer_events == NULL) { - *ptimeout = MIN(*ptimeout, INT_MAX); - return true; - } - - now = timeval_current(); - diff = timeval_until(&now, &ev->timer_events->next_event); - timeout = timeval_to_msec(diff); - - if (timeout < *ptimeout) { - *ptimeout = timeout; - } - - return true; -} - -bool run_events_poll(struct tevent_context *ev, int pollrtn, - struct pollfd *pfds, int num_pfds) -{ - struct tevent_poll_private *state; - int *pollfd_idx; - struct tevent_fd *fde; - - if (ev->signal_events && - tevent_common_check_signal(ev)) { - return true; - } - - if (ev->immediate_events && - tevent_common_loop_immediate(ev)) { - return true; - } - - if (pollrtn <= 0) { - struct timeval tval; - - tval = tevent_common_loop_timer_delay(ev); - if (tevent_timeval_is_zero(&tval)) { - return true; - } - - /* - * No fd ready - */ - return false; - } - - state = (struct tevent_poll_private *)ev->additional_data; - pollfd_idx = state->pollfd_idx; - - for (fde = ev->fd_events; fde; fde = fde->next) { - struct pollfd *pfd; - uint16_t flags = 0; - - if ((fde->flags & (TEVENT_FD_READ|TEVENT_FD_WRITE)) == 0) { - continue; - } - - if (pollfd_idx[fde->fd] >= num_pfds) { - DEBUG(1, ("internal error: pollfd_idx[fde->fd] (%d) " - ">= num_pfds (%d)\n", pollfd_idx[fde->fd], - num_pfds)); - return false; - } - pfd = &pfds[pollfd_idx[fde->fd]]; - - if (pfd->fd != fde->fd) { - DEBUG(1, ("internal error: pfd->fd (%d) " - "!= fde->fd (%d)\n", pollfd_idx[fde->fd], - num_pfds)); - return false; - } - - if (pfd->revents & (POLLHUP|POLLERR)) { - /* If we only wait for TEVENT_FD_WRITE, we - should not tell the event handler about it, - and remove the writable flag, as we only - report errors when waiting for read events - to match the select behavior. */ - if (!(fde->flags & TEVENT_FD_READ)) { - TEVENT_FD_NOT_WRITEABLE(fde); - continue; - } - flags |= TEVENT_FD_READ; - } - - if (pfd->revents & POLLIN) { - flags |= TEVENT_FD_READ; - } - if (pfd->revents & POLLOUT) { - flags |= TEVENT_FD_WRITE; - } - if (flags & fde->flags) { - DLIST_DEMOTE(ev->fd_events, fde, struct tevent_fd); - fde->handler(ev, fde, flags, fde->private_data); - return true; - } - } - - return false; -} - -struct timeval *get_timed_events_timeout(struct tevent_context *ev, - struct timeval *to_ret) -{ - struct timeval now; - - if ((ev->timer_events == NULL) && (ev->immediate_events == NULL)) { - return NULL; - } - if (ev->immediate_events != NULL) { - *to_ret = timeval_zero(); - return to_ret; - } - - now = timeval_current(); - *to_ret = timeval_until(&now, &ev->timer_events->next_event); - - DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec, - (int)to_ret->tv_usec)); - - return to_ret; -} - -static int s3_event_loop_once(struct tevent_context *ev, const char *location) -{ - struct tevent_poll_private *state; - int timeout; - int num_pfds; - int ret; - int poll_errno; - - timeout = INT_MAX; - - state = tevent_get_poll_private(ev); - if (state == NULL) { - errno = ENOMEM; - return -1; - } - - if (run_events_poll(ev, 0, NULL, 0)) { - return 0; - } - - num_pfds = 0; - if (!event_add_to_poll_args(ev, state, - &state->pfds, &num_pfds, &timeout)) { - return -1; - } - - tevent_trace_point_callback(ev, TEVENT_TRACE_BEFORE_WAIT); - ret = poll(state->pfds, num_pfds, timeout); - poll_errno = errno; - tevent_trace_point_callback(ev, TEVENT_TRACE_AFTER_WAIT); - errno = poll_errno; - - if (ret == -1 && errno != EINTR) { - tevent_debug(ev, TEVENT_DEBUG_FATAL, - "poll() failed: %d:%s\n", - errno, strerror(errno)); - return -1; - } - - run_events_poll(ev, ret, state->pfds, num_pfds); - return 0; -} - -static int s3_event_context_init(struct tevent_context *ev) -{ - return 0; -} - -void dump_event_list(struct tevent_context *ev) -{ - struct tevent_timer *te; - struct tevent_fd *fe; - struct timeval evt, now; - - if (!ev) { - return; - } - - now = timeval_current(); - - DEBUG(10,("dump_event_list:\n")); - - for (te = ev->timer_events; te; te = te->next) { - - evt = timeval_until(&now, &te->next_event); - - DEBUGADD(10,("Timed Event \"%s\" %p handled in %d seconds (at %s)\n", - te->handler_name, - te, - (int)evt.tv_sec, - http_timestring(talloc_tos(), te->next_event.tv_sec))); - } - - for (fe = ev->fd_events; fe; fe = fe->next) { - - DEBUGADD(10,("FD Event %d %p, flags: 0x%04x\n", - fe->fd, - fe, - fe->flags)); - } -} - -static const struct tevent_ops s3_event_ops = { - .context_init = s3_event_context_init, - .add_fd = tevent_common_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, - .schedule_immediate = tevent_common_schedule_immediate, - .add_signal = tevent_common_add_signal, - .loop_once = s3_event_loop_once, - .loop_wait = tevent_common_loop_wait, -}; - -static bool s3_tevent_init(void) -{ - static bool initialized; - if (initialized) { - return true; - } - initialized = tevent_register_backend("s3", &s3_event_ops); - tevent_set_default_backend("s3"); - return initialized; -} - -struct tevent_context *s3_tevent_context_init(TALLOC_CTX *mem_ctx) -{ - struct tevent_context *ev; - - s3_tevent_init(); - - ev = tevent_context_init_byname(mem_ctx, "s3"); - if (ev) { - samba_tevent_set_debug(ev, "s3_tevent"); - } - - return ev; -} - -struct idle_event { - struct tevent_timer *te; - struct timeval interval; - char *name; - bool (*handler)(const struct timeval *now, void *private_data); - void *private_data; -}; - -static void smbd_idle_event_handler(struct tevent_context *ctx, - struct tevent_timer *te, - struct timeval now, - void *private_data) -{ - struct idle_event *event = - talloc_get_type_abort(private_data, struct idle_event); - - TALLOC_FREE(event->te); - - DEBUG(10,("smbd_idle_event_handler: %s %p called\n", - event->name, event->te)); - - if (!event->handler(&now, event->private_data)) { - DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n", - event->name, event->te)); - /* Don't repeat, delete ourselves */ - TALLOC_FREE(event); - return; - } - - DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n", - event->name, event->te)); - - event->te = tevent_add_timer(ctx, event, - timeval_sum(&now, &event->interval), - smbd_idle_event_handler, event); - - /* We can't do much but fail here. */ - SMB_ASSERT(event->te != NULL); -} - -struct idle_event *event_add_idle(struct tevent_context *event_ctx, - TALLOC_CTX *mem_ctx, - struct timeval interval, - const char *name, - bool (*handler)(const struct timeval *now, - void *private_data), - void *private_data) -{ - struct idle_event *result; - struct timeval now = timeval_current(); - - result = talloc(mem_ctx, struct idle_event); - if (result == NULL) { - DEBUG(0, ("talloc failed\n")); - return NULL; - } - - result->interval = interval; - result->handler = handler; - result->private_data = private_data; - - if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) { - DEBUG(0, ("talloc failed\n")); - TALLOC_FREE(result); - return NULL; - } - - result->te = tevent_add_timer(event_ctx, result, - timeval_sum(&now, &interval), - smbd_idle_event_handler, result); - if (result->te == NULL) { - DEBUG(0, ("event_add_timed failed\n")); - TALLOC_FREE(result); - return NULL; - } - - DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te)); - return result; -} - diff --git a/source3/lib/util_event.c b/source3/lib/util_event.c new file mode 100644 index 00000000000..4ca2840b661 --- /dev/null +++ b/source3/lib/util_event.c @@ -0,0 +1,101 @@ +/* + Unix SMB/CIFS implementation. + Timed event library. + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Volker Lendecke 2005-2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +struct idle_event { + struct tevent_timer *te; + struct timeval interval; + char *name; + bool (*handler)(const struct timeval *now, void *private_data); + void *private_data; +}; + +static void smbd_idle_event_handler(struct tevent_context *ctx, + struct tevent_timer *te, + struct timeval now, + void *private_data) +{ + struct idle_event *event = + talloc_get_type_abort(private_data, struct idle_event); + + TALLOC_FREE(event->te); + + DEBUG(10,("smbd_idle_event_handler: %s %p called\n", + event->name, event->te)); + + if (!event->handler(&now, event->private_data)) { + DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n", + event->name, event->te)); + /* Don't repeat, delete ourselves */ + TALLOC_FREE(event); + return; + } + + DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n", + event->name, event->te)); + + event->te = tevent_add_timer(ctx, event, + timeval_sum(&now, &event->interval), + smbd_idle_event_handler, event); + + /* We can't do much but fail here. */ + SMB_ASSERT(event->te != NULL); +} + +struct idle_event *event_add_idle(struct tevent_context *event_ctx, + TALLOC_CTX *mem_ctx, + struct timeval interval, + const char *name, + bool (*handler)(const struct timeval *now, + void *private_data), + void *private_data) +{ + struct idle_event *result; + struct timeval now = timeval_current(); + + result = talloc(mem_ctx, struct idle_event); + if (result == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + + result->interval = interval; + result->handler = handler; + result->private_data = private_data; + + if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) { + DEBUG(0, ("talloc failed\n")); + TALLOC_FREE(result); + return NULL; + } + + result->te = tevent_add_timer(event_ctx, result, + timeval_sum(&now, &interval), + smbd_idle_event_handler, result); + if (result->te == NULL) { + DEBUG(0, ("event_add_timed failed\n")); + TALLOC_FREE(result); + return NULL; + } + + DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te)); + return result; +} diff --git a/source3/wscript_build b/source3/wscript_build index d415220de05..761a874df65 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -333,7 +333,7 @@ bld.SAMBA3_SUBSYSTEM('samba3core', lib/dmallocmsg.c intl/lang_tdb.c lib/gencache.c - lib/events.c + lib/util_event.c lib/server_contexts.c lib/server_prefork.c lib/server_prefork_util.c