summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/event.h17
-rw-r--r--source3/lib/events.c219
-rw-r--r--source3/nsswitch/winbindd.c14
-rw-r--r--source3/nsswitch/winbindd_cm.c32
-rw-r--r--source3/nsswitch/winbindd_cred_cache.c16
-rw-r--r--source3/nsswitch/winbindd_dual.c16
-rw-r--r--source3/smbd/oplock.c5
-rw-r--r--source3/smbd/process.c65
-rw-r--r--source3/smbd/server.c10
-rw-r--r--source3/torture/vfstest.c10
10 files changed, 314 insertions, 90 deletions
diff --git a/source3/include/event.h b/source3/include/event.h
index fdb990678d..f3c468c9b8 100644
--- a/source3/include/event.h
+++ b/source3/include/event.h
@@ -19,13 +19,12 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-struct timed_event {
- struct timed_event *next, *prev;
- struct timeval when;
- const char *event_name;
- void (*handler)(struct timed_event *te,
- const struct timeval *now,
- void *private_data);
- void *private_data;
-};
+struct event_context;
+struct timed_event;
+
+struct fd_event;
+
+/* bits for file descriptor event flags */
+#define EVENT_FD_READ 1
+#define EVENT_FD_WRITE 2
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 66aefa3b52..ef52faef01 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -21,13 +21,50 @@
#include "includes.h"
-static struct timed_event *timed_events;
+struct timed_event {
+ struct timed_event *next, *prev;
+ struct event_context *event_ctx;
+ struct timeval when;
+ const char *event_name;
+ void (*handler)(struct event_context *event_ctx,
+ struct timed_event *te,
+ const struct timeval *now,
+ void *private_data);
+ void *private_data;
+};
+
+struct fd_event {
+ struct fd_event *prev, *next;
+ struct event_context *event_ctx;
+ int fd;
+ uint16_t flags; /* see EVENT_FD_* flags */
+ void (*handler)(struct event_context *event_ctx,
+ struct fd_event *event,
+ uint16 flags,
+ void *private_data);
+ void *private_data;
+};
+
+#define EVENT_FD_WRITEABLE(fde) \
+ event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_WRITE)
+#define EVENT_FD_READABLE(fde) \
+ event_set_fd_flags(fde, event_get_fd_flags(fde) | EVENT_FD_READ)
+
+#define EVENT_FD_NOT_WRITEABLE(fde) \
+ event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_WRITE)
+#define EVENT_FD_NOT_READABLE(fde) \
+ event_set_fd_flags(fde, event_get_fd_flags(fde) & ~EVENT_FD_READ)
+
+struct event_context {
+ struct timed_event *timed_events;
+ struct fd_event *fd_events;
+};
static int timed_event_destructor(struct timed_event *te)
{
DEBUG(10, ("Destroying timed event %lx \"%s\"\n", (unsigned long)te,
te->event_name));
- DLIST_REMOVE(timed_events, te);
+ DLIST_REMOVE(te->event_ctx->timed_events, te);
return 0;
}
@@ -37,10 +74,12 @@ static int timed_event_destructor(struct timed_event *te)
handed to it.
****************************************************************************/
-struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
+struct timed_event *event_add_timed(struct event_context *event_ctx,
+ TALLOC_CTX *mem_ctx,
struct timeval when,
const char *event_name,
- void (*handler)(struct timed_event *te,
+ void (*handler)(struct event_context *event_ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data),
void *private_data)
@@ -53,6 +92,7 @@ struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
return NULL;
}
+ te->event_ctx = event_ctx;
te->when = when;
te->event_name = event_name;
te->handler = handler;
@@ -61,16 +101,16 @@ struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
/* keep the list ordered - this is NOT guarenteed as event times
may be changed after insertion */
last_te = NULL;
- for (cur_te = timed_events; cur_te; cur_te = cur_te->next) {
+ for (cur_te = event_ctx->timed_events; cur_te; cur_te = cur_te->next) {
/* if the new event comes before the current one break */
- if (!timeval_is_zero(&cur_te->when) &&
- timeval_compare(&te->when, &cur_te->when) < 0) {
+ if (!timeval_is_zero(&cur_te->when)
+ && timeval_compare(&te->when, &cur_te->when) < 0) {
break;
}
last_te = cur_te;
}
- DLIST_ADD_AFTER(timed_events, te, last_te);
+ DLIST_ADD_AFTER(event_ctx->timed_events, te, last_te);
talloc_set_destructor(te, timed_event_destructor);
DEBUG(10, ("Added timed event \"%s\": %lx\n", event_name,
@@ -78,38 +118,166 @@ struct timed_event *add_timed_event(TALLOC_CTX *mem_ctx,
return te;
}
-void run_events(void)
+static int fd_event_destructor(struct fd_event *fde)
+{
+ struct event_context *event_ctx = fde->event_ctx;
+
+ DLIST_REMOVE(event_ctx->fd_events, fde);
+ return 0;
+}
+
+struct fd_event *event_add_fd(struct event_context *event_ctx,
+ TALLOC_CTX *mem_ctx,
+ int fd, uint16_t flags,
+ void (*handler)(struct event_context *event_ctx,
+ struct fd_event *event,
+ uint16 flags,
+ void *private_data),
+ void *private_data)
+{
+ struct fd_event *fde;
+
+ if (!(fde = TALLOC_P(mem_ctx, struct fd_event))) {
+ return NULL;
+ }
+
+ fde->event_ctx = event_ctx;
+ fde->fd = fd;
+ fde->flags = flags;
+ fde->handler = handler;
+ fde->private_data = private_data;
+
+ DLIST_ADD(event_ctx->fd_events, fde);
+
+ talloc_set_destructor(fde, fd_event_destructor);
+ return fde;
+}
+
+void event_fd_set_writeable(struct fd_event *fde)
+{
+ fde->flags |= EVENT_FD_WRITE;
+}
+
+void event_fd_set_not_writeable(struct fd_event *fde)
+{
+ fde->flags &= ~EVENT_FD_WRITE;
+}
+
+void event_fd_set_readable(struct fd_event *fde)
+{
+ fde->flags |= EVENT_FD_READ;
+}
+
+void event_fd_set_not_readable(struct fd_event *fde)
+{
+ fde->flags &= ~EVENT_FD_READ;
+}
+
+void event_add_to_select_args(struct event_context *event_ctx,
+ const struct timeval *now,
+ fd_set *read_fds, fd_set *write_fds,
+ struct timeval *timeout, int *maxfd)
{
+ struct fd_event *fde;
+ struct timeval diff;
+
+ for (fde = event_ctx->fd_events; fde; fde = fde->next) {
+ if (fde->flags & EVENT_FD_READ) {
+ FD_SET(fde->fd, read_fds);
+ }
+ if (fde->flags & EVENT_FD_WRITE) {
+ FD_SET(fde->fd, write_fds);
+ }
+
+ if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
+ && (fde->fd > *maxfd)) {
+ *maxfd = fde->fd;
+ }
+ }
+
+ if (event_ctx->timed_events == NULL) {
+ return;
+ }
+
+ diff = timeval_until(now, &event_ctx->timed_events->when);
+ *timeout = timeval_min(timeout, &diff);
+}
+
+BOOL run_events(struct event_context *event_ctx,
+ int selrtn, fd_set *read_fds, fd_set *write_fds)
+{
+ BOOL fired = False;
+ struct fd_event *fde, *next;
+
/* Run all events that are pending, not just one (as we
did previously. */
- while (timed_events) {
+ while (event_ctx->timed_events) {
struct timeval now;
GetTimeOfDay(&now);
- if (timeval_compare(&now, &timed_events->when) < 0) {
+ if (timeval_compare(
+ &now, &event_ctx->timed_events->when) < 0) {
/* Nothing to do yet */
DEBUG(11, ("run_events: Nothing to do\n"));
- return;
+ break;
}
- DEBUG(10, ("Running event \"%s\" %lx\n", timed_events->event_name,
- (unsigned long)timed_events));
+ DEBUG(10, ("Running event \"%s\" %lx\n",
+ event_ctx->timed_events->event_name,
+ (unsigned long)event_ctx->timed_events));
+
+ event_ctx->timed_events->handler(
+ event_ctx,
+ event_ctx->timed_events, &now,
+ event_ctx->timed_events->private_data);
- timed_events->handler(timed_events, &now, timed_events->private_data);
+ fired = True;
}
+
+ if (fired) {
+ /*
+ * We might have changed the socket status during the timed
+ * events, return to run select again.
+ */
+ return True;
+ }
+
+ if (selrtn == 0) {
+ /*
+ * No fd ready
+ */
+ return fired;
+ }
+
+ for (fde = event_ctx->fd_events; fde; fde = next) {
+ uint16 flags = 0;
+
+ next = fde->next;
+ if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
+ if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
+
+ if (flags) {
+ fde->handler(event_ctx, fde, flags, fde->private_data);
+ fired = True;
+ }
+ }
+
+ return fired;
}
-struct timeval *get_timed_events_timeout(struct timeval *to_ret)
+
+struct timeval *get_timed_events_timeout(struct event_context *event_ctx,
+ struct timeval *to_ret)
{
struct timeval now;
- if (timed_events == NULL) {
+ if (event_ctx->timed_events == NULL) {
return NULL;
}
now = timeval_current();
- *to_ret = timeval_until(&now, &timed_events->when);
+ *to_ret = timeval_until(&now, &event_ctx->timed_events->when);
DEBUG(10, ("timed_events_timeout: %d/%d\n", (int)to_ret->tv_sec,
(int)to_ret->tv_usec));
@@ -117,12 +285,18 @@ struct timeval *get_timed_events_timeout(struct timeval *to_ret)
return to_ret;
}
-int set_event_dispatch_time(const char *event_name, struct timeval when)
+struct event_context *event_context_init(TALLOC_CTX *mem_ctx)
+{
+ return TALLOC_ZERO_P(NULL, struct event_context);
+}
+
+int set_event_dispatch_time(struct event_context *event_ctx,
+ const char *event_name, struct timeval when)
{
int num_events = 0;
struct timed_event *te;
- for (te = timed_events; te; te = te->next) {
+ for (te = event_ctx->timed_events; te; te = te->next) {
if (strcmp(event_name, te->event_name) == 0) {
te->when = when;
num_events++;
@@ -133,11 +307,12 @@ int set_event_dispatch_time(const char *event_name, struct timeval when)
/* Returns 1 if event was found and cancelled, 0 otherwise. */
-int cancel_named_event(const char *event_name)
+int cancel_named_event(struct event_context *event_ctx,
+ const char *event_name)
{
struct timed_event *te;
- for (te = timed_events; te; te = te->next) {
+ for (te = event_ctx->timed_events; te; te = te->next) {
if (strcmp(event_name, te->event_name) == 0) {
TALLOC_FREE(te);
return 1;
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index 049bc47aba..1a3e761adc 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -34,6 +34,16 @@ static BOOL interactive = False;
extern BOOL override_logfile;
+struct event_context *winbind_event_context(void)
+{
+ static struct event_context *ctx;
+
+ if (!ctx && !(ctx = event_context_init(NULL))) {
+ smb_panic("Could not init smbd event context\n");
+ }
+ return ctx;
+}
+
/* Reload configuration */
static BOOL reload_services_file(void)
@@ -716,7 +726,7 @@ static void process_loop(void)
message_dispatch();
- run_events();
+ run_events(winbind_event_context(), 0, NULL, NULL);
/* refresh the trusted domain cache */
@@ -748,7 +758,7 @@ static void process_loop(void)
timeout.tv_usec = 0;
/* Check for any event timeouts. */
- if (get_timed_events_timeout(&ev_timeout)) {
+ if (get_timed_events_timeout(winbind_event_context(), &ev_timeout)) {
timeout = timeval_min(&timeout, &ev_timeout);
}
diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c
index 3f61da12dc..19b60c1c17 100644
--- a/source3/nsswitch/winbindd_cm.c
+++ b/source3/nsswitch/winbindd_cm.c
@@ -231,7 +231,8 @@ static BOOL fork_child_dc_connect(struct winbindd_domain *domain)
Handler triggered if we're offline to try and detect a DC.
****************************************************************/
-static void check_domain_online_handler(struct timed_event *te,
+static void check_domain_online_handler(struct event_context *ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -327,7 +328,7 @@ void set_domain_offline(struct winbindd_domain *domain)
calc_new_online_timeout_check(domain);
- domain->check_online_event = add_timed_event( NULL,
+ domain->check_online_event = event_add_timed(winbind_event_context(), NULL,
timeval_current_ofs(domain->check_online_timeout,0),
"check_domain_online_handler",
check_domain_online_handler,
@@ -367,7 +368,8 @@ static void set_domain_online(struct winbindd_domain *domain)
/* If we are waiting to get a krb5 ticket, trigger immediately. */
GetTimeOfDay(&now);
- set_event_dispatch_time("krb5_ticket_gain_handler", now);
+ set_event_dispatch_time(winbind_event_context(),
+ "krb5_ticket_gain_handler", now);
/* Ok, we're out of any startup mode now... */
domain->startup = False;
@@ -432,18 +434,10 @@ void set_domain_online_request(struct winbindd_domain *domain)
DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
domain->name ));
- domain->check_online_event = add_timed_event( NULL,
- timeval_current_ofs(5, 0),
- "check_domain_online_handler",
- check_domain_online_handler,
- domain);
-
- /* The above *has* to succeed for winbindd to work. */
- if (!domain->check_online_event) {
- smb_panic("set_domain_online_request: failed to add online handler.\n");
- }
}
+ TALLOC_FREE(domain->check_online_event);
+
GetTimeOfDay(&tev);
/* Go into "startup" mode again. */
@@ -451,7 +445,17 @@ void set_domain_online_request(struct winbindd_domain *domain)
domain->startup = True;
tev.tv_sec += 5;
- set_event_dispatch_time("check_domain_online_handler", tev);
+
+ domain->check_online_event = event_add_timed(
+ winbind_event_context(), NULL, tev,
+ "check_domain_online_handler",
+ check_domain_online_handler,
+ domain);
+
+ /* The above *has* to succeed for winbindd to work. */
+ if (!domain->check_online_event) {
+ smb_panic("set_domain_online_request: failed to add online handler.\n");
+ }
}
/****************************************************************
diff --git a/source3/nsswitch/winbindd_cred_cache.c b/source3/nsswitch/winbindd_cred_cache.c
index 6f629ad15c..50d39dd670 100644
--- a/source3/nsswitch/winbindd_cred_cache.c
+++ b/source3/nsswitch/winbindd_cred_cache.c
@@ -66,7 +66,8 @@ static int ccache_entry_count(void)
Do the work of refreshing the ticket.
****************************************************************/
-static void krb5_ticket_refresh_handler(struct timed_event *te,
+static void krb5_ticket_refresh_handler(struct event_context *event_ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -145,7 +146,7 @@ static void krb5_ticket_refresh_handler(struct timed_event *te,
done:
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set(new_start, 0),
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
@@ -158,7 +159,8 @@ done:
Do the work of regaining a ticket when coming from offline auth.
****************************************************************/
-static void krb5_ticket_gain_handler(struct timed_event *te,
+static void krb5_ticket_gain_handler(struct event_context *event_ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -220,7 +222,7 @@ static void krb5_ticket_gain_handler(struct timed_event *te,
retry_later:
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
@@ -236,7 +238,7 @@ static void krb5_ticket_gain_handler(struct timed_event *te,
t = timeval_set(new_start, 0);
#endif /* TESTING */
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
t,
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
@@ -349,13 +351,13 @@ NTSTATUS add_ccache_to_list(const char *princ_name,
if (lp_winbind_refresh_tickets() && renew_until > 0) {
if (postponed_request) {
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0),
"krb5_ticket_gain_handler",
krb5_ticket_gain_handler,
entry);
} else {
- entry->event = add_timed_event(entry,
+ entry->event = event_add_timed(winbind_event_context(), entry,
timeval_set((ticket_end - 1), 0),
"krb5_ticket_refresh_handler",
krb5_ticket_refresh_handler,
diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c
index b72b7238b1..62193c0b69 100644
--- a/source3/nsswitch/winbindd_dual.c
+++ b/source3/nsswitch/winbindd_dual.c
@@ -598,7 +598,8 @@ void winbind_msg_onlinestatus(int msg_type, struct process_id src, void *buf, si
}
-static void account_lockout_policy_handler(struct timed_event *te,
+static void account_lockout_policy_handler(struct event_context *ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -631,7 +632,7 @@ static void account_lockout_policy_handler(struct timed_event *te,
nt_errstr(result)));
}
- child->lockout_policy_event = add_timed_event(NULL,
+ child->lockout_policy_event = event_add_timed(winbind_event_context(), NULL,
timeval_current_ofs(3600, 0),
"account_lockout_policy_handler",
account_lockout_policy_handler,
@@ -843,8 +844,8 @@ static BOOL fork_domain_child(struct winbindd_child *child)
if (child->domain != NULL && lp_winbind_offline_logon()) {
/* We might be in the idmap child...*/
- child->lockout_policy_event = add_timed_event(
- NULL, timeval_zero(),
+ child->lockout_policy_event = event_add_timed(
+ winbind_event_context(), NULL, timeval_zero(),
"account_lockout_policy_handler",
account_lockout_policy_handler,
child);
@@ -874,7 +875,8 @@ static BOOL fork_domain_child(struct winbindd_child *child)
/* Ensure we're not handling an event inherited from
our parent. */
- cancel_named_event("krb5_ticket_refresh_handler");
+ cancel_named_event(winbind_event_context(),
+ "krb5_ticket_refresh_handler");
while (1) {
@@ -888,7 +890,7 @@ static BOOL fork_domain_child(struct winbindd_child *child)
lp_TALLOC_FREE();
main_loop_TALLOC_FREE();
- run_events();
+ run_events(winbind_event_context(), 0, NULL, NULL);
GetTimeOfDay(&now);
@@ -900,7 +902,7 @@ static BOOL fork_domain_child(struct winbindd_child *child)
child->domain->startup = False;
}
- tp = get_timed_events_timeout(&t);
+ tp = get_timed_events_timeout(winbind_event_context(), &t);
if (tp) {
DEBUG(11,("select will use timeout of %u.%u seconds\n",
(unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index 427fb7f245..1f73ea837d 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -342,7 +342,8 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, un
return fsp;
}
-static void oplock_timeout_handler(struct timed_event *te,
+static void oplock_timeout_handler(struct event_context *ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -372,7 +373,7 @@ static void add_oplock_timeout_handler(files_struct *fsp)
}
fsp->oplock_timeout =
- add_timed_event(NULL,
+ event_add_timed(smbd_event_context(), NULL,
timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
"oplock_timeout_handler",
oplock_timeout_handler, fsp);
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 929471a48c..2a52da12b3 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -225,7 +225,8 @@ struct idle_event {
void *private_data;
};
-static void idle_event_handler(struct timed_event *te,
+static void idle_event_handler(struct event_context *ctx,
+ struct timed_event *te,
const struct timeval *now,
void *private_data)
{
@@ -240,7 +241,8 @@ static void idle_event_handler(struct timed_event *te,
return;
}
- event->te = add_timed_event(event, timeval_sum(now, &event->interval),
+ event->te = event_add_timed(smbd_event_context(), event,
+ timeval_sum(now, &event->interval),
"idle_event_handler",
idle_event_handler, event);
@@ -267,11 +269,12 @@ struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
result->handler = handler;
result->private_data = private_data;
- result->te = add_timed_event(result, timeval_sum(&now, &interval),
+ result->te = event_add_timed(smbd_event_context(), result,
+ timeval_sum(&now, &interval),
"idle_event_handler",
idle_event_handler, result);
if (result->te == NULL) {
- DEBUG(0, ("add_timed_event failed\n"));
+ DEBUG(0, ("event_add_timed failed\n"));
TALLOC_FREE(result);
return NULL;
}
@@ -350,7 +353,7 @@ The timeout is in milliseconds
static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
{
- fd_set fds;
+ fd_set r_fds, w_fds;
int selrtn;
struct timeval to;
int maxfd = 0;
@@ -414,10 +417,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
}
/*
- * Setup the select read fd set.
+ * Setup the select fd sets.
*/
- FD_ZERO(&fds);
+ FD_ZERO(&r_fds);
+ FD_ZERO(&w_fds);
/*
* Ensure we process oplock break messages by preference.
@@ -428,9 +432,9 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
* This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
*/
- if (oplock_message_waiting(&fds)) {
+ if (oplock_message_waiting(&r_fds)) {
DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
- async_processing(&fds);
+ async_processing(&r_fds);
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -445,15 +449,17 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
*/
{
- struct timeval tmp;
- struct timeval *tp = get_timed_events_timeout(&tmp);
-
- if (tp) {
- to = timeval_min(&to, tp);
- if (timeval_is_zero(&to)) {
- /* Process a timed event now... */
- run_events();
- }
+ struct timeval now;
+ GetTimeOfDay(&now);
+
+ event_add_to_select_args(smbd_event_context(), &now,
+ &r_fds, &w_fds, &to, &maxfd);
+ }
+
+ if (timeval_is_zero(&to)) {
+ /* Process a timed event now... */
+ if (run_events(smbd_event_context(), 0, NULL, NULL)) {
+ goto again;
}
}
@@ -461,23 +467,27 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
int sav;
START_PROFILE(smbd_idle);
- maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds);
- maxfd = select_on_fd(change_notify_fd(), maxfd, &fds);
- maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds);
+ maxfd = select_on_fd(smbd_server_fd(), maxfd, &r_fds);
+ maxfd = select_on_fd(change_notify_fd(), maxfd, &r_fds);
+ maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds);
- selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to);
+ selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
sav = errno;
END_PROFILE(smbd_idle);
errno = sav;
}
+ if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
+ goto again;
+ }
+
/* if we get EINTR then maybe we have received an oplock
signal - treat this as select returning 1. This is ugly, but
is the best we can do until the oplock code knows more about
signals */
if (selrtn == -1 && errno == EINTR) {
- async_processing(&fds);
+ async_processing(&r_fds);
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -505,8 +515,8 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
* sending us an oplock break message. JRA.
*/
- if (oplock_message_waiting(&fds)) {
- async_processing(&fds);
+ if (oplock_message_waiting(&r_fds)) {
+ async_processing(&r_fds);
/*
* After async processing we must go and do the select again, as
* the state of the flag in fds for the server file descriptor is
@@ -515,7 +525,8 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
goto again;
}
- if ((change_notify_fd() >= 0) && FD_ISSET(change_notify_fd(), &fds)) {
+ if ((change_notify_fd() >= 0) && FD_ISSET(change_notify_fd(),
+ &r_fds)) {
process_pending_change_notify_queue((time_t)0);
@@ -1603,7 +1614,7 @@ void smbd_process(void)
num_smbs = 0; /* Reset smb counter. */
}
- run_events();
+ run_events(smbd_event_context(), 0, NULL, NULL);
#if defined(DEVELOPER)
clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 5ee9320fb3..4a242488da 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -61,6 +61,16 @@ static void smbd_set_server_fd(int fd)
client_setfd(fd);
}
+struct event_context *smbd_event_context(void)
+{
+ static struct event_context *ctx;
+
+ if (!ctx && !(ctx = event_context_init(NULL))) {
+ smb_panic("Could not init smbd event context\n");
+ }
+ return ctx;
+}
+
/*******************************************************************
What to do when smb.conf is updated.
********************************************************************/
diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c
index fa0545988e..f9a01a3e91 100644
--- a/source3/torture/vfstest.c
+++ b/source3/torture/vfstest.c
@@ -479,6 +479,16 @@ BOOL reload_services(BOOL test)
return (ret);
}
+struct event_context *smbd_event_context(void)
+{
+ static struct event_context *ctx;
+
+ if (!ctx && !(ctx = event_context_init(NULL))) {
+ smb_panic("Could not init smbd event context\n");
+ }
+ return ctx;
+}
+
/* Main function */
int main(int argc, char *argv[])