1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

- make the recalculation of ev->maxfd a bit more efficient.

- fix the case when we have no fd_events left on the event_context
  we now exit after doing the timed events and not block in select()
  waiting for no fd's to become ready...

metze
This commit is contained in:
Stefan Metzmacher 0001-01-01 00:00:00 +00:00
parent f3b917402a
commit 857e76ef6b

View File

@ -118,6 +118,11 @@ static void calc_maxfd(struct event_context *ev)
} }
} }
/* to mark the ev->maxfd invalid
* this means we need to recalculate it
*/
#define EVENT_INVALID_MAXFD (-1)
/* /*
remove a fd based event remove a fd based event
the event to remove is matched by looking at the handler the event to remove is matched by looking at the handler
@ -132,8 +137,6 @@ BOOL event_remove_fd(struct event_context *ev, struct fd_event *e1)
e->fd == e1->fd && e->fd == e1->fd &&
e->handler == e1->handler) { e->handler == e1->handler) {
e->ref_count--; e->ref_count--;
/* possibly calculate the new maxfd */
calc_maxfd(ev);
return True; return True;
} }
} }
@ -151,7 +154,6 @@ void event_remove_fd_all(struct event_context *ev, int fd)
e->ref_count--; e->ref_count--;
} }
} }
calc_maxfd(ev);
} }
/* /*
@ -166,7 +168,6 @@ void event_remove_fd_all_handler(struct event_context *ev, void *handler)
e->ref_count--; e->ref_count--;
} }
} }
calc_maxfd(ev);
} }
@ -289,6 +290,9 @@ int event_loop_wait(struct event_context *ev)
struct fd_event *next = fe->next; struct fd_event *next = fe->next;
if (fe->ref_count == 0) { if (fe->ref_count == 0) {
DLIST_REMOVE(ev->fd_events, fe); DLIST_REMOVE(ev->fd_events, fe);
if (ev->maxfd == fe->fd) {
ev->maxfd = EVENT_INVALID_MAXFD;
}
free(fe); free(fe);
} else { } else {
if (fe->flags & EVENT_FD_READ) { if (fe->flags & EVENT_FD_READ) {
@ -316,39 +320,50 @@ int event_loop_wait(struct event_context *ev)
} }
} }
/* only do a select() if there're fd_events
* otherwise we would block for a the time in tval,
* and if there're no fd_events present anymore we want to
* leave the event loop directly
*/
if (ev->fd_events) {
/* we maybe need to recalculate the maxfd */
if (ev->maxfd == EVENT_INVALID_MAXFD) {
calc_maxfd(ev);
}
/* TODO: /* TODO:
* we don't use sys_select() as it isn't thread
* safe. We need to replace the magic pipe handling in
* sys_select() with something in the events
* structure - for now just use select()
*/
selrtn = select(ev->maxfd+1, &r_fds, &w_fds, NULL, &tval);
we don't use sys_select() as it isn't thread t = time(NULL);
safe. We need to replace the magic pipe handling in
sys_select() with something in the events
structure - for now just use select() */
selrtn = select(ev->maxfd+1, &r_fds, &w_fds, NULL, &tval);
t = time(NULL); if (selrtn == -1 && errno == EBADF) {
/* the socket is dead! this should never
happen as the socket should have first been
made readable and that should have removed
the event, so this must be a bug. This is a
fatal error. */
DEBUG(0,("EBADF on event_loop_wait - exiting\n"));
return -1;
}
if (selrtn == -1 && errno == EBADF) { if (selrtn > 0) {
/* the socket is dead! this should never /* at least one file descriptor is ready - check
happen as the socket should have first been which ones and call the handler, being careful to allow
made readable and that should have removed the handler to remove itself when called */
the event, so this must be a bug. This is a for (fe=ev->fd_events; fe; fe=fe->next) {
fatal error. */ uint16 flags = 0;
DEBUG(0,("EBADF on event_loop_wait - exiting\n")); if (FD_ISSET(fe->fd, &r_fds)) flags |= EVENT_FD_READ;
return -1; if (FD_ISSET(fe->fd, &w_fds)) flags |= EVENT_FD_WRITE;
} if (fe->ref_count && flags) {
fe->ref_count++;
if (selrtn > 0) { fe->handler(ev, fe, t, flags);
/* at least one file descriptor is ready - check fe->ref_count--;
which ones and call the handler, being careful to allow }
the handler to remove itself when called */
for (fe=ev->fd_events; fe; fe=fe->next) {
uint16 flags = 0;
if (FD_ISSET(fe->fd, &r_fds)) flags |= EVENT_FD_READ;
if (FD_ISSET(fe->fd, &w_fds)) flags |= EVENT_FD_WRITE;
if (fe->ref_count && flags) {
fe->ref_count++;
fe->handler(ev, fe, t, flags);
fe->ref_count--;
} }
} }
} }