Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/lib/util/select.c

    r740 r988  
    2424#include "lib/util/select.h"
    2525
    26 /* This is here because it allows us to avoid a nasty race in signal handling.
    27    We need to guarantee that when we get a signal we get out of a select immediately
    28    but doing that involves a race condition. We can avoid the race by getting the
    29    signal handler to write to a pipe that is in the select/poll list
    30 
    31    This means all Samba signal handlers should call sys_select_signal().
    32 */
    33 
    34 static pid_t initialised;
    35 static int select_pipe[2];
    36 static volatile unsigned pipe_written, pipe_read;
    37 
    38 /*******************************************************************
    39  Call this from all Samba signal handlers if you want to avoid a
    40  nasty signal race condition.
    41 ********************************************************************/
    42 
    43 void sys_select_signal(char c)
    44 {
    45         int saved_errno = errno;
    46 
    47         if (!initialised) return;
    48 
    49         if (pipe_written > pipe_read+256) return;
    50 
    51         if (write(select_pipe[1], &c, 1) == 1) pipe_written++;
    52 
    53         errno = saved_errno;
    54 }
    55 
    56 /*
    57  * sys_poll expects pollfd's to be a talloc'ed array.
    58  *
    59  * It expects the talloc_array_length(fds) >= num_fds+1 to give space
    60  * to the signal pipe.
    61  */
    62 
    63 int sys_poll(struct pollfd *fds, int num_fds, int timeout)
    64 {
    65         int ret;
    66 
    67         if (talloc_array_length(fds) < num_fds+1) {
    68                 errno = ENOSPC;
    69                 return -1;
    70         }
    71 
    72         if (initialised != sys_getpid()) {
    73                 if (pipe(select_pipe) == -1)
    74                 {
    75                         int saved_errno = errno;
    76                         DEBUG(0, ("sys_poll: pipe failed (%s)\n",
    77                                 strerror(errno)));
    78                         errno = saved_errno;
    79                         return -1;
    80                 }
    81 
    82                 /*
    83                  * These next two lines seem to fix a bug with the Linux
    84                  * 2.0.x kernel (and probably other UNIXes as well) where
    85                  * the one byte read below can block even though the
    86                  * select returned that there is data in the pipe and
    87                  * the pipe_written variable was incremented. Thanks to
    88                  * HP for finding this one. JRA.
    89                  */
    90 
    91                 if(set_blocking(select_pipe[0],0)==-1)
    92                         smb_panic("select_pipe[0]: O_NONBLOCK failed");
    93                 if(set_blocking(select_pipe[1],0)==-1)
    94                         smb_panic("select_pipe[1]: O_NONBLOCK failed");
    95 
    96                 initialised = sys_getpid();
    97         }
    98 
    99         ZERO_STRUCT(fds[num_fds]);
    100         fds[num_fds].fd = select_pipe[0];
    101         fds[num_fds].events = POLLIN|POLLHUP;
    102 
    103         errno = 0;
    104         ret = poll(fds, num_fds+1, timeout);
    105 
    106         if ((ret >= 0) && (fds[num_fds].revents & (POLLIN|POLLHUP|POLLERR))) {
    107                 char c;
    108                 int saved_errno = errno;
    109 
    110                 if (read(select_pipe[0], &c, 1) == 1) {
    111                         pipe_read += 1;
    112 
    113                         /* Mark Weaver <mark-clist@npsl.co.uk> pointed out a critical
    114                            fix to ensure we don't lose signals. We must always
    115                            return -1 when the select pipe is set, otherwise if another
    116                            fd is also ready (so ret == 2) then we used to eat the
    117                            byte in the pipe and lose the signal. JRA.
    118                         */
    119                         ret = -1;
    120 #if 0
    121                         /* JRA - we can use this to debug the signal messaging... */
    122                         DEBUG(0,("select got %u signal\n", (unsigned int)c));
    123 #endif
    124                         errno = EINTR;
    125                 } else {
    126                         ret -= 1;
    127                         errno = saved_errno;
    128                 }
    129         }
    130 
    131         return ret;
    132 }
    133 
    13426int sys_poll_intr(struct pollfd *fds, int num_fds, int timeout)
    13527{
     
    15143                        break;
    15244                }
     45                /* Infinite timeout, no need to adjust. */
     46                if (timeout < 0) {
     47                        continue;
     48                }
    15349                clock_gettime_mono(&now);
    154                 elapsed = nsec_time_diff(&now, &start);
    155                 timeout = (orig_timeout - elapsed) / 1000000;
     50                elapsed = nsec_time_diff(&now, &start) / 1000000;
     51                timeout = orig_timeout - elapsed;
     52                /* Unlikely, but might happen eg. when getting traced.
     53                 * Make sure we're not hanging in this case.
     54                 */
     55                if (timeout < 0) {
     56                        timeout = 0;
     57                }
    15658        };
    15759        return ret;
Note: See TracChangeset for help on using the changeset viewer.