void EventThread::Entry()
{
    struct eventreq theCurrentEvent;
    ::memset( &theCurrentEvent, '\0', sizeof(theCurrentEvent) );

    while (!IsStopRequested())
    {
        int theErrno = EINTR;
        while (theErrno == EINTR)
        {
#if MACOSXEVENTQUEUE
            int theReturnValue = waitevent(&theCurrentEvent, NULL);
#else
            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();
            if(IsStopRequested()) break;
        }
        if (IsStopRequested()) break;

        AssertV(theErrno == 0, theErrno);

        //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)
            {
                EventContext* theContext = (EventContext*)ref->GetObject();
#if DEBUG
                theContext->fModwatched = false;
#endif
                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
    }
}
示例#2
0
void OSEventThread::Entry()
{
    int n;
    fd_set rfds;
    struct timeval tv;
    struct timeval * ptv = NULL;

    ULONG lasttime = OS::GetTickCount();
    ULONG currtime = lasttime;

    init_wakeuper();

    while (!IsStopRequested()) {

        //10 check time rollback
        lasttime = currtime;
        currtime = OS::GetTickCount();
        if(currtime < lasttime) {
            rollback_timer(currtime);
            firePending();
        }

        //20 calc timeout
        if (-1 == calcNextTimeout(&tv,currtime)) {
            // no pending timers; block indefinitely
            TRACE("~~~~ no timers; blocking indefinitely ~~~~\n");
            ptv = NULL;
        } else {
            TRACE("~~~~ blocking for %ds + %dus ~~~~\n", (int)tv.tv_sec, (int)tv.tv_usec);
            ptv = &tv;
        }

        //30 make local copy of read fd_set
        memcpy(&rfds, &mReadFds, sizeof(fd_set));

        //40 select
        n = select(mMaxfFd, &rfds, NULL, NULL, ptv);

        TRACE("~~~~ %d events fired ~~~~\n", n);
        
        if(n > 0){

            //50 Check for read-ready
            processReadReadies(&rfds, n);

        }else if(n == 0){

            //60 Check for timeouts
            processTimeouts();

        }else{

            //70 check error
            int err = OSThread::GetErrno();
            switch(err)
            {
            case EINTR:
                continue;
            case EBADF:
                WARN("event_req: EBADF\n");
				continue;
            case ENOTCONN:
                ERR("event_req: ENOTCONN\n");
                continue;
            default:
                ERR("event_req: select error (%d)\n", err);
                ASSERT_C(0);
                return;
            }
        }


        //80 Fire away
        firePending();
    }

    uninit_wakeuper();

    TRACE("~~~~ Thread exit:%x ~~~~\n",(unsigned int)GetCurrentThreadID());
}