From 4eb666da31191588d89629ebc38ee98f02ee89b4 Mon Sep 17 00:00:00 2001 From: chatty Date: Tue, 28 Nov 2000 17:06:08 +0000 Subject: Amelioration de la gestion des timers dans Scan Amelioration de la gestion des timers dans LoopScan --- comm/Multiplexer.cc | 64 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 18 deletions(-) (limited to 'comm') 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)) { -- cgit v1.1