summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-01-17 12:59:14 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:17:13 -0500
commitbf219447a35d86913c1a643b66d993986a651360 (patch)
treeabd6650e6694233de6d6f8e197a03b513ecaec56 /source3
parent60c1a8e5a8f905a5ae703dac05ed2f440875ad5d (diff)
downloadsamba-bf219447a35d86913c1a643b66d993986a651360.tar.gz
samba-bf219447a35d86913c1a643b66d993986a651360.tar.bz2
samba-bf219447a35d86913c1a643b66d993986a651360.zip
r20846: Before this gets out of control...
This add a struct event_context and infrastructure for fd events to smbd. This is step zero to import lib/events. Jeremy, I rely on you to watch the change in receive_message_or_smb() closely. For the normal code path this should be the only relevant change. The rest is either not yet used or is cosmetic. Volker (This used to be commit cd07f93a8aecb24c056e33b1ad3447a41959810f)
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[])