|
reSIProcate/stack
9359
|
Used to 'artificially' interrupt a select call. More...
#include <SelectInterruptor.hxx>


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 |
Used to 'artificially' interrupt a select call.
Definition at line 21 of file SelectInterruptor.hxx.
| 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
}

| SelectInterruptor::~SelectInterruptor | ( | ) | [virtual] |
Definition at line 46 of file SelectInterruptor.cxx.
References mPipe.
| 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().

| 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();
}

| void SelectInterruptor::interrupt | ( | ) |
cause the 'artificial' fd to signal
Definition at line 101 of file SelectInterruptor.cxx.
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().
{
if (fdset.readyToRead(mReadThing))
processCleanup();
}

| 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
}
int resip::SelectInterruptor::mPipe[2] [private] |
Definition at line 64 of file SelectInterruptor.hxx.
Referenced by buildFdSet(), interrupt(), processCleanup(), SelectInterruptor(), and ~SelectInterruptor().
Socket resip::SelectInterruptor::mReadThing [private] |
Definition at line 70 of file SelectInterruptor.hxx.
Referenced by getReadSocket(), process(), and SelectInterruptor().
1.7.5.1