mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
r22963: fixed the epoll/fork interaction in the epoll and aio backends
This commit is contained in:
parent
1f1f57023b
commit
aeca07659a
@ -48,6 +48,9 @@ struct aio_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* list of filedescriptor events */
|
||||
struct fd_event *fd_events;
|
||||
|
||||
/* number of registered fd event handlers */
|
||||
int num_fd_events;
|
||||
|
||||
@ -61,6 +64,7 @@ struct aio_event_context {
|
||||
|
||||
int epoll_fd;
|
||||
int is_epoll_set;
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
struct aio_event {
|
||||
@ -92,6 +96,28 @@ static int aio_ctx_destructor(struct aio_event_context *aio_ev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *fde);
|
||||
|
||||
/*
|
||||
reopen the epoll handle when our pid changes
|
||||
see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
|
||||
demonstration of why this is needed
|
||||
*/
|
||||
static void epoll_reopen(struct aio_event_context *aio_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
close(aio_ev->epoll_fd);
|
||||
aio_ev->epoll_fd = epoll_create(64);
|
||||
if (aio_ev->epoll_fd == -1) {
|
||||
return;
|
||||
}
|
||||
aio_ev->pid = getpid();
|
||||
for (fde=aio_ev->fd_events;fde;fde=fde->next) {
|
||||
epoll_add_event(aio_ev, fde);
|
||||
}
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
@ -104,6 +130,16 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *f
|
||||
struct epoll_event event;
|
||||
if (aio_ev->epoll_fd == -1) return;
|
||||
|
||||
/* during an add event we need to check if our pid has changed
|
||||
and re-open the epoll socket. Note that we don't need to do this
|
||||
for other epoll changes */
|
||||
if (aio_ev->pid != getpid()) {
|
||||
epoll_reopen(aio_ev);
|
||||
/* the current event gets added in epoll_reopen(), so
|
||||
we can return here */
|
||||
return;
|
||||
}
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if we don't want events yet, don't add an aio_event */
|
||||
@ -127,6 +163,9 @@ static void epoll_add_event(struct aio_event_context *aio_ev, struct fd_event *f
|
||||
static void epoll_del_event(struct aio_event_context *aio_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
DLIST_REMOVE(aio_ev->fd_events, fde);
|
||||
|
||||
if (aio_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
@ -185,6 +224,7 @@ static void epoll_change_event(struct aio_event_context *aio_ev, struct fd_event
|
||||
|
||||
/* there's no aio_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
DLIST_ADD(aio_ev->fd_events, fde);
|
||||
epoll_add_event(aio_ev, fde);
|
||||
return;
|
||||
}
|
||||
@ -334,6 +374,7 @@ static int aio_event_context_init(struct event_context *ev)
|
||||
talloc_free(aio_ev);
|
||||
return -1;
|
||||
}
|
||||
aio_ev->pid = getpid();
|
||||
|
||||
talloc_set_destructor(aio_ev, aio_ctx_destructor);
|
||||
|
||||
@ -396,6 +437,7 @@ static struct fd_event *aio_event_add_fd(struct event_context *ev, TALLOC_CTX *m
|
||||
aio_ev->num_fd_events++;
|
||||
talloc_set_destructor(fde, aio_event_fd_destructor);
|
||||
|
||||
DLIST_ADD(aio_ev->fd_events, fde);
|
||||
epoll_add_event(aio_ev, fde);
|
||||
|
||||
return fde;
|
||||
|
@ -32,6 +32,9 @@ struct epoll_event_context {
|
||||
/* a pointer back to the generic event_context */
|
||||
struct event_context *ev;
|
||||
|
||||
/* list of filedescriptor events */
|
||||
struct fd_event *fd_events;
|
||||
|
||||
/* number of registered fd event handlers */
|
||||
int num_fd_events;
|
||||
|
||||
@ -45,6 +48,8 @@ struct epoll_event_context {
|
||||
|
||||
/* when using epoll this is the handle from epoll_create */
|
||||
int epoll_fd;
|
||||
|
||||
pid_t pid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -86,9 +91,32 @@ static int epoll_ctx_destructor(struct epoll_event_context *epoll_ev)
|
||||
static void epoll_init_ctx(struct epoll_event_context *epoll_ev)
|
||||
{
|
||||
epoll_ev->epoll_fd = epoll_create(64);
|
||||
epoll_ev->pid = getpid();
|
||||
talloc_set_destructor(epoll_ev, epoll_ctx_destructor);
|
||||
}
|
||||
|
||||
static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde);
|
||||
|
||||
/*
|
||||
reopen the epoll handle when our pid changes
|
||||
see http://junkcode.samba.org/ftp/unpacked/junkcode/epoll_fork.c for an
|
||||
demonstration of why this is needed
|
||||
*/
|
||||
static void epoll_reopen(struct epoll_event_context *epoll_ev)
|
||||
{
|
||||
struct fd_event *fde;
|
||||
|
||||
close(epoll_ev->epoll_fd);
|
||||
epoll_ev->epoll_fd = epoll_create(64);
|
||||
if (epoll_ev->epoll_fd == -1) {
|
||||
return;
|
||||
}
|
||||
epoll_ev->pid = getpid();
|
||||
for (fde=epoll_ev->fd_events;fde;fde=fde->next) {
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
}
|
||||
}
|
||||
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR (1<<1)
|
||||
#define EPOLL_ADDITIONAL_FD_FLAG_GOT_ERROR (1<<2)
|
||||
@ -99,8 +127,19 @@ static void epoll_init_ctx(struct epoll_event_context *epoll_ev)
|
||||
static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
if (epoll_ev->epoll_fd == -1) return;
|
||||
|
||||
/* during an add event we need to check if our pid has changed
|
||||
and re-open the epoll socket. Note that we don't need to do this
|
||||
for other epoll changes */
|
||||
if (epoll_ev->pid != getpid()) {
|
||||
epoll_reopen(epoll_ev);
|
||||
/* the current event gets added in epoll_reopen(), so
|
||||
we can return here */
|
||||
return;
|
||||
}
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
|
||||
/* if we don't want events yet, don't add an epoll_event */
|
||||
@ -126,6 +165,9 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct fd_even
|
||||
static void epoll_del_event(struct epoll_event_context *epoll_ev, struct fd_event *fde)
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
DLIST_REMOVE(epoll_ev->fd_events, fde);
|
||||
|
||||
if (epoll_ev->epoll_fd == -1) return;
|
||||
|
||||
fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_REPORT_ERROR;
|
||||
@ -193,6 +235,7 @@ static void epoll_change_event(struct epoll_event_context *epoll_ev, struct fd_e
|
||||
|
||||
/* there's no epoll_event attached to the fde */
|
||||
if (want_read || (want_write && !got_error)) {
|
||||
DLIST_ADD(epoll_ev->fd_events, fde);
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
return;
|
||||
}
|
||||
@ -343,6 +386,7 @@ static struct fd_event *epoll_event_add_fd(struct event_context *ev, TALLOC_CTX
|
||||
epoll_ev->num_fd_events++;
|
||||
talloc_set_destructor(fde, epoll_event_fd_destructor);
|
||||
|
||||
DLIST_ADD(epoll_ev->fd_events, fde);
|
||||
epoll_add_event(epoll_ev, fde);
|
||||
|
||||
return fde;
|
||||
|
Loading…
Reference in New Issue
Block a user