libassa  3.5.1
Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
ASSA::Reactor Class Reference

#include <Reactor.h>

Public Member Functions

 Reactor ()
 Constructor. More...
 
 ~Reactor ()
 Destructor. More...
 
TimerId registerTimerHandler (EventHandler *eh_, const TimeVal &tv_, const std::string &name_="<unknown>")
 Register Timer Event handler with Reactor. More...
 
bool registerIOHandler (EventHandler *eh_, handler_t fd_, EventType et_=RWE_EVENTS)
 Register I/O Event handler with Reactor. More...
 
bool removeHandler (EventHandler *eh_, EventType et_=ALL_EVENTS)
 Remove Event handler from reactor for either all I/O events or timeout event or both. More...
 
bool removeTimerHandler (TimerId id_)
 Remove Timer event from the queue. More...
 
bool removeIOHandler (handler_t fd_)
 Remove IO Event handler from reactor. More...
 
void waitForEvents (void)
 Main waiting loop that blocks indefinitely processing events. More...
 
void waitForEvents (TimeVal *tv_)
 Wait for events for time specified. More...
 
void stopReactor (void)
 Stop Reactor's activity. More...
 
void deactivate (void)
 Deactivate Reactor. More...
 

Private Types

typedef std::map< u_int, EventHandler * > Fd2Eh_Map_Type
 no cloning More...
 
typedef Fd2Eh_Map_Type::iterator Fd2Eh_Map_Iter
 

Private Member Functions

 Reactor (const Reactor &)
 
Reactoroperator= (const Reactor &)
 no cloning More...
 
void adjust_maxfdp1 (handler_t fd_)
 Adjust maxfdp1 in a portable way (win32 ignores maxfd alltogether). More...
 
bool handleError (void)
 Handle error in select(2) loop appropriately. More...
 
bool dispatch (int minimum_)
 Notify all EventHandlers registered on respecful events occured. More...
 
int isAnyReady (void)
 Return number of file descriptors ready accross all sets. More...
 
bool checkFDs (void)
 Check mask for bad file descriptors. More...
 
void dispatchHandler (FdSet &mask_, Fd2Eh_Map_Type &fdSet_, EH_IO_Callback callback_)
 Call handler's callback and, if callback returns negative value, remove it from the Reactor. More...
 
void calculateTimeout (TimeVal *&howlong_, TimeVal *maxwait_)
 Calculate closest timeout. More...
 

Private Attributes

int m_fd_setsize
 Max number of open files per process. More...
 
handler_t m_maxfd_plus1
 Max file descriptor number (in all sets) plus 1. More...
 
bool m_active
 Flag that indicates whether Reactor is active or had been stopped. More...
 
Fd2Eh_Map_Type m_readSet
 Event handlers awaiting on READ_EVENT. More...
 
Fd2Eh_Map_Type m_writeSet
 Event handlers awaiting on WRITE_EVENT. More...
 
Fd2Eh_Map_Type m_exceptSet
 Event handlers awaiting on EXCEPT_EVENT. More...
 
MaskSet m_waitSet
 Handlers to wait for event on. More...
 
MaskSet m_readySet
 Handlers that are ready for processing. More...
 
TimerQueue m_tqueue
 The queue of Timers. More...
 

Detailed Description

Definition at line 57 of file Reactor.h.

Member Typedef Documentation

◆ Fd2Eh_Map_Iter

typedef Fd2Eh_Map_Type::iterator ASSA::Reactor::Fd2Eh_Map_Iter
private

Definition at line 155 of file Reactor.h.

◆ Fd2Eh_Map_Type

typedef std::map<u_int, EventHandler*> ASSA::Reactor::Fd2Eh_Map_Type
private

no cloning

Definition at line 154 of file Reactor.h.

Constructor & Destructor Documentation

◆ Reactor() [1/2]

Reactor::Reactor ( )

Constructor.

Maximum number of sockets supported (per process) Win32 defines it to 64 in winsock2.h.

