--- pth_sched.c 2002/11/03 11:15:05 1.82
+++ pth_sched.c 2002/11/05 19:39:09 1.83
@@ -368,7 +368,7 @@
}
/*
- * Look whether some events already occurred and move
+ * Look whether some events already occurred (or failed) and move
* corresponding threads from waiting queue back to ready queue.
*/
intern void pth_sched_eventmanager(pth_time_t *now, int dopoll)
@@ -441,7 +441,7 @@
/* ...check whether events occurred */
ev = evh = t->events;
do {
- if (!ev->ev_occurred) {
+ if (ev->ev_status == PTH_STATUS_PENDING) {
this_occurred = FALSE;
/* Filedescriptor I/O */
@@ -559,7 +559,7 @@
/* tag event if it has occurred */
if (this_occurred) {
pth_debug2("pth_sched_eventmanager: [non-I/O] event occurred for thread \"%s\"", t->name);
- ev->ev_occurred = TRUE;
+ ev->ev_status = PTH_STATUS_OCCURRED;
any_occurred = TRUE;
}
}
@@ -633,7 +633,7 @@
/* it was an explicit timer event, standing for its own */
pth_debug2("pth_sched_eventmanager: [timeout] event occurred for thread \"%s\"",
nexttimer_thread->name);
- nexttimer_ev->ev_occurred = TRUE;
+ nexttimer_ev->ev_status = PTH_STATUS_OCCURRED;
}
}
@@ -655,6 +655,9 @@
additionally if a thread has one occurred event, we move it from the
waiting queue to the ready queue */
+ /* pre-configure a raw polling timeout for later checks (see below) */
+ pth_time_set(&delay, PTH_TIME_ZERO);
+
/* for all threads in the waiting queue... */
t = pth_pqueue_head(&pth_WQ);
while (t != NULL) {
@@ -668,7 +671,7 @@
/*
* Late handling for still not occured events
*/
- if (!ev->ev_occurred) {
+ if (ev->ev_status == PTH_STATUS_PENDING) {
/* Filedescriptor I/O */
if (ev->ev_type == PTH_EVENT_FD) {
if ( ( ev->ev_goal & PTH_UNTIL_FD_READABLE
@@ -679,7 +682,33 @@
&& FD_ISSET(ev->ev_args.FD.fd, &efds)) ) {
pth_debug2("pth_sched_eventmanager: "
"[I/O] event occurred for thread \"%s\"", t->name);
- ev->ev_occurred = TRUE;
+ ev->ev_status = PTH_STATUS_OCCURRED;
+ }
+ else if (rc < 0) {
+ /* re-check particular filedescriptor */
+ int rc2;
+ if (ev->ev_goal & PTH_UNTIL_FD_READABLE)
+ FD_SET(ev->ev_args.FD.fd, &rfds);
+ if (ev->ev_goal & PTH_UNTIL_FD_WRITEABLE)
+ FD_SET(ev->ev_args.FD.fd, &wfds);
+ if (ev->ev_goal & PTH_UNTIL_FD_EXCEPTION)
+ FD_SET(ev->ev_args.FD.fd, &efds);
+ while ((rc2 = pth_sc(select)(ev->ev_args.FD.fd+1, &rfds, &wfds, &efds, &delay)) < 0
+ && errno == EINTR) ;
+ if (rc2 > 0) {
+ /* cleanup afterwards for next iteration */
+ FD_CLR(ev->ev_args.FD.fd, &rfds);
+ FD_CLR(ev->ev_args.FD.fd, &wfds);
+ FD_CLR(ev->ev_args.FD.fd, &efds);
+ } else if (rc2 < 0) {
+ /* cleanup afterwards for next iteration */
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_ZERO(&efds);
+ ev->ev_status = PTH_STATUS_FAILED;
+ pth_debug2("pth_sched_eventmanager: "
+ "[I/O] event failed for thread \"%s\"", t->name);
+ }
}
}
/* Filedescriptor Set I/O */
@@ -694,10 +723,39 @@
ev->ev_args.SELECT.efds, &efds);
if (ev->ev_args.SELECT.n != NULL)
*(ev->ev_args.SELECT.n) = n;
- ev->ev_occurred = TRUE;
+ ev->ev_status = PTH_STATUS_OCCURRED;
pth_debug2("pth_sched_eventmanager: "
"[I/O] event occurred for thread \"%s\"", t->name);
}
+ else if (rc < 0) {
+ /* re-check particular filedescriptor set */
+ int rc2;
+ fd_set *prfds = NULL;
+ fd_set *pwfds = NULL;
+ fd_set *pefds = NULL;
+ fd_set trfds;
+ fd_set twfds;
+ fd_set tefds;
+ if (ev->ev_args.SELECT.rfds) {
+ memcpy(&trfds, ev->ev_args.SELECT.rfds, sizeof(rfds));
+ prfds = &trfds;
+ }
+ if (ev->ev_args.SELECT.wfds) {
+ memcpy(&twfds, ev->ev_args.SELECT.wfds, sizeof(wfds));
+ pwfds = &twfds;
+ }
+ if (ev->ev_args.SELECT.efds) {
+ memcpy(&tefds, ev->ev_args.SELECT.efds, sizeof(efds));
+ pefds = &tefds;
+ }
+ while ((rc2 = pth_sc(select)(ev->ev_args.SELECT.nfd+1, prfds, pwfds, pefds, &delay)) < 0
+ && errno == EINTR) ;
+ if (rc2 < 0) {
+ ev->ev_status = PTH_STATUS_FAILED;
+ pth_debug2("pth_sched_eventmanager: "
+ "[I/O] event failed for thread \"%s\"", t->name);
+ }
+ }
}
/* Signal Set */
else if (ev->ev_type == PTH_EVENT_SIGS) {
@@ -709,7 +767,7 @@
pth_debug2("pth_sched_eventmanager: "
"[signal] event occurred for thread \"%s\"", t->name);
sigdelset(&pth_sigraised, sig);
- ev->ev_occurred = TRUE;
+ ev->ev_status = PTH_STATUS_OCCURRED;
}
}
}
@@ -731,7 +789,7 @@
}
/* local to global mapping */
- if (ev->ev_occurred)
+ if (ev->ev_status != PTH_STATUS_PENDING)
any_occurred = TRUE;
} while ((ev = ev->ev_next) != evh);
}
|