SAMBA4 event loop
Stefan (metze) Metzmacher
metze at metzemix.de
Tue Sep 9 10:54:42 GMT 2003
Hi tridge,
I'm using samba4's event_loop for my imap server (emil-surfer).
And I found a bug in it..:-(
we call select even if there're no fd_events left...
I use the attached patch in my server.
- I move calc_maxfd in only one place
- I call select only if (ev->events)
- I add the expect fd's to select
(I'm not using it but I want modules to be able to use this)
Index: incdir/mx-events.h
===================================================================
RCS file: /home/CVSROOT/emil-surfer/incdir/mx-events.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- incdir/mx-events.h 2003/09/09 10:42:48 1.2
+++ incdir/mx-events.h 2003/09/09 10:43:20 1.3
@@ -69,7 +69,9 @@
} exit;
};
+#define EVENT_INVALID_MAXFD (-1)
/* bits for fd_event.flags */
-#define EVENT_FD_READ 1
-#define EVENT_FD_WRITE 2
+#define EVENT_FD_READ 0x0001
+#define EVENT_FD_WRITE 0x0002
+#define EVENT_FD_EXPECT 0x0004
Index: server/events.c
===================================================================
RCS file: /home/CVSROOT/emil-surfer/server/events.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- server/events.c 2003/09/08 06:33:44 1.1
+++ server/events.c 2003/09/09 10:37:04 1.2
@@ -132,8 +132,6 @@
e->fd == e1->fd &&
e->handler == e1->handler) {
e->ref_count--;
- /* possibly calculate the new maxfd */
- calc_maxfd(ev);
return True;
}
}
@@ -151,7 +149,6 @@
e->ref_count--;
}
}
- calc_maxfd(ev);
}
/*
@@ -166,7 +163,6 @@
e->ref_count--;
}
}
- calc_maxfd(ev);
}
@@ -258,7 +254,7 @@
t = time(NULL);
while (ev->fd_events && !ev->exit.exit_now) {
- fd_set r_fds, w_fds;
+ fd_set r_fds, w_fds, e_fds;
struct fd_event *fe;
struct loop_event *le;
struct timed_event *te;
@@ -283,12 +279,16 @@
ZERO_STRUCT(tval);
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
+ FD_ZERO(&e_fds);
/* setup any fd events */
for (fe=ev->fd_events; fe; ) {
struct fd_event *next = fe->next;
if (fe->ref_count == 0) {
DLIST_REMOVE(ev->fd_events, fe);
+ if (ev->maxfd == fe->fd) {
+ ev->maxfd = EVENT_INVALID_MAXFD;
+ }
free(fe);
} else {
if (fe->flags & EVENT_FD_READ) {
@@ -297,6 +297,9 @@
if (fe->flags & EVENT_FD_WRITE) {
FD_SET(fe->fd, &w_fds);
}
+ if (fe->flags & EVENT_FD_EXPECT) {
+ FD_SET(fe->fd, &e_fds);
+ }
}
fe = next;
}
@@ -316,33 +319,39 @@
}
}
+ if (ev->maxfd == EVENT_INVALID_MAXFD) {
+ calc_maxfd(ev);
+ }
+
+ if (ev->fd_events) {
+ selrtn = sys_select(ev->maxfd+1, &r_fds, &w_fds,
&e_fds, &tval);
- selrtn = sys_select(ev->maxfd+1, &r_fds, &w_fds, NULL, &tval);
+ t = time(NULL);
- 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) {
- /* 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 > 0) {
- /* at least one file descriptor is ready - check
- 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--;
+ if (selrtn > 0) {
+ /* at least one file descriptor is ready -
check
+ 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 (FD_ISSET(fe->fd, &e_fds)) flags
|= EVENT_FD_EXPECT;
+ if (fe->ref_count && flags) {
+ fe->ref_count++;
+ fe->handler(ev, fe, t, flags);
+ fe->ref_count--;
+ }
}
}
}
metze
-----------------------------------------------------------------------------
Stefan "metze" Metzmacher <metze at metzemix.de>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: events-01.diff
Type: application/octet-stream
Size: 4118 bytes
Desc: not available
Url : http://lists.samba.org/archive/samba-technical/attachments/20030909/7abeb538/events-01.obj
More information about the samba-technical
mailing list