reSIProcate/stack  9359
Public Member Functions | Protected Member Functions | Private Attributes
resip::SelectInterruptor Class Reference

Used to 'artificially' interrupt a select call. More...

#include <SelectInterruptor.hxx>

Inheritance diagram for resip::SelectInterruptor:
Inheritance graph
[legend]
Collaboration diagram for resip::SelectInterruptor:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SelectInterruptor ()
virtual ~SelectInterruptor ()
virtual void handleProcessNotification ()
 Called by the stack when messages are posted to it.
void interrupt ()
 cause the 'artificial' fd to signal
void buildFdSet (FdSet &fdset)
 Used to add the 'artificial' fd to the fdset that will be responsible for interrupting a subsequent select call.
void process (FdSet &fdset)
 cleanup signalled fd

Protected Member Functions

Socket getReadSocket () const
void processCleanup ()

Private Attributes

int mPipe [2]
Socket mReadThing

Detailed Description

Used to 'artificially' interrupt a select call.

Definition at line 21 of file SelectInterruptor.hxx.


Constructor & Destructor Documentation

SelectInterruptor::SelectInterruptor ( )

Definition at line 14 of file SelectInterruptor.cxx.

References len, resip::makeSocketNonBlocking(), mPipe, and mReadThing.

{
#ifdef WIN32
   mSocket = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

   sockaddr_in loopback;
   memset(&loopback, 0, sizeof(loopback));
   loopback.sin_family = AF_INET;
   loopback.sin_port = 0;
   loopback.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
   makeSocketNonBlocking(mSocket); //win32 woes
   ::bind( mSocket, reinterpret_cast<sockaddr*>(&loopback), sizeof(loopback));
   memset(&mWakeupAddr, 0, sizeof(mWakeupAddr));
   int len = sizeof(mWakeupAddr);
   int error = getsockname(mSocket, (sockaddr *)&mWakeupAddr, &len);
   assert(error == 0);
   error= connect(mSocket, &mWakeupAddr, sizeof(mWakeupAddr));
   assert(error == 0);
   mReadThing = mSocket;
#else
   int x = pipe(mPipe);
   (void)x;
   assert( x != -1 );
   // make write-side non-blocking to avoid deadlock
   makeSocketNonBlocking(mPipe[1]);
   // make read-side non-blocking so safe to read out entire pipe
   // all in one go (also just safer)
   makeSocketNonBlocking(mPipe[0]);
   mReadThing = mPipe[0];
#endif
}

Here is the call graph for this function:

SelectInterruptor::~SelectInterruptor ( ) [virtual]

Definition at line 46 of file SelectInterruptor.cxx.

References mPipe.

{
#ifdef WIN32
   closesocket(mSocket);
#else
   close(mPipe[0]);
   close(mPipe[1]);
#endif
}

Member Function Documentation

void SelectInterruptor::buildFdSet ( FdSet fdset)

Used to add the 'artificial' fd to the fdset that will be responsible for interrupting a subsequent select call.

Definition at line 63 of file SelectInterruptor.cxx.

References mPipe, and resip::FdSet::setRead().

Referenced by main(), resip::InterruptableStackThread::thread(), and waitForTwoStacks().

{
#ifdef WIN32
        fdset.setRead(mSocket);
#else
   fdset.setRead(mPipe[0]);
#endif
}

Here is the call graph for this function:

Socket resip::SelectInterruptor::getReadSocket ( ) const [inline, protected]

Definition at line 54 of file SelectInterruptor.hxx.

References mReadThing.

Referenced by resip::EventThreadInterruptor::EventThreadInterruptor().

{ return mReadThing; }
void SelectInterruptor::handleProcessNotification ( ) [virtual]

Called by the stack when messages are posted to it.

Calls interrupt.

Implements resip::AsyncProcessHandler.

Definition at line 57 of file SelectInterruptor.cxx.

References interrupt().

{
   interrupt();
}

Here is the call graph for this function:

void SelectInterruptor::interrupt ( )

cause the 'artificial' fd to signal

Definition at line 101 of file SelectInterruptor.cxx.

References errno, and mPipe.

Referenced by handleProcessNotification(), resip::InterruptableStackThread::shutdown(), resip::EventStackThread::shutdown(), and FakeApp::thread().

{
   static char wakeUp[] = "w";
#ifdef WIN32
   int count = send(mSocket, wakeUp, sizeof(wakeUp), 0);
   assert(count == sizeof(wakeUp));
#else
   ssize_t res = write(mPipe[1], wakeUp, sizeof(wakeUp));
   if ( res == -1 && errno==EAGAIN )
   {
      ; // this can happen when SipStack thread gets behind.
      // no need to block since our only purpose is to wake up the thread
      // also, this write can occur within the SipStack thread, in which
      // case we get dead-lock if this blocks
   } else {
      assert(res == sizeof(wakeUp));
   }
#endif
}
void SelectInterruptor::process ( FdSet fdset)

cleanup signalled fd

Definition at line 94 of file SelectInterruptor.cxx.

References mReadThing, processCleanup(), and resip::FdSet::readyToRead().

Referenced by main(), resip::InterruptableStackThread::thread(), and waitForTwoStacks().

Here is the call graph for this function:

void SelectInterruptor::processCleanup ( ) [protected]

Definition at line 73 of file SelectInterruptor.cxx.

References mPipe.

Referenced by process(), and resip::EventThreadInterruptor::processPollEvent().

{
#ifdef WIN32
   {
      char rdBuf[16];
      recv(mSocket, rdBuf, sizeof(rdBuf), 0);
   }
#else
   {
      char rdBuf[16];
      int x;
      while ( (x=read(mPipe[0], rdBuf, sizeof(rdBuf))) == sizeof(rdBuf) )
         ;
      // WATCHOUT: EWOULDBLOCK *will* happen above when the pending
      // number of bytes is exactly size of rdBuf
      // XXX: should check for certain errors (like fd closed) and die?
   }
#endif
}

Member Data Documentation

Definition at line 70 of file SelectInterruptor.hxx.

Referenced by getReadSocket(), process(), and SelectInterruptor().


The documentation for this class was generated from the following files: