summaryrefslogtreecommitdiff
path: root/comm/Multiplexer.cc
diff options
context:
space:
mode:
authorchatty1993-07-27 13:55:18 +0000
committerchatty1993-07-27 13:55:18 +0000
commit233b1b3091282ee89cfc1c5c606f2e7cb1f36262 (patch)
treef344b42a116e4dbf6131451bad6a30d5529425f2 /comm/Multiplexer.cc
parent266839df23d696cecb049514b98784bcf6fa59c7 (diff)
downloadivy-league-233b1b3091282ee89cfc1c5c606f2e7cb1f36262.zip
ivy-league-233b1b3091282ee89cfc1c5c606f2e7cb1f36262.tar.gz
ivy-league-233b1b3091282ee89cfc1c5c606f2e7cb1f36262.tar.bz2
ivy-league-233b1b3091282ee89cfc1c5c606f2e7cb1f36262.tar.xz
Split in 2 classes, to incorporate UchXtMultiplexer and UchTkMultiplexer
Diffstat (limited to 'comm/Multiplexer.cc')
-rw-r--r--comm/Multiplexer.cc239
1 files changed, 145 insertions, 94 deletions
diff --git a/comm/Multiplexer.cc b/comm/Multiplexer.cc
index a763c6d..9f29f40 100644
--- a/comm/Multiplexer.cc
+++ b/comm/Multiplexer.cc
@@ -24,6 +24,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
+#include <setjmp.h>
#if defined(__hpux) && !defined(__GNUG__)
#define FD_SET_TYPE(x) ((int*) x)
@@ -70,7 +71,7 @@ pointed to objects for an automatic reclaim of dynamically allocated objects.
/*?
Create an empty channel set.
?*/
-UchMultiplexer :: UchMultiplexer ()
+UchBaseMultiplexer :: UchBaseMultiplexer ()
: Channels (new pUchChannel [NFILE]),
Timers (),
ReadCount (0),
@@ -78,19 +79,15 @@ UchMultiplexer :: UchMultiplexer ()
SelectCount (0),
Looping (FALSE),
SigFired (FALSE),
- TimeOut (-1),
Handlers (new UchBaseSignalHandler* [NSIG]),
NbSignals (new int [NSIG])
{
- FD_ZERO (&ReadMask);
- FD_ZERO (&WriteMask);
- FD_ZERO (&SelectMask);
memset (Handlers, 0, NSIG * sizeof (UchBaseSignalHandler*));
memset (NbSignals, 0, NSIG * sizeof (int));
}
/*?nodoc?*/
-UchMultiplexer :: ~UchMultiplexer ()
+UchBaseMultiplexer :: ~UchBaseMultiplexer ()
{
#ifdef CPLUS_BUG4
delete [NFILE] Channels;
@@ -106,12 +103,10 @@ UchMultiplexer :: ~UchMultiplexer ()
Add a channel to the set.
Note that the argument is a pointer to the channel; no copy is made by this function.
If a channel with the same file descriptor as the one being added is already in the set,
-the old channel is first removed, thus calling \fun{RemoveNotify} for that channel.
-The virtual function \fun{AddNotify} is called before actually adding the channel
-to the set.
+the old channel is first removed.
?*/
void
-UchMultiplexer :: Add (UchChannel* chan)
+UchBaseMultiplexer :: Add (UchChannel* chan)
{
int fd = chan->FilDes ();
if (fd < 0)
@@ -119,8 +114,7 @@ UchMultiplexer :: Add (UchChannel* chan)
pUchChannel ochan = Channels [fd];
if (ochan)
Remove (fd);
- chan->AddNotify (*this);
- AddNotify (chan);
+ chan->Added (*this);
Channels [fd] = chan;
SetMasks (fd, chan->IOMode ());
}
@@ -129,18 +123,15 @@ pUchChannel NIL_CHAN (0);
/*?
Remove a channel from the set.
-The virtual function \fun{RemoveNotify} is called before actually removing the channel
-from the set.
?*/
void
-UchMultiplexer :: Remove (int fd)
+UchBaseMultiplexer :: Remove (int fd)
{
if (fd < 0)
return;
UchChannel* ch = Channels [fd];
if (ch) {
- ch->RemoveNotify (*this);
- RemoveNotify (ch);
+ ch->Removed (*this);
SetMasks (fd, IONone);
Channels [fd] = 0;
}
@@ -152,7 +143,7 @@ This function calls \fun{Remove} for all channels of the set.
This is a way of exiting from \fun{LoopScan}.
?*/
void
-UchMultiplexer :: RemoveAll ()
+UchBaseMultiplexer :: RemoveAll ()
{
for (int fd = 0; fd < NFILE; fd++)
Remove (fd);
@@ -161,20 +152,124 @@ UchMultiplexer :: RemoveAll ()
/*?
Change the mode of a channel in the set.
Mode \var{IONone} makes the channel inactive (without removing it).
-The virtual function \fun{SetModeNotify} is called before actually changing
-the mode of the channel.
?*/
void
-UchMultiplexer :: SetMode (int fd, IOMODE mode)
+UchBaseMultiplexer :: SetMode (int fd, IOMODE mode)
{
if (fd < 0)
return;
- SetModeNotify (Channels [fd], mode);
SetMasks (fd, mode);
Channels [fd] -> SetMode (mode);
}
+#ifdef DOC
+
+/*?
+This array operator returns a (smart) pointer to the channel corresponding to file descriptor \var{fd}.
+If there is no such channel in this channel set, the operator returns NIL.
+?*/
+pUchChannel
+UchBaseMultiplexer :: operator [] (int fd)
+{ }
+
+/*?
+Add a channel to the set.
+Here the argument is a reference, and a dynamically allocated copy of it is actually added.
+Compare with previous function.
+?*/
+void
+UchBaseMultiplexer :: Add (const UchChannel& ch)
+{ }
+
+#endif /* DOC */
+
+/*!
+This function is called by UchSignalHandlers when a signal is
+received. It just stores the signal for future (and safe) handling.
+!*/
+/*?hidden?*/
+void
+UchBaseMultiplexer :: HandleSignal (UchBaseSignalHandler& h)
+{
+ if (!SigFired)
+ AddSignalHook ();
+ SigFired = TRUE;
+ int sig = h.GetSignal () - 1;
+ /* We have to work with arrays, because we are in a signal
+ handler, and we cannot use lists */
+ Handlers [sig] = &h;
+ NbSignals [sig]++;
+
+}
+
+
+void
+UchBaseMultiplexer :: AddSignalHook ()
+{
+}
+
+void
+UchBaseMultiplexer :: HandleDeferredSignals ()
+{
+ CcuSignalBlocker b (AllSigs);
+ int c;
+ for (int i = 0; i < NSIG; ++i)
+ if (c = NbSignals [i]) {
+ Handlers [i]->DeferredHandle (c);
+ NbSignals [i] = 0;
+ Handlers [i] = 0;
+ }
+}
+
+static jmp_buf reset_run;
+
+class UchMpxAborter : public UchBaseSignalHandler {
+public:
+ UchMpxAborter (UchBaseMultiplexer& m, int s) : UchBaseSignalHandler (m, s) {}
+ void DeferredHandle (int) { MyMpx.Abort (); }
+};
+
+MPX_RES
+UchBaseMultiplexer :: Run ()
+{
+ if (setjmp (reset_run))
+ return isMpxAborted;
+
+ UchMpxAborter h1 (*this, SigTerm);
+ UchMpxAborter h2 (*this, SigInt);
+
+ return Loop ();
+}
+
+void
+UchBaseMultiplexer :: Abort ()
+{
+ if (Looping)
+ longjmp (reset_run, 1);
+}
+
+void
+UchBaseMultiplexer :: Close ()
+{
+ RemoveAll ();
+ Looping = FALSE;
+}
+
+UchMultiplexer :: UchMultiplexer ()
+: UchBaseMultiplexer (),
+ TimeOut (-1)
+{
+ FD_ZERO (&ReadMask);
+ FD_ZERO (&WriteMask);
+ FD_ZERO (&SelectMask);
+}
+
+UchMultiplexer :: ~UchMultiplexer ()
+{
+}
+
+
// update the masks when channel fd changes its mode
//
@@ -220,20 +315,6 @@ UchMultiplexer :: SetMasks (int fd, IOMODE mode)
}
-/*?nextdoc?*/
-void
-UchMultiplexer :: AddNotify (UchChannel*)
-{
- // nothing
-}
-
-/*?nextdoc?*/
-void
-UchMultiplexer :: RemoveNotify (UchChannel*)
-{
- // nothing
-}
-
/*?
This function calls the select handler of each channel of the set in select mode.
It returns TRUE as soon as one select handler returns true,
@@ -258,19 +339,6 @@ UchMultiplexer :: HandleSelect ()
return FALSE;
}
-/*?
-These virtual functions are called by the functions \fun{Add}, \fun{Remove}
-(and thus \fun{RemoveAll}) and \fun{SetMode}.
-They provide hooks for application that need to take special action when the
-set changes. They are called before the corresponding action is actually
-carried out.
-By default these functions do nothing.
-?*/
-void
-UchMultiplexer :: SetModeNotify (UchChannel*, IOMODE)
-{
- // nothing
-}
////// should add signal handling
/*?nextdoc?*/
@@ -366,11 +434,11 @@ an error occurs, the channel set has no more active channel
This can occur because the select, read or write handler of a channel may remove
the channel or change its mode.
This is usually done when the read handler detects an end of file.
-\fun{LoopScan} returns 0 when there are no more active channel in the set,
-it returns -1 when an error occured (the code is in \var{errno}),
-and it returns 1 if \fun{LoopEnd} was called.
+\fun{LoopScan} returns \var{isMpxEmpty} when there are no more active channel in the set,
+it returns \var{isMpxError} when an error occured (the code is in \var{errno}),
+and it returns \var{isMpxTerminated} if \fun{LoopEnd} or \fun{Close} was called.
?*/
-int
+MPX_RES
UchMultiplexer :: LoopScan (bool nointr)
{
fd_set rmsk, wmsk;
@@ -378,24 +446,17 @@ UchMultiplexer :: LoopScan (bool nointr)
Looping = TRUE;
for (fd0 = 0; Looping; fd0 < NFILE ? fd0++ : (fd0 = 0)) {
+
/* First, handle signals */
- if (SigFired) {
- CcuSignalBlocker b (AllSigs);
- int c;
- for (int i = 0; i < NSIG; ++i)
- if (c = NbSignals [i]) {
- Handlers [i]->DeferredHandle (c);
- NbSignals [i] = 0;
- Handlers [i] = 0;
- }
- }
+ if (SigFired)
+ HandleDeferredSignals ();
/* Then, timers */
CcuCoreTimer::Fire (&Timers);
/* Then, I/Os */
if (ReadCount == 0 && WriteCount == 0 && SelectCount == 0)
- return 0;
+ return isMpxEmpty;
for (fd = fd0, nfd = SelectCount; nfd; (fd < NFILE) ? fd++ : (fd = 0)) {
if (! FD_ISSET (fd, &SelectMask))
@@ -405,7 +466,7 @@ UchMultiplexer :: LoopScan (bool nointr)
break;
nfd--;
if (! Looping)
- return 1;
+ return isMpxTerminated;
}
if (nfd) // a handler returned TRUE.
continue;
@@ -425,7 +486,7 @@ UchMultiplexer :: LoopScan (bool nointr)
if (nfd < 0) {
if (nointr && nfd == -1 && errno == EINTR)
continue;
- return nfd;
+ return isMpxError;
}
for (fd = fd0; nfd; (fd < NFILE) ? fd++ : (fd = 0)) {
@@ -433,17 +494,17 @@ UchMultiplexer :: LoopScan (bool nointr)
nfd--;
Channels [fd] -> HandleWrite ();
if (! Looping)
- return 1;
+ return isMpxTerminated;
}
if (FD_ISSET (fd, &rmsk)) {
nfd--;
Channels [fd] -> HandleRead ();
if (! Looping)
- return 1;
+ return isMpxTerminated;
}
}
}
- return 1;
+ return isMpxTerminated;
}
// string repr
@@ -458,24 +519,6 @@ UchMultiplexer :: StrRepr (char* buf)
#ifdef DOC
// fake entries for inline functions
-
-/*?
-This array operator returns a (smart) pointer to the channel corresponding to file descriptor \var{fd}.
-If there is no such channel in this channel set, the operator returns NIL.
-?*/
-pUchChannel
-UchMultiplexer :: operator [] (int fd)
-{ }
-
-/*?
-Add a channel to the set.
-Here the argument is a reference, and a dynamically allocated copy of it is actually added.
-Compare with previous function.
-?*/
-void
-UchMultiplexer :: Add (const UchChannel& ch)
-{ }
-
/*?
This function makes \fun{LoopScan} exit immediately.
Thus it must be called from within a channel's handler.
@@ -487,12 +530,20 @@ UchMultiplexer :: LoopEnd ()
#endif /* DOC */
void
-UchMultiplexer :: RegisterSignal (UchBaseSignalHandler& h)
+UchMultiplexer :: SetTimeOut (Millisecond delay)
{
- SigFired = TRUE;
- int sig = h.GetSignal () - 1;
- /* We have to work with arrays, because we are in a signal
- handler, and we cannot use lists */
- Handlers [sig] = &h;
- NbSignals [sig]++;
+ CcuTimeStamp now;
+ TimeOut = now + delay;
+}
+
+void
+UchMultiplexer :: SuppressTimeOut ()
+{
+ TimeOut = -1;
+}
+
+MPX_RES
+UchMultiplexer :: Loop ()
+{
+ return LoopScan ();
}