Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/lib/events.c

    r594 r740  
    2020
    2121#include "includes.h"
    22 #include <tevent_internal.h>
    23 
    24 void event_fd_set_writeable(struct tevent_fd *fde)
    25 {
    26         TEVENT_FD_WRITEABLE(fde);
    27 }
    28 
    29 void event_fd_set_not_writeable(struct tevent_fd *fde)
    30 {
    31         TEVENT_FD_NOT_WRITEABLE(fde);
    32 }
    33 
    34 void event_fd_set_readable(struct tevent_fd *fde)
    35 {
    36         TEVENT_FD_READABLE(fde);
    37 }
    38 
    39 void event_fd_set_not_readable(struct tevent_fd *fde)
    40 {
    41         TEVENT_FD_NOT_READABLE(fde);
    42 }
    43 
    44 /*
    45  * Return if there's something in the queue
    46  */
    47 
    48 bool event_add_to_select_args(struct tevent_context *ev,
    49                               const struct timeval *now,
    50                               fd_set *read_fds, fd_set *write_fds,
    51                               struct timeval *timeout, int *maxfd)
     22#include "lib/tevent/tevent_internal.h"
     23#include "../lib/util/select.h"
     24#include "system/select.h"
     25
     26struct tevent_poll_private {
     27        /*
     28         * Index from file descriptor into the pollfd array
     29         */
     30        int *pollfd_idx;
     31
     32        /*
     33         * Cache for s3_event_loop_once to avoid reallocs
     34         */
     35        struct pollfd *pfds;
     36};
     37
     38static struct tevent_poll_private *tevent_get_poll_private(
     39        struct tevent_context *ev)
     40{
     41        struct tevent_poll_private *state;
     42
     43        state = (struct tevent_poll_private *)ev->additional_data;
     44        if (state == NULL) {
     45                state = TALLOC_ZERO_P(ev, struct tevent_poll_private);
     46                ev->additional_data = (void *)state;
     47                if (state == NULL) {
     48                        DEBUG(10, ("talloc failed\n"));
     49                }
     50        }
     51        return state;
     52}
     53
     54static void count_fds(struct tevent_context *ev,
     55                      int *pnum_fds, int *pmax_fd)
    5256{
    5357        struct tevent_fd *fde;
    54         struct timeval diff;
    55         bool ret = false;
     58        int num_fds = 0;
     59        int max_fd = 0;
     60
     61        for (fde = ev->fd_events; fde != NULL; fde = fde->next) {
     62                if (fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) {
     63                        num_fds += 1;
     64                        if (fde->fd > max_fd) {
     65                                max_fd = fde->fd;
     66                        }
     67                }
     68        }
     69        *pnum_fds = num_fds;
     70        *pmax_fd = max_fd;
     71}
     72
     73bool event_add_to_poll_args(struct tevent_context *ev, TALLOC_CTX *mem_ctx,
     74                            struct pollfd **pfds, int *pnum_pfds,
     75                            int *ptimeout)
     76{
     77        struct tevent_poll_private *state;
     78        struct tevent_fd *fde;
     79        int i, num_fds, max_fd, num_pollfds, idx_len;
     80        struct pollfd *fds;
     81        struct timeval now, diff;
     82        int timeout;
     83
     84        state = tevent_get_poll_private(ev);
     85        if (state == NULL) {
     86                return false;
     87        }
     88        count_fds(ev, &num_fds, &max_fd);
     89
     90        idx_len = max_fd+1;
     91
     92        if (talloc_array_length(state->pollfd_idx) < idx_len) {
     93                state->pollfd_idx = TALLOC_REALLOC_ARRAY(
     94                        state, state->pollfd_idx, int, idx_len);
     95                if (state->pollfd_idx == NULL) {
     96                        DEBUG(10, ("talloc_realloc failed\n"));
     97                        return false;
     98                }
     99        }
     100
     101        fds = *pfds;
     102        num_pollfds = *pnum_pfds;
     103
     104        /*
     105         * The +1 is for the sys_poll calling convention. It expects
     106         * an array 1 longer for the signal pipe
     107         */
     108
     109        if (talloc_array_length(fds) < num_pollfds + num_fds + 1) {
     110                fds = TALLOC_REALLOC_ARRAY(mem_ctx, fds, struct pollfd,
     111                                           num_pollfds + num_fds + 1);
     112                if (fds == NULL) {
     113                        DEBUG(10, ("talloc_realloc failed\n"));
     114                        return false;
     115                }
     116        }
     117
     118        memset(&fds[num_pollfds], 0, sizeof(struct pollfd) * num_fds);
     119
     120        /*
     121         * This needs tuning. We need to cope with multiple fde's for a file
     122         * descriptor. The problem is that we need to re-use pollfd_idx across
     123         * calls for efficiency. One way would be a direct bitmask that might
     124         * be initialized quicker, but our bitmap_init implementation is
     125         * pretty heavy-weight as well.
     126         */
     127        for (i=0; i<idx_len; i++) {
     128                state->pollfd_idx[i] = -1;
     129        }
    56130
    57131        for (fde = ev->fd_events; fde; fde = fde->next) {
    58                 if (fde->fd < 0 || fde->fd >= FD_SETSIZE) {
    59                         /* We ignore here, as it shouldn't be
    60                            possible to add an invalid fde->fd
    61                            but we don't want FD_SET to see an
    62                            invalid fd. */
     132                struct pollfd *pfd;
     133
     134                if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {
    63135                        continue;
    64136                }
    65137
     138                if (state->pollfd_idx[fde->fd] == -1) {
     139                        /*
     140                         * We haven't seen this fd yet. Allocate a new pollfd.
     141                         */
     142                        state->pollfd_idx[fde->fd] = num_pollfds;
     143                        pfd = &fds[num_pollfds];
     144                        num_pollfds += 1;
     145                } else {
     146                        /*
     147                         * We have already seen this fd. OR in the flags.
     148                         */
     149                        pfd = &fds[state->pollfd_idx[fde->fd]];
     150                }
     151
     152                pfd->fd = fde->fd;
     153
    66154                if (fde->flags & EVENT_FD_READ) {
    67                         FD_SET(fde->fd, read_fds);
    68                         ret = true;
     155                        pfd->events |= (POLLIN|POLLHUP);
    69156                }
    70157                if (fde->flags & EVENT_FD_WRITE) {
    71                         FD_SET(fde->fd, write_fds);
    72                         ret = true;
    73                 }
    74 
    75                 if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE))
    76                     && (fde->fd > *maxfd)) {
    77                         *maxfd = fde->fd;
    78                 }
    79         }
     158                        pfd->events |= POLLOUT;
     159                }
     160        }
     161        *pfds = fds;
     162        *pnum_pfds = num_pollfds;
    80163
    81164        if (ev->immediate_events != NULL) {
    82                 *timeout = timeval_zero();
    83                 return true;
    84         }
    85 
     165                *ptimeout = 0;
     166                return true;
     167        }
    86168        if (ev->timer_events == NULL) {
    87                 return ret;
    88         }
    89 
    90         diff = timeval_until(now, &ev->timer_events->next_event);
    91         *timeout = timeval_min(timeout, &diff);
     169                *ptimeout = MIN(*ptimeout, INT_MAX);
     170                return true;
     171        }
     172
     173        now = timeval_current();
     174        diff = timeval_until(&now, &ev->timer_events->next_event);
     175        timeout = timeval_to_msec(diff);
     176
     177        if (timeout < *ptimeout) {
     178                *ptimeout = timeout;
     179        }
    92180
    93181        return true;
    94182}
    95183
    96 bool run_events(struct tevent_context *ev,
    97                 int selrtn, fd_set *read_fds, fd_set *write_fds)
    98 {
     184bool run_events_poll(struct tevent_context *ev, int pollrtn,
     185                     struct pollfd *pfds, int num_pfds)
     186{
     187        struct tevent_poll_private *state;
     188        int *pollfd_idx;
    99189        struct tevent_fd *fde;
    100190        struct timeval now;
     
    140230        }
    141231
    142         if (selrtn <= 0) {
     232        if (pollrtn <= 0) {
    143233                /*
    144234                 * No fd ready
     
    147237        }
    148238
     239        state = (struct tevent_poll_private *)ev->additional_data;
     240        pollfd_idx = state->pollfd_idx;
     241
    149242        for (fde = ev->fd_events; fde; fde = fde->next) {
     243                struct pollfd *pfd;
    150244                uint16 flags = 0;
    151245
    152                 if (FD_ISSET(fde->fd, read_fds)) flags |= EVENT_FD_READ;
    153                 if (FD_ISSET(fde->fd, write_fds)) flags |= EVENT_FD_WRITE;
    154 
     246                if ((fde->flags & (EVENT_FD_READ|EVENT_FD_WRITE)) == 0) {
     247                        continue;
     248                }
     249
     250                if (pollfd_idx[fde->fd] >= num_pfds) {
     251                        DEBUG(1, ("internal error: pollfd_idx[fde->fd] (%d) "
     252                                  ">= num_pfds (%d)\n", pollfd_idx[fde->fd],
     253                                  num_pfds));
     254                        return false;
     255                }
     256                pfd = &pfds[pollfd_idx[fde->fd]];
     257
     258                if (pfd->fd != fde->fd) {
     259                        DEBUG(1, ("internal error: pfd->fd (%d) "
     260                                  "!= fde->fd (%d)\n", pollfd_idx[fde->fd],
     261                                  num_pfds));
     262                        return false;
     263                }
     264
     265                if (pfd->revents & (POLLHUP|POLLERR)) {
     266                        /* If we only wait for EVENT_FD_WRITE, we
     267                           should not tell the event handler about it,
     268                           and remove the writable flag, as we only
     269                           report errors when waiting for read events
     270                           to match the select behavior. */
     271                        if (!(fde->flags & EVENT_FD_READ)) {
     272                                EVENT_FD_NOT_WRITEABLE(fde);
     273                                continue;
     274                        }
     275                        flags |= EVENT_FD_READ;
     276                }
     277
     278                if (pfd->revents & POLLIN) {
     279                        flags |= EVENT_FD_READ;
     280                }
     281                if (pfd->revents & POLLOUT) {
     282                        flags |= EVENT_FD_WRITE;
     283                }
    155284                if (flags & fde->flags) {
    156                         DLIST_DEMOTE(ev->fd_events, fde, struct tevent_fd *);
     285                        DLIST_DEMOTE(ev->fd_events, fde, struct tevent_fd);
    157286                        fde->handler(ev, fde, flags, fde->private_data);
    158287                        return true;
     
    162291        return false;
    163292}
    164 
    165293
    166294struct timeval *get_timed_events_timeout(struct tevent_context *ev,
     
    188316static int s3_event_loop_once(struct tevent_context *ev, const char *location)
    189317{
    190         struct timeval now, to;
    191         fd_set r_fds, w_fds;
    192         int maxfd = 0;
     318        struct tevent_poll_private *state;
     319        int timeout;
     320        int num_pfds;
    193321        int ret;
    194322
    195         FD_ZERO(&r_fds);
    196         FD_ZERO(&w_fds);
    197 
    198         to.tv_sec = 9999;       /* Max timeout */
    199         to.tv_usec = 0;
    200 
    201         if (run_events(ev, 0, NULL, NULL)) {
     323        timeout = INT_MAX;
     324
     325        state = tevent_get_poll_private(ev);
     326        if (state == NULL) {
     327                errno = ENOMEM;
     328                return -1;
     329        }
     330
     331        if (run_events_poll(ev, 0, NULL, 0)) {
    202332                return 0;
    203333        }
    204334
    205         GetTimeOfDay(&now);
    206 
    207         if (!event_add_to_select_args(ev, &now, &r_fds, &w_fds, &to, &maxfd)) {
     335        num_pfds = 0;
     336        if (!event_add_to_poll_args(ev, state,
     337                                    &state->pfds, &num_pfds, &timeout)) {
    208338                return -1;
    209339        }
    210340
    211         ret = sys_select(maxfd+1, &r_fds, &w_fds, NULL, &to);
    212 
     341        ret = sys_poll(state->pfds, num_pfds, timeout);
    213342        if (ret == -1 && errno != EINTR) {
    214343                tevent_debug(ev, TEVENT_DEBUG_FATAL,
    215                              "sys_select() failed: %d:%s\n",
     344                             "poll() failed: %d:%s\n",
    216345                             errno, strerror(errno));
    217346                return -1;
    218347        }
    219348
    220         run_events(ev, ret, &r_fds, &w_fds);
     349        run_events_poll(ev, ret, state->pfds, num_pfds);
    221350        return 0;
    222 }
    223 
    224 void event_context_reinit(struct tevent_context *ev)
    225 {
    226         tevent_common_context_destructor(ev);
    227         return;
    228351}
    229352
Note: See TracChangeset for help on using the changeset viewer.