summaryrefslogtreecommitdiff
path: root/comm
diff options
context:
space:
mode:
authorchatty2000-11-28 17:06:08 +0000
committerchatty2000-11-28 17:06:08 +0000
commit4eb666da31191588d89629ebc38ee98f02ee89b4 (patch)
tree2a5ac1bb6b138d1dee01d142a4af2a68535698e7 /comm
parent4c26f7000135a6184a36c6c416ce625d21d43382 (diff)
downloadivy-league-4eb666da31191588d89629ebc38ee98f02ee89b4.zip
ivy-league-4eb666da31191588d89629ebc38ee98f02ee89b4.tar.gz
ivy-league-4eb666da31191588d89629ebc38ee98f02ee89b4.tar.bz2
ivy-league-4eb666da31191588d89629ebc38ee98f02ee89b4.tar.xz
Amelioration de la gestion des timers dans Scan
Amelioration de la gestion des timers dans LoopScan
Diffstat (limited to 'comm')
-rw-r--r--comm/Multiplexer.cc64
1 files changed, 46 insertions, 18 deletions
diff --git a/comm/Multiplexer.cc b/comm/Multiplexer.cc
index 1823705..c1bf8b6 100644
--- a/comm/Multiplexer.cc
+++ b/comm/Multiplexer.cc
@@ -3,7 +3,7 @@
*
* by Michel Beaudouin-Lafon
*
- * Copyright 1990-1993
+ * Copyright 1990-1995
* Laboratoire de Recherche en Informatique (LRI)
*
* Channel sets, or multiplexers
@@ -415,10 +415,8 @@ UchMultiplexer :: Scan (bool nointr, bool poll)
timeout = &tout;
tout.tv_sec = tout.tv_usec = 0;
}
-
+
while (ret <= 0) {
- CcuCoreTimer::Fire (&Timers);
-
if (ReadCount == 0 && WriteCount == 0 && SelectCount == 0)
return 0;
@@ -431,30 +429,46 @@ UchMultiplexer :: Scan (bool nointr, bool poll)
nfd--;
}
-//printf ("Scan: read %x, write %x, TimeOut %d", ReadMask, WriteMask, TimeOut);
rmsk = ReadMask;
wmsk = WriteMask;
+
+ /* let's fiddle with ret to skip select if we are late with timers */
+ ret = -1;
if (!poll && TimeOut != -1) {
CcuTimeStamp now;
Millisecond delay = TimeOut - now;
-//printf (", timeout in %d ms", delay);
+ /* if delay < 0, select is unhappy */
+ if (delay < 0)
+ ret = 0;
tout.tv_sec = delay / 1000;
tout.tv_usec = 1000 * (delay % 1000);
timeout = &tout;
}
-//printf ("\n");
-
- ret = select (NFILE, FD_SET_TYPE(&rmsk) /*read*/, FD_SET_TYPE(&wmsk) /*write*/, 0 /*except*/, timeout);
- if (ret < 0 || ret == 0 && poll) {
-//printf ("select failed: %d, errno %d\n", ret, errno);
- if (nointr && ret == -1 && errno == EINTR)
+
+ /* skipping select is a trick to avoid problems with timers. However,
+ something more general should be done to:
+ - manage priorities (I'm not sure the current situation is sound)
+ - handle situations when we are late.
+ */
+ if (ret != 0)
+ ret = select (NFILE, FD_SET_TYPE(&rmsk), FD_SET_TYPE(&wmsk), 0, timeout);
+
+ if (ret == 0) {
+ if (TimeOut != -1)
+ /* Fire might be called without reason if polling is on. Too bad... */
+ CcuCoreTimer::Fire (&Timers);
+ else if (!poll)
+ fprintf (stderr, "select returned 0 without reason!\n");
+ return 0;
+ } else if (ret < 0) {
+ if (nointr && errno == EINTR)
continue;
- return ret;
+ else
+ return ret;
}
}
for (fd = 0, nfd = ret; nfd; fd++) {
-//printf ("Scan: handle %d: r %d, w %d\n", fd, FD_ISSET (fd, &rmsk), FD_ISSET (fd, &wmsk));
if (FD_ISSET (fd, &wmsk)) {
nfd --;
UchChannel* ch = Channels [fd];
@@ -511,8 +525,10 @@ UchMultiplexer :: LoopScan (bool nointr)
if (SigFired)
HandleDeferredSignals ();
+#if 0
/* Then, timers */
CcuCoreTimer::Fire (&Timers);
+#endif
/* Then, I/Os */
if (ReadCount == 0 && WriteCount == 0 && SelectCount == 0)
@@ -530,7 +546,9 @@ UchMultiplexer :: LoopScan (bool nointr)
}
if (nfd) // a handler returned true.
continue;
-
+
+ /* let's fiddle with ret to skip select if we are late with timers */
+ nfd = -1;
rmsk = ReadMask;
wmsk = WriteMask;
struct timeval tv;
@@ -538,15 +556,25 @@ UchMultiplexer :: LoopScan (bool nointr)
if (TimeOut != -1) {
CcuTimeStamp now;
Millisecond delay = TimeOut - now;
+ if (delay < 0)
+ nfd = 0;
tv.tv_sec = delay / 1000;
tv.tv_usec = 1000 * (delay % 1000);
timeout = &tv;
}
- nfd = select (NFILE, FD_SET_TYPE(&rmsk) /*read*/, FD_SET_TYPE(&wmsk) /*write*/, 0 /*except*/, timeout);
- if (nfd < 0) {
+ if (nfd != 0)
+ nfd = select (NFILE, FD_SET_TYPE(&rmsk), FD_SET_TYPE(&wmsk), 0, timeout);
+ if (nfd == 0) {
+ if (TimeOut != -1)
+ CcuCoreTimer::Fire (&Timers);
+ else
+ fprintf (stderr, "select returned 0 without reason!\n");
+ continue;
+ } else if (nfd < 0) {
if (nointr && nfd == -1 && errno == EINTR)
continue;
- return isMpxError;
+ else
+ return isMpxError;
}
for (fd = fd0; nfd; (fd < NFILE) ? fd++ : (fd = 0)) {