void EventThread::Entry()
{
// init current event variable
struct eventreq theCurrentEvent;
::memset( &theCurrentEvent, '\0', sizeof(theCurrentEvent) );
while (true)
{
int theErrno = EINTR;
while (theErrno == EINTR)
{
#if MACOSXEVENTQUEUE
// Apple os io events intercept
int theReturnValue = waitevent(&theCurrentEvent, NULL);
#else
// Linux etc io events intercept
int theReturnValue = select_waitevent(&theCurrentEvent, NULL);
#endif
//Sort of a hack. In the POSIX version of the server, waitevent can return
//an actual POSIX errorcode.
if (theReturnValue >= 0)
theErrno = theReturnValue;
else
theErrno = OSThread::GetErrno();
}
AssertV(theErrno == 0, theErrno);
// Some io event ready,
// theCurrentEvent is set in constructeventreq in as thus
// this->Entry --> select_waitevent --> constructeventreq, details below
// req->er_handle = fd;
// req->er_eventbits = event;
// req->er_data = sCookieArray[fd];
//ok, there's data waiting on this socket. Send a wakeup.
if (theCurrentEvent.er_data != NULL)
{
//The cookie in this event is an ObjectID. Resolve that objectID into
//a pointer.
StrPtrLen idStr((char*)&theCurrentEvent.er_data, sizeof(theCurrentEvent.er_data));
OSRef* ref = fRefTable.Resolve(&idStr);
if (ref != NULL)
{
// take task object from ref object
EventContext* theContext = (EventContext*)ref->GetObject();
#if DEBUG
theContext->fModwatched = false;
#endif
// theContext is a Socket object, it may be RTSPListenerSocket(TCPSocket),
// TCPSocket(general) and UDPSocket
// Each Socket is derived from EventContext.
// RTSPListenerSocket is derived from both EventContext and Task.
// TCPSocket(general), UDPSocket is only derived from EventContext, but
// associate with one Task object.
// as far as RTSPListenerSocket TCPSocket object, TCPListenerSocket's ProcessEvent called
// as far as other TCPSocket, UDPSocket object, the EventContext's
// ProcessEvent in EventContext.h called
// Notes: each TCPSocket, UDPSocket associate with one task object.
// RTSPListenerSocket object is itself a task object because it derived from Task.
theContext->ProcessEvent(theCurrentEvent.er_eventbits);
fRefTable.Release(ref);
}
}
#if EVENT_CONTEXT_DEBUG
SInt64 yieldStart = OS::Milliseconds();
#endif
this->ThreadYield();
#if EVENT_CONTEXT_DEBUG
SInt64 yieldDur = OS::Milliseconds() - yieldStart;
static SInt64 numZeroYields;
if ( yieldDur > 1 )
{
qtss_printf( "EventThread time in OSTHread::Yield %i, numZeroYields %i\n", (SInt32)yieldDur, (SInt32)numZeroYields );
numZeroYields = 0;
}
else
numZeroYields++;
#endif
}
}