Initialize winsock2 library

Definition at line 24 of file Reactor.cpp.

References m_fd_setsize, ASSA::REACTTRACE, trace_with_mask, and ~Reactor().

24  :
25  m_fd_setsize (1024),
26  m_maxfd_plus1 (0),
27  m_active (true)
28 {
29  trace_with_mask("Reactor::Reactor",REACTTRACE);
30 
34 #if defined(WIN32)
35  m_fd_setsize = FD_SETSIZE;
36 
37 #else // POSIX
38  struct rlimit rlim;
39  rlim.rlim_max = 0;
40 
41  if ( getrlimit (RLIMIT_NOFILE, &rlim) == 0 ) {
42  m_fd_setsize = rlim.rlim_cur;
43  }
44 #endif
45 
48 #if defined (WIN32)
49  WSADATA data;
50  WSAStartup (MAKEWORD (2, 2), &data);
51 #endif
52 }
handler_t m_maxfd_plus1
Max file descriptor number (in all sets) plus 1.
Definition: Reactor.h:206
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
bool m_active
Flag that indicates whether Reactor is active or had been stopped.
Definition: Reactor.h:209
int m_fd_setsize
Max number of open files per process.
Definition: Reactor.h:200

◆ ~Reactor()

Reactor::~Reactor ( )

Destructor.

Definition at line 55 of file Reactor.cpp.

References deactivate(), m_exceptSet, m_readSet, m_writeSet, ASSA::REACTTRACE, registerTimerHandler(), and trace_with_mask.

Referenced by Reactor().

56 {
57  trace_with_mask("Reactor::~Reactor",REACTTRACE);
58 
59  m_readSet.clear ();
60  m_writeSet.clear ();
61  m_exceptSet.clear ();
62  deactivate ();
63 }
Fd2Eh_Map_Type m_writeSet
Event handlers awaiting on WRITE_EVENT.
Definition: Reactor.h:215
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Fd2Eh_Map_Type m_readSet
Event handlers awaiting on READ_EVENT.
Definition: Reactor.h:212
void deactivate(void)
Deactivate Reactor.
Definition: Reactor.h:234
Fd2Eh_Map_Type m_exceptSet
Event handlers awaiting on EXCEPT_EVENT.
Definition: Reactor.h:218

◆ Reactor() [2/2]

ASSA::Reactor::Reactor ( const Reactor )
private

Member Function Documentation

◆ adjust_maxfdp1()

void Reactor::adjust_maxfdp1 ( handler_t  fd_)
private

Adjust maxfdp1 in a portable way (win32 ignores maxfd alltogether).

If the socket descriptor that has just been eliminated was the maxfd+1, we readjust to the next highest.

Win32 implementation of select() ignores this value altogether.

Definition at line 701 of file Reactor.cpp.

References DL, m_maxfd_plus1, m_waitSet, ASSA::MaskSet::max_fd(), ASSA::REACT, ASSA::REACTTRACE, and trace_with_mask.

Referenced by removeHandler(), removeIOHandler(), and stopReactor().

702 {
703 #if !defined (WIN32) /* POSIX */
704 
705  trace_with_mask("Reactor::adjust_maxfdp1", REACTTRACE);
706 
707  if (m_maxfd_plus1 == fd_ + 1)
708  {
709  m_maxfd_plus1 = m_waitSet.max_fd () + 1;
710  DL((REACT,"maxfd+1 adjusted to %d\n", m_maxfd_plus1));
711  }
712 #endif
713 }
handler_t m_maxfd_plus1
Max file descriptor number (in all sets) plus 1.
Definition: Reactor.h:206
MaskSet m_waitSet
Handlers to wait for event on.
Definition: Reactor.h:221
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
int max_fd()
Return maximum value of the file descriptor in the Set.
Definition: MaskSet.h:71

◆ calculateTimeout()

void Reactor::calculateTimeout ( TimeVal *&  howlong_,
TimeVal maxwait_ 
)
private

Calculate closest timeout.

If TimerQueue is not empty, then return smallest of maxtimeout and first in the queue. Otherwise, return maxtimeout.

Parameters
maxwait_(in) how long we are expected to wait for event(s).
howlong_(out) how long we are going to wait.

Definition at line 421 of file Reactor.cpp.

References DL, ASSA::TimerQueue::dump(), ASSA::TimeVal::gettimeofday(), ASSA::TimerQueue::isEmpty(), m_tqueue, ASSA::REACT, ASSA::REACTTRACE, ASSA::TimerQueue::top(), trace_with_mask, waitForEvents(), and ASSA::TimeVal::zeroTime().

Referenced by isAnyReady(), and waitForEvents().

422 {
423  trace_with_mask("Reactor::calculateTimeout",REACTTRACE);
424 
425  TimeVal now;
426  TimeVal tv;
427 
428  if (m_tqueue.isEmpty () ) {
429  howlong_ = maxwait_;
430  goto done;
431  }
432  now = TimeVal::gettimeofday ();
433  tv = m_tqueue.top ();
434 
435  if (tv < now) {
436  /*---
437  It took too long to get here (fraction of a millisecond),
438  and top timer had already expired. In this case,
439  perform non-blocking select in order to drain the timer queue.
440  ---*/
441  *howlong_ = 0;
442  }
443  else {
444  DL((REACT,"--------- Timer Queue ----------\n"));
445  m_tqueue.dump();
446  DL((REACT,"--------------------------------\n"));
447 
448  if (maxwait_ == NULL || *maxwait_ == TimeVal::zeroTime ()) {
449  *howlong_ = tv - now;
450  }
451  else {
452  *howlong_ = (*maxwait_+now) < tv ? *maxwait_ : tv-now;
453  }
454  }
455 
456  done:
457  if (howlong_ != NULL) {
458  DL((REACT,"delay (%f)\n", double (*howlong_) ));
459  }
460  else {
461  DL((REACT,"delay (forever)\n"));
462  }
463 }
static TimeVal zeroTime()
Static that returns zero timeval: {0,0}.
Definition: TimeVal.h:157
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
void dump(void)
Dump Queue information to the log file.
Definition: TimerQueue.cpp:152
TimeVal & top(void)
Return expiration time of the top element in the queue.
Definition: TimerQueue.h:117
bool isEmpty()
Is queue empty?
Definition: TimerQueue.h:110
TimerQueue m_tqueue
The queue of Timers.
Definition: Reactor.h:227
static TimeVal gettimeofday()
Shields off underlying OS differences in getting current time.
Definition: TimeVal.cpp:44

◆ checkFDs()

bool Reactor::checkFDs ( void  )
private

Check mask for bad file descriptors.

Returns
true if any fd(s) were found and removed; false otherwise

Definition at line 317 of file Reactor.cpp.

References ASSA::FdSet::clear(), DL, handleError(), m_fd_setsize, m_readSet, ASSA::REACT, ASSA::REACTTRACE, removeIOHandler(), ASSA::FdSet::setFd(), and trace_with_mask.

Referenced by handleError(), and removeIOHandler().

318 {
319  trace_with_mask("Reactor::checkFDs",REACTTRACE);
320 
321  bool num_removed = false;
322  FdSet mask;
323  timeval poll = { 0, 0 };
324 
325  for (handler_t fd = 0; fd < m_fd_setsize; fd++) {
326  if ( m_readSet[fd] != NULL ) {
327  mask.setFd (fd);
328  if ( ::select (fd+1, &mask, NULL, NULL, &poll) < 0 ) {
329  removeIOHandler (fd);
330  num_removed = true;
331  DL((REACT,"Detected BAD FD: %d\n", fd ));
332  }
333  mask.clear (fd);
334  }
335  }
336  return (num_removed);
337 }
bool clear(handler_t fd_)
Clear flag (OFF) for the argument fd.
Definition: FdSet.cpp:39
bool setFd(handler_t fd_)
Set flag (ON) for the argument fd.
Definition: FdSet.cpp:20
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
bool removeIOHandler(handler_t fd_)
Remove IO Event handler from reactor.
Definition: Reactor.cpp:247
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
int handler_t
Definition: Logger_Impl.h:82
Fd2Eh_Map_Type m_readSet
Event handlers awaiting on READ_EVENT.
Definition: Reactor.h:212
Class FdSet.
Definition: FdSet.h:51
int m_fd_setsize
Max number of open files per process.
Definition: Reactor.h:200

◆ deactivate()

void ASSA::Reactor::deactivate ( void  )
inline

Deactivate Reactor.

This function sets internal flag which notifies Reactor's internal event handling loop to abort its activity. It is mostly used when a slow system call is interrupted by the signal handler. The system call will be restarted by OS after control returns from the signal handler. Signal handler (GenServer::handle_signal()) should call this method to delay Reactor's deactivation.

Definition at line 234 of file Reactor.h.

References m_active.

Referenced by ASSA::GenServer::handle_signal(), ASSA::GenServer::stop_service(), and ~Reactor().

234 { m_active = false; }
bool m_active
Flag that indicates whether Reactor is active or had been stopped.
Definition: Reactor.h:209

◆ dispatch()

bool Reactor::dispatch ( int  minimum_)
private

Notify all EventHandlers registered on respecful events occured.

Many UNIX systems will count a particular file descriptor in the ready_ only ONCE, even if it was flagged by select(2) in, say, both read and write masks.

Parameters
minimum_number of file descriptors ready.

Definition at line 626 of file Reactor.cpp.

References ASSA::ASSAERR, dispatchHandler(), DL, ASSA::MaskSet::dump(), EL, ASSA::TimerQueue::expire(), ASSA::TimeVal::gettimeofday(), ASSA::EventHandler::handle_except(), ASSA::EventHandler::handle_read(), ASSA::EventHandler::handle_write(), ASSA::MaskSet::m_eset, m_exceptSet, m_readSet, m_readySet, ASSA::MaskSet::m_rset, m_tqueue, m_writeSet, ASSA::MaskSet::m_wset, ASSA::REACT, ASSA::REACTTRACE, stopReactor(), and trace_with_mask.

Referenced by dispatchHandler(), and waitForEvents().

627 {
628  trace_with_mask("Reactor::dispatch", REACTTRACE);
629 
631 
632  if ( ready_ < 0 )
633  {
634 #if !defined (WIN32)
635  EL((ASSAERR,"::select(3) error\n"));
636 #endif
637  return (false);
638  }
639  if ( ready_ == 0 ) {
640  return (true);
641  }
642 
643  DL((REACT,"Dispatching %d FDs.\n",ready_));
644  DL((REACT,"m_readySet:\n"));
645  m_readySet.dump ();
646 
647  /*--- Writes first ---*/
649  m_writeSet,
651 
652  /*--- Exceptions next ---*/
654  m_exceptSet,
656 
657  /*--- Finally, the Reads ---*/
659  m_readSet,
661 
662  return (true);
663 }
ASSA and system errors.
Definition: LogMask.h:34
virtual int handle_write(int fd)
Write handler callback.
Definition: EventHandler.h:180
int expire(const TimeVal &tv_)
Traverse the queue, triggering all timers that are past argument timeval.
Definition: TimerQueue.cpp:89
Fd2Eh_Map_Type m_writeSet
Event handlers awaiting on WRITE_EVENT.
Definition: Reactor.h:215
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
FdSet m_eset
Exception fds set.
Definition: MaskSet.h:34
#define EL(X)
A macro for writing error message to the Logger.
Definition: Logger.h:285
virtual int handle_read(int fd)
Read event callback.
Definition: EventHandler.h:172
void dump()
Write current state of MaskSet object to log file.
Definition: MaskSet.h:80
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
Fd2Eh_Map_Type m_readSet
Event handlers awaiting on READ_EVENT.
Definition: Reactor.h:212
virtual int handle_except(int fd)
Exception handler callback.
Definition: EventHandler.h:188
TimerQueue m_tqueue
The queue of Timers.
Definition: Reactor.h:227
FdSet m_wset
Write fds set.
Definition: MaskSet.h:31
void dispatchHandler(FdSet &mask_, Fd2Eh_Map_Type &fdSet_, EH_IO_Callback callback_)
Call handler&#39;s callback and, if callback returns negative value, remove it from the Reactor...
Definition: Reactor.cpp:568
FdSet m_rset
Read fds set.
Definition: MaskSet.h:28
Fd2Eh_Map_Type m_exceptSet
Event handlers awaiting on EXCEPT_EVENT.
Definition: Reactor.h:218
static TimeVal gettimeofday()
Shields off underlying OS differences in getting current time.
Definition: TimeVal.cpp:44
MaskSet m_readySet
Handlers that are ready for processing.
Definition: Reactor.h:224

◆ dispatchHandler()

void Reactor::dispatchHandler ( FdSet mask_,
Fd2Eh_Map_Type fdSet_,
EH_IO_Callback  callback_ 
)
private

Call handler's callback and, if callback returns negative value, remove it from the Reactor.

This spot needs re-thinking.

When you have several high data-rate connections sending data at the same time, the one that had connected first would get lower FD number and would get data transfer preference over everybody else who has connected later on.

WIN32 HACK: Without having restarted scan from the beginning, this causes crash due to the fact that firing a callback of EventHandler might have invalidated the iterator (happens with Connector's in a sync mode).

Definition at line 568 of file Reactor.cpp.

References ASSA::FdSet::clear(), dispatch(), DL, ASSA::EventHandler::get_id(), ASSA::FdSet::isSet(), ASSA::REACT, ASSA::REACTTRACE, removeIOHandler(), and trace_with_mask.

Referenced by dispatch(), and waitForEvents().

569 {
570  trace_with_mask("Reactor::dispatchHandler",REACTTRACE);
571 
572  int ret = 0;
573  handler_t fd;
574  EventHandler* ehp = NULL;
575  std::string eh_id;
576 
577  Fd2Eh_Map_Iter iter = fdSet_.begin ();
578 
579  while (iter != fdSet_.end ())
580  {
581  fd = (*iter).first;
582  ehp = (*iter).second;
583 
584  if (mask_.isSet (fd) && ehp != NULL)
585  {
586  eh_id = ehp->get_id ();
587  DL((REACT,"Data detected from \"%s\"(fd=%d)\n",
588  eh_id.c_str (), fd));
589 
590  ret = (ehp->*callback_) (fd); /* Fire up a callback */
591 
592  if (ret == -1) {
593  removeIOHandler (fd);
594  }
595  else if (ret > 0) {
596  DL((REACT,"%d bytes pending on fd=%d \"%s\"\n",
597  ret, fd, eh_id.c_str ()));
598  //return; <-- would starve other connections
599  }
600  else {
601  DL((REACT,"All data from \"%s\"(fd=%d) are consumed\n",
602  eh_id.c_str (), fd));
603  mask_.clear (fd);
604  }
611  iter = fdSet_.begin ();
612  }
613  else {
614  iter++;
615  }
616  }
617 }
bool clear(handler_t fd_)
Clear flag (OFF) for the argument fd.
Definition: FdSet.cpp:39
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
bool removeIOHandler(handler_t fd_)
Remove IO Event handler from reactor.
Definition: Reactor.cpp:247
bool isSet(handler_t fd_)
Test whether fd&#39;s flag is on.
Definition: FdSet.h:122
std::string get_id() const
Retrieve EventHandler ID.
Definition: EventHandler.h:157
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
int handler_t
Definition: Logger_Impl.h:82
Fd2Eh_Map_Type::iterator Fd2Eh_Map_Iter
Definition: Reactor.h:155
EventHandler class.
Definition: EventHandler.h:102

◆ handleError()

bool Reactor::handleError ( void  )
private

Handle error in select(2) loop appropriately.

If commanded to stop, do so

Definition at line 341 of file Reactor.cpp.

References ASSA::ASSAERR, checkFDs(), DL, EL, isAnyReady(), m_active, ASSA::REACT, ASSA::REACTTRACE, and trace_with_mask.

Referenced by checkFDs(), and waitForEvents().

342 {
343  trace_with_mask("Reactor::handleError",REACTTRACE);
344 
347  if ( !m_active ) {
348  DL((REACT,"Received cmd to stop Reactor\n"));
349  return (false);
350  }
351 
352  /*---
353  TODO: If select(2) returns before time expires, with
354  a descriptor ready or with EINTR, timeval is not
355  going to be updated with number of seconds remaining.
356  This is true for all systems except Linux, which will
357  do so. Therefore, to restart correctly in case of
358  EINTR, we ought to take time measurement before and
359  after select, and try to select() for remaining time.
360 
361  For now, we restart with the initial timing value.
362  ---*/
363  /*---
364  BSD kernel never restarts select(2). SVR4 will restart if
365  the SA_RESTART flag is specified when the signal handler
366  for the signal delivered is installed. This means taht for
367  portability, we must handle signal interrupts.
368  ---*/
369 
370  if ( errno == EINTR ) {
371  EL((REACT,"EINTR: interrupted select(2)\n"));
372  /*
373  If I was sitting in select(2) and received SIGTERM,
374  the signal handler would have set m_active to 'false',
375  and this function would have returned 'false' as above.
376  For any other non-critical signals (USR1,...),
377  we retry select.
378  */
379  return (true);
380  }
381  /*
382  EBADF - bad file number. One of the file descriptors does
383  not reference an open file to open(), close(), ioctl().
384  This can happen if user closed fd and forgot to remove
385  handler from Reactor.
386  */
387  if ( errno == EBADF ) {
388  DL((REACT,"EBADF: bad file descriptor\n"));
389  return (checkFDs ());
390  }
391  /*
392  Any other error from select
393  */
394 #if defined (WIN32)
395  DL ((REACT,"select(3) error = %d\n", WSAGetLastError()));
396 #else
397  EL((ASSAERR,"select(3) error\n"));
398 #endif
399  return (false);
400 }
ASSA and system errors.
Definition: LogMask.h:34
#define DL(X)
A macro for writing debug message to the Logger.
Definition: Logger.h:273
#define trace_with_mask(s, m)
trace_with_mask() is used to trace function call chain in C++ program.
Definition: Logger.h:437
#define EL(X)
A macro for writing error message to the Logger.
Definition: Logger.h:285
Extended Reactor/PrioriyQueue messages.
Definition: LogMask.h:40
Class Reactor/PrioriyQueue messages.
Definition: LogMask.h:39
bool m_active
Flag that indicates whether Reactor is active or had been stopped.
Definition: Reactor.h:209
bool checkFDs(void)
Check mask for bad file descriptors.
Definition: Reactor.cpp:317

◆ isAnyReady()

int Reactor::isAnyReady ( void  )
private

Return number of file descriptors ready accross all sets.

Definition at line 404 of file Reactor.cpp.

References calculateTimeout(), DL, ASSA::MaskSet::dump(), ASSA::MaskSet::m_eset, m_readySet, ASSA::MaskSet::m_rset, ASSA::MaskSet::m_wset, ASSA::FdSet::numSet(), ASSA::REACT, ASSA::REACTTRACE, and trace_with_mask.

Referenced by handleError(), and waitForEvents().

405 {
406  trace_with_mask("Reactor::isAnyReady",REACTTRACE);
407 
408  int n = m_readySet.m_rset.numSet () +
411 
412  if ( n > 0 ) {
413  DL((REACT,"m_readySet: %d FDs are ready for