r20846: Before this gets out of control...
authorVolker Lendecke <vlendec@samba.org>
Wed, 17 Jan 2007 12:59:14 +0000 (12:59 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:17:13 +0000 (12:17 -0500)
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)

source3/include/event.h
source3/lib/events.c
source3/nsswitch/winbindd.c
source3/nsswitch/winbindd_cm.c
source3/nsswitch/winbindd_cred_cache.c
source3/nsswitch/winbindd_dual.c
source3/smbd/oplock.c
source3/smbd/process.c
source3/smbd/server.c
source3/torture/vfstest.c

index fdb990678db4489a3e7529b0bfea99156ba007f9..f3c468c9b8d454b2d1b8caaeab980d7c217c991b 100644 (file)
    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
 
index 66aefa3b52dfb1cea413ef3248403b6da4ec3d5d..ef52faef01faa659d0d487219366d070430a1301 100644 (file)
 
 #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;
index 049bc47abac47034aa38de8b52464539beeb8936..1a3e761adcb072612715e0df598d48c7d3eaacb1 100644 (file)
@@ -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);
        }
 
index 3f61da12dc724026368a8cea3c089b1737a038f3..19b60c1c1731ffd3eaa7e3dbd721c3dd79729fd9 100644 (file)
@@ -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");
+       }
 }
 
 /****************************************************************
index 6f629ad15c212603322dead5148a4797b18a5ae4..50d39dd670b6ebe22b557707c57922f552723dfe 100644 (file)
@@ -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,
index b72b7238b1f2698374e2dbe3a066e9f55737d8c0..62193c0b69dc95af19534c78b78a0bf36dfaf5a7 100644 (file)
@@ -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 ));
index 427fb7f24502f259a2148aadbcaa6a03f5752873..1f73ea837da03208f40570f0d8aa69d85d4720d1 100644 (file)
@@ -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);
index 929471a48c21bc73113468364f922a8b8c771596..2a52da12b38810543ca6497d4f136316aa2f8a9c 100644 (file)
@@ -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);
index 5ee9320fb3607a8477237b78681f3adc8ac30c68..4a242488daa1ab321e4c7ee0ba20417cafcc3ee8 100644 (file)
@@ -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.
  ********************************************************************/
index fa0545988e9eb3064844db8e16e5ec333f0eac3c..f9a01a3e91c9f37155f775031078b0d469b105a7 100644 (file)
@@ -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[])