[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Thu Feb 14 14:41:02 MST 2013
The branch, master has been updated
via daada84 tevent: Remove the previous "standard" tevent backend implementation.
via 16f5707 tevent: Add in the new implementation of "standard" tevent backend.
via 203f85c tevent: Add a private function tevent_poll_event_add_fd_internal().
via 5fe459f tevent: make use of tevent_find_ops_byname() in tevent_context_init_byname()
via b5556a7 tevent: make sure tevent_backend_init() only runs once
via aceeb58 tevent: Add a utility function tevent_find_ops_byname().
via 1ee428d tevent: Add in the same tevent_re_initialise() fix Metze put in the tevent_poll backend.
via 06fb88b tevent: Add in some test code to allow the panic fallback path to be tested.
via 6f98192 tevent: Plumb in the panic fallback code into the epoll_panic() runtime call.
via 04ba47e tevent: Add an internal function tevent_epoll_set_panic_fallback().
via e4ef2ecf tevent: pass 'bool replay' to epoll_panic()
via 129da06 tevent: Ensure we return after every call to epoll_panic().
via c36f8c1 tevent: Preparing to fix "standard" backend fallback. Initialize standard after epoll.
from 736e3b1 docs: fix typo in serverrole.xml
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit daada849209df893ef9b42ea2be5de77d2d4125f
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 11:42:08 2013 -0800
tevent: Remove the previous "standard" tevent backend implementation.
This was a horrible hybrid of duplicated epoll and select()
code.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Jeremy Allison <jra at samba.org>
Autobuild-Date(master): Thu Feb 14 22:40:30 CET 2013 on sn-devel-104
commit 16f57076b1b527c65da42e1fab6119c67bcd7f47
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 11:40:49 2013 -0800
tevent: Add in the new implementation of "standard" tevent backend.
Falls back cleanly from epoll -> poll, or uses poll if
epoll not available.
Signed-off-by: Jeremy Allison <jra at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 203f85c25eb9238eae8e4dc5b55b549294b0fa03
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 11:20:28 2013 -0800
tevent: Add a private function tevent_poll_event_add_fd_internal().
Not yet used, but will be called by the "standard"
fallback from epoll -> poll backends.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 5fe459f5d7c0e6b5eeeb1aa2c8248e174a31008f
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 14 09:30:31 2013 +0100
tevent: make use of tevent_find_ops_byname() in tevent_context_init_byname()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit b5556a79e39be0bc9945cbac4e603b045ab55505
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 14 09:29:57 2013 +0100
tevent: make sure tevent_backend_init() only runs once
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit aceeb585cb6170e42cadae17791b8314083c278c
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:56:58 2013 -0800
tevent: Add a utility function tevent_find_ops_byname().
Returns an event ops struct given a string name. Not
yet used, but will be part of the new "standard" fallback
code.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 1ee428d5cad6910521ce77322614183fa2c7916e
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:53:15 2013 -0800
tevent: Add in the same tevent_re_initialise() fix Metze put in the tevent_poll backend.
We might be called during tevent_re_initialise()
which means we need to free our old additional_data.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 06fb88b449806d6de7ca20c73778dd6545a38cf7
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:52:30 2013 -0800
tevent: Add in some test code to allow the panic fallback path to be tested.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 6f9819229b3d60cb898a0f9bfc67793b6c40fc2c
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:48:02 2013 -0800
tevent: Plumb in the panic fallback code into the epoll_panic() runtime call.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 04ba47e491d84f58562b57f937be632e75c204aa
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:43:39 2013 -0800
tevent: Add an internal function tevent_epoll_set_panic_fallback().
Can be set externally, allows us to fallback if epoll
fails at runtime.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit e4ef2ecf023c63ee28e40a1b60ecc6091a126001
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 14 10:58:55 2013 +0100
tevent: pass 'bool replay' to epoll_panic()
A fallback panic handler will need to know if
there was an error while waiting for events
(replay=true) or if the error happened on modify
(replay=false).
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 129da06d2d9c9d1cedc5e4de492744b29adc1684
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:38:01 2013 -0800
tevent: Ensure we return after every call to epoll_panic().
Currently we can't return from this, but the new fallback
code will change this.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit c36f8c14008e55b2be2e93c0987eb6971d45855f
Author: Jeremy Allison <jra at samba.org>
Date: Mon Feb 11 10:36:52 2013 -0800
tevent: Preparing to fix "standard" backend fallback. Initialize standard after epoll.
Signed-off-by: Jeremy Allison <jra at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
lib/tevent/tevent.c | 51 +++-
lib/tevent/tevent_epoll.c | 84 +++++-
lib/tevent/tevent_internal.h | 7 +
lib/tevent/tevent_poll.c | 16 +
lib/tevent/tevent_select.c | 6 +
lib/tevent/tevent_standard.c | 625 +++++++++---------------------------------
6 files changed, 266 insertions(+), 523 deletions(-)
Changeset truncated at 500 lines:
diff --git a/lib/tevent/tevent.c b/lib/tevent/tevent.c
index fa842e4..aa758de 100644
--- a/lib/tevent/tevent.c
+++ b/lib/tevent/tevent.c
@@ -112,13 +112,43 @@ void tevent_set_default_backend(const char *backend)
*/
static void tevent_backend_init(void)
{
+ static bool done;
+
+ if (done) {
+ return;
+ }
+
+ done = true;
+
tevent_select_init();
tevent_poll_init();
tevent_poll_mt_init();
- tevent_standard_init();
#ifdef HAVE_EPOLL
tevent_epoll_init();
#endif
+ tevent_standard_init();
+}
+
+_PRIVATE_ const struct tevent_ops *tevent_find_ops_byname(const char *name)
+{
+ struct tevent_ops_list *e;
+
+ tevent_backend_init();
+
+ if (name == NULL) {
+ name = tevent_default_backend;
+ }
+ if (name == NULL) {
+ name = "standard";
+ }
+
+ for (e = tevent_backends; e != NULL; e = e->next) {
+ if (0 == strcmp(e->name, name)) {
+ return e->ops;
+ }
+ }
+
+ return NULL;
}
/*
@@ -243,23 +273,14 @@ struct tevent_context *tevent_context_init_ops(TALLOC_CTX *mem_ctx,
struct tevent_context *tevent_context_init_byname(TALLOC_CTX *mem_ctx,
const char *name)
{
- struct tevent_ops_list *e;
+ struct tevent_ops *ops;
- tevent_backend_init();
-
- if (name == NULL) {
- name = tevent_default_backend;
- }
- if (name == NULL) {
- name = "standard";
+ ops = tevent_find_ops_byname(name);
+ if (ops == NULL) {
+ return NULL;
}
- for (e=tevent_backends;e;e=e->next) {
- if (strcmp(name, e->name) == 0) {
- return tevent_context_init_ops(mem_ctx, e->ops, NULL);
- }
- }
- return NULL;
+ return tevent_context_init_ops(mem_ctx, ops, NULL);
}
diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c
index 5f93de2..8696215 100644
--- a/lib/tevent/tevent_epoll.c
+++ b/lib/tevent/tevent_epoll.c
@@ -39,16 +39,76 @@ struct epoll_event_context {
int epoll_fd;
pid_t pid;
+
+ bool (*panic_fallback)(struct tevent_context *ev, bool replay);
};
+#ifdef TEST_PANIC_FALLBACK
+static int epoll_wait_panic_fallback(int epfd,
+ struct epoll_event *events,
+ int maxevents,
+ int timeout)
+{
+ /* 50% of the time, fail... */
+ if ((random() % 2) == 0) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return epoll_wait(epfd, events, maxevents, timeout);
+}
+
+#define epoll_wait epoll_wait_panic_fallback
+#endif
+
+/*
+ called to set the panic fallback function.
+*/
+_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;
+ }
+
+ 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;
+}
+
/*
called when a epoll call fails
*/
-static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason)
+static void epoll_panic(struct epoll_event_context *epoll_ev,
+ const char *reason, bool replay)
{
- tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL,
- "%s (%s) - calling abort()\n", reason, strerror(errno));
- abort();
+ struct tevent_context *ev = epoll_ev->ev;
+
+ if (epoll_ev->panic_fallback == NULL) {
+ tevent_debug(ev, TEVENT_DEBUG_FATAL,
+ "%s (%s) replay[%u] - calling abort()\n",
+ reason, strerror(errno), (unsigned)replay);
+ abort();
+ }
+
+ tevent_debug(ev, TEVENT_DEBUG_WARNING,
+ "%s (%s) replay[%u] - calling panic_fallback\n",
+ reason, strerror(errno), (unsigned)replay);
+
+ if (!epoll_ev->panic_fallback(ev, replay)) {
+ /* Fallback failed. */
+ tevent_debug(ev, TEVENT_DEBUG_FATAL,
+ "%s (%s) replay[%u] - calling abort()\n",
+ reason, strerror(errno), (unsigned)replay);
+ abort();
+ }
}
/*
@@ -151,7 +211,8 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
- epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed");
+ epoll_panic(epoll_ev, "EPOLL_CTL_ADD failed", false);
+ return;
}
fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
@@ -200,7 +261,8 @@ static void epoll_mod_event(struct epoll_event_context *epoll_ev, struct tevent_
event.events = epoll_map_flags(fde->flags);
event.data.ptr = fde;
if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_MOD, fde->fd, &event) != 0) {
- epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed");
+ epoll_panic(epoll_ev, "EPOLL_CTL_MOD failed", false);
+ return;
}
/* only if we want to read we want to tell the event handler about errors */
@@ -275,7 +337,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
}
if (ret == -1 && errno != EINTR) {
- epoll_panic(epoll_ev, "epoll_wait() failed");
+ epoll_panic(epoll_ev, "epoll_wait() failed", true);
return -1;
}
@@ -291,7 +353,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
uint16_t flags = 0;
if (fde == NULL) {
- epoll_panic(epoll_ev, "epoll_wait() gave bad data");
+ epoll_panic(epoll_ev, "epoll_wait() gave bad data", true);
return -1;
}
if (events[i].events & (EPOLLHUP|EPOLLERR)) {
@@ -327,6 +389,12 @@ static int epoll_event_context_init(struct tevent_context *ev)
int ret;
struct epoll_event_context *epoll_ev;
+ /*
+ * We might be called during tevent_re_initialise()
+ * which means we need to free our old additional_data.
+ */
+ TALLOC_FREE(ev->additional_data);
+
epoll_ev = talloc_zero(ev, struct epoll_event_context);
if (!epoll_ev) return -1;
epoll_ev->ev = ev;
diff --git a/lib/tevent/tevent_internal.h b/lib/tevent/tevent_internal.h
index f09cf57..8433333 100644
--- a/lib/tevent/tevent_internal.h
+++ b/lib/tevent/tevent_internal.h
@@ -265,6 +265,7 @@ struct tevent_context {
} tracing;
};
+const struct tevent_ops *tevent_find_ops_byname(const char *name);
int tevent_common_context_destructor(struct tevent_context *ev);
int tevent_common_loop_wait(struct tevent_context *ev,
@@ -315,10 +316,16 @@ 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);
bool tevent_poll_mt_init(void);
#ifdef HAVE_EPOLL
bool tevent_epoll_init(void);
+bool tevent_epoll_set_panic_fallback(struct tevent_context *ev,
+ bool (*panic_fallback)(struct tevent_context *ev,
+ bool replay));
#endif
+
void tevent_trace_point_callback(struct tevent_context *ev,
enum tevent_trace_point);
diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c
index 5479f2f..89b3bbc 100644
--- a/lib/tevent/tevent_poll.c
+++ b/lib/tevent/tevent_poll.c
@@ -256,6 +256,22 @@ static void poll_event_schedule_immediate(struct tevent_immediate *im,
}
/*
+ Private function called by "standard" backend fallback.
+ Note this only allows fallback to "poll" backend, not "poll-mt".
+*/
+_PRIVATE_ void tevent_poll_event_add_fd_internal(struct tevent_context *ev,
+ struct tevent_fd *fde)
+{
+ struct poll_event_context *poll_ev = talloc_get_type_abort(
+ ev->additional_data, struct poll_event_context);
+
+ fde->additional_flags = UINT64_MAX;
+ fde->additional_data = NULL;
+ DLIST_ADD(poll_ev->fresh, fde);
+ talloc_set_destructor(fde, poll_fresh_fde_destructor);
+}
+
+/*
add a fd based event
return NULL on failure (memory allocation error)
*/
diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c
index c11f0e8..7e0c927 100644
--- a/lib/tevent/tevent_select.c
+++ b/lib/tevent/tevent_select.c
@@ -47,6 +47,12 @@ 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;
diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c
index 1e33720..d7a5bd7 100644
--- a/lib/tevent/tevent_standard.c
+++ b/lib/tevent/tevent_standard.c
@@ -1,8 +1,8 @@
/*
Unix SMB/CIFS implementation.
main select loop and event handling
- Copyright (C) Andrew Tridgell 2003-2005
- Copyright (C) Stefan Metzmacher 2005-2009
+ Copyright (C) Stefan Metzmacher 2013
+ 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
@@ -26,567 +26,192 @@
This is SAMBA's default event loop code
- we try to use epoll if configure detected support for it
- otherwise we use select()
+ otherwise we use poll()
- if epoll is broken on the system or the kernel doesn't support it
- at runtime we fallback to select()
+ at runtime we fallback to poll()
*/
#include "replace.h"
-#include "system/filesys.h"
-#include "system/select.h"
#include "tevent.h"
#include "tevent_util.h"
#include "tevent_internal.h"
-struct std_event_context {
- /* a pointer back to the generic event_context */
- struct tevent_context *ev;
-
- /* the maximum file descriptor number in fd_events */
- int maxfd;
-
- /* information for exiting from the event loop */
- int exit_code;
-
- /* when using epoll this is the handle from epoll_create */
- int epoll_fd;
-
- /* our pid at the time the epoll_fd was created */
- pid_t pid;
+struct std_event_glue {
+ const struct tevent_ops *epoll_ops;
+ const struct tevent_ops *poll_ops;
+ struct tevent_ops *glue_ops;
+ bool fallback_replay;
};
-/* use epoll if it is available */
-#if HAVE_EPOLL
-/*
- called when a epoll call fails, and we should fallback
- to using select
-*/
-static void epoll_fallback_to_select(struct std_event_context *std_ev, const char *reason)
-{
- tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
- "%s (%s) - falling back to select()\n",
- reason, strerror(errno));
- close(std_ev->epoll_fd);
- std_ev->epoll_fd = -1;
- talloc_set_destructor(std_ev, NULL);
-}
-
-/*
- map from TEVENT_FD_* to EPOLLIN/EPOLLOUT
-*/
-static uint32_t epoll_map_flags(uint16_t flags)
-{
- uint32_t ret = 0;
- if (flags & TEVENT_FD_READ) ret |= (EPOLLIN | EPOLLERR | EPOLLHUP);
- if (flags & TEVENT_FD_WRITE) ret |= (EPOLLOUT | EPOLLERR | EPOLLHUP);
- return ret;
-}
+static int std_event_context_init(struct tevent_context *ev);
-/*
- free the epoll fd
-*/
-static int epoll_ctx_destructor(struct std_event_context *std_ev)
-{
- if (std_ev->epoll_fd != -1) {
- close(std_ev->epoll_fd);
- }
- std_ev->epoll_fd = -1;
- return 0;
-}
+static const struct tevent_ops std_event_ops = {
+ .context_init = std_event_context_init,
+};
/*
- init the epoll fd
+ If this function gets called. epoll failed at runtime.
+ Move us to using poll instead. If we return false here,
+ caller should abort().
*/
-static void epoll_init_ctx(struct std_event_context *std_ev)
-{
- std_ev->epoll_fd = epoll_create(64);
- if (std_ev->epoll_fd == -1) {
- tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
- "Failed to create epoll handle.\n");
- return;
- }
-
- if (!ev_set_close_on_exec(std_ev->epoll_fd)) {
- tevent_debug(std_ev->ev, TEVENT_DEBUG_WARNING,
- "Failed to set close-on-exec, file descriptor may be leaked to children.\n");
- }
-
- std_ev->pid = getpid();
- talloc_set_destructor(std_ev, epoll_ctx_destructor);
-}
-
-static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *fde);
-
-/*
- reopen the epoll handle when our pid changes
- see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
- demonstration of why this is needed
- */
-static void epoll_check_reopen(struct std_event_context *std_ev)
+static bool std_fallback_to_poll(struct tevent_context *ev, bool replay)
{
+ void *glue_ptr = talloc_parent(ev->ops);
+ struct std_event_glue *glue =
+ talloc_get_type_abort(glue_ptr,
+ struct std_event_glue);
+ int ret;
struct tevent_fd *fde;
+ struct tevent_fd *fde_next;
- if (std_ev->pid == getpid()) {
- return;
- }
+ glue->fallback_replay = replay;
- close(std_ev->epoll_fd);
- std_ev->epoll_fd = epoll_create(64);
- if (std_ev->epoll_fd == -1) {
- tevent_debug(std_ev->ev, TEVENT_DEBUG_FATAL,
- "Failed to recreate epoll handle after fork\n");
- return;
- }
+ /* First switch all the ops to poll. */
+ glue->epoll_ops = NULL;
+ TALLOC_FREE(ev->additional_data);
- if (!ev_set_close_on_exec(std_ev->epoll_fd)) {
- tevent_debug(std_ev->ev, TEVENT_DEBUG_WARNING,
- "Failed to set close-on-exec, file descriptor may be leaked to children.\n");
- }
+ /*
+ * Set custom_ops the same as poll.
+ */
+ *glue->glue_ops = *glue->poll_ops;
+ glue->glue_ops->context_init = std_event_context_init;
- std_ev->pid = getpid();
- for (fde=std_ev->ev->fd_events;fde;fde=fde->next) {
- epoll_add_event(std_ev, fde);
+ /* Next initialize the poll backend. */
+ ret = glue->poll_ops->context_init(ev);
+ if (ret != 0) {
+ return false;
}
-}
-#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
-#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
-#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
-
-/*
- add the epoll event to the given fd_event
-*/
-static void epoll_add_event(struct std_event_context *std_ev, struct tevent_fd *fde)
-{
- struct epoll_event event;
- if (std_ev->epoll_fd == -1) return;
-
- fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
-
- /* if we don't want events yet, don't add an epoll_event */
- if (fde->flags == 0) return;
+ /*
+ * Now we have to change all the existing file descriptor
+ * events from the epoll backend to the poll backend.
+ */
+ for (fde = ev->fd_events; fde; fde = fde_next) {
+ /*
+ * We must remove this fde off the ev->fd_events list.
+ */
+ fde_next = fde->next;
- ZERO_STRUCT(event);
- event.events = epoll_map_flags(fde->flags);
- event.data.ptr = fde;
- if (epoll_ctl(std_ev->epoll_fd, EPOLL_CTL_ADD, fde->fd, &event) != 0) {
- epoll_fallback_to_select(std_ev, "EPOLL_CTL_ADD failed");
- }
- fde->additional_flags |= EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT;
+ /* Remove from the ev->fd_events list. */
+ DLIST_REMOVE(ev->fd_events, fde);
- /* only if we want to read we want to tell the event handler about errors */
--
Samba Shared Repository
More information about the samba-cvs
mailing list