mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r21171: fixed a bug related to recursive event handling.
If this happens: - two sockets are readable, and select/epoll/aio returns both of them - read event on socket1 is called - inside that read event an event_loop_once is called, this returns that socket2 is readable - read event on socket2 is called - event_loop_once returns - top level event handler then calls read event on socket2 (as it still has that listed as readable) - read handler for socket2 returns zero byte read, which is interpreted as end of file - socket is incorrectly closed this happened with ctdb, but it could happen anywhere (just rarely). The fix is trivial - ensure we break out of the event loop when we have been called recursively.
This commit is contained in:
parent
a4a394c9bb
commit
e042002bb5
@ -219,7 +219,7 @@ static int setup_epoll_wait(struct aio_event_context *aio_ev)
|
||||
static int aio_event_loop(struct aio_event_context *aio_ev, struct timeval *tvalp)
|
||||
{
|
||||
int ret, i;
|
||||
uint32_t destruction_count = aio_ev->destruction_count;
|
||||
uint32_t destruction_count = ++aio_ev->destruction_count;
|
||||
struct timespec timeout;
|
||||
struct io_event events[8];
|
||||
|
||||
|
@ -204,7 +204,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval
|
||||
int ret, i;
|
||||
#define MAXEVENTS 8
|
||||
struct epoll_event events[MAXEVENTS];
|
||||
uint32_t destruction_count = epoll_ev->destruction_count;
|
||||
uint32_t destruction_count = ++epoll_ev->destruction_count;
|
||||
int timeout = -1;
|
||||
|
||||
if (epoll_ev->epoll_fd == -1) return -1;
|
||||
|
@ -47,12 +47,8 @@ struct select_event_context {
|
||||
/* information for exiting from the event loop */
|
||||
int exit_code;
|
||||
|
||||
/* this is changed by the destructors for the fd event
|
||||
type. It is used to detect event destruction by event
|
||||
handlers, which means the code that is calling the event
|
||||
handler needs to assume that the linked list is no longer
|
||||
valid
|
||||
*/
|
||||
/* this is incremented when the loop over events causes something which
|
||||
could change the events yet to be processed */
|
||||
uint32_t destruction_count;
|
||||
};
|
||||
|
||||
@ -177,7 +173,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru
|
||||
fd_set r_fds, w_fds;
|
||||
struct fd_event *fde;
|
||||
int selrtn;
|
||||
uint32_t destruction_count = select_ev->destruction_count;
|
||||
uint32_t destruction_count = ++select_ev->destruction_count;
|
||||
|
||||
/* we maybe need to recalculate the maxfd */
|
||||
if (select_ev->maxfd == EVENT_INVALID_MAXFD) {
|
||||
|
@ -219,7 +219,7 @@ static int epoll_event_loop(struct std_event_context *std_ev, struct timeval *tv
|
||||
int ret, i;
|
||||
#define MAXEVENTS 8
|
||||
struct epoll_event events[MAXEVENTS];
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
uint32_t destruction_count = ++std_ev->destruction_count;
|
||||
int timeout = -1;
|
||||
|
||||
if (std_ev->epoll_fd == -1) return -1;
|
||||
@ -425,7 +425,7 @@ static int std_event_loop_select(struct std_event_context *std_ev, struct timeva
|
||||
fd_set r_fds, w_fds;
|
||||
struct fd_event *fde;
|
||||
int selrtn;
|
||||
uint32_t destruction_count = std_ev->destruction_count;
|
||||
uint32_t destruction_count = ++std_ev->destruction_count;
|
||||
|
||||
/* we maybe need to recalculate the maxfd */
|
||||
if (std_ev->maxfd == EVENT_INVALID_MAXFD) {
|
||||
|
Loading…
Reference in New Issue
Block a user