Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
plevent.h File Reference
#include "prtypes.h"
#include "prclist.h"
#include "prthread.h"
#include "prlock.h"
#include "prcvar.h"
#include "prmon.h"
#include "nscore.h"

Go to the source code of this file.

Classes

struct  PLEvent

Defines

#define PL_ENTER_EVENT_QUEUE_MONITOR(queue)   PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
#define PL_EXIT_EVENT_QUEUE_MONITOR(queue)   PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
#define PREvent   PLEvent
#define PREventQueue   PLEventQueue
#define PR_CreateEventQueue   PL_CreateEventQueue
#define PR_DestroyEventQueue   PL_DestroyEventQueue
#define PR_GetEventQueueMonitor   PL_GetEventQueueMonitor
#define PR_ENTER_EVENT_QUEUE_MONITOR   PL_ENTER_EVENT_QUEUE_MONITOR
#define PR_EXIT_EVENT_QUEUE_MONITOR   PL_EXIT_EVENT_QUEUE_MONITOR
#define PR_PostEvent   PL_PostEvent
#define PR_PostSynchronousEvent   PL_PostSynchronousEvent
#define PR_GetEvent   PL_GetEvent
#define PR_EventAvailable   PL_EventAvailable
#define PREventFunProc   PLEventFunProc
#define PR_MapEvents   PL_MapEvents
#define PR_RevokeEvents   PL_RevokeEvents
#define PR_ProcessPendingEvents   PL_ProcessPendingEvents
#define PR_WaitForEvent   PL_WaitForEvent
#define PR_EventLoop   PL_EventLoop
#define PR_GetEventQueueSelectFD   PL_GetEventQueueSelectFD
#define PRHandleEventProc   PLHandleEventProc
#define PRDestroyEventProc   PLDestroyEventProc
#define PR_InitEvent   PL_InitEvent
#define PR_GetEventOwner   PL_GetEventOwner
#define PR_HandleEvent   PL_HandleEvent
#define PR_DestroyEvent   PL_DestroyEvent
#define PR_DequeueEvent   PL_DequeueEvent
#define PR_GetMainEventQueue   PL_GetMainEventQueue
#define PL_ENTER_EVENT_QUEUE_MONITOR(queue)   PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
#define PL_EXIT_EVENT_QUEUE_MONITOR(queue)   PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
#define PREvent   PLEvent
#define PREventQueue   PLEventQueue
#define PR_CreateEventQueue   PL_CreateEventQueue
#define PR_DestroyEventQueue   PL_DestroyEventQueue
#define PR_GetEventQueueMonitor   PL_GetEventQueueMonitor
#define PR_ENTER_EVENT_QUEUE_MONITOR   PL_ENTER_EVENT_QUEUE_MONITOR
#define PR_EXIT_EVENT_QUEUE_MONITOR   PL_EXIT_EVENT_QUEUE_MONITOR
#define PR_PostEvent   PL_PostEvent
#define PR_PostSynchronousEvent   PL_PostSynchronousEvent
#define PR_GetEvent   PL_GetEvent
#define PR_EventAvailable   PL_EventAvailable
#define PREventFunProc   PLEventFunProc
#define PR_MapEvents   PL_MapEvents
#define PR_RevokeEvents   PL_RevokeEvents
#define PR_ProcessPendingEvents   PL_ProcessPendingEvents
#define PR_WaitForEvent   PL_WaitForEvent
#define PR_EventLoop   PL_EventLoop
#define PR_GetEventQueueSelectFD   PL_GetEventQueueSelectFD
#define PRHandleEventProc   PLHandleEventProc
#define PRDestroyEventProc   PLDestroyEventProc
#define PR_InitEvent   PL_InitEvent
#define PR_GetEventOwner   PL_GetEventOwner
#define PR_HandleEvent   PL_HandleEvent
#define PR_DestroyEvent   PL_DestroyEvent
#define PR_DequeueEvent   PL_DequeueEvent
#define PR_GetMainEventQueue   PL_GetMainEventQueue
#define PL_ENTER_EVENT_QUEUE_MONITOR(queue)   PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
#define PL_EXIT_EVENT_QUEUE_MONITOR(queue)   PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
#define PREvent   PLEvent
#define PREventQueue   PLEventQueue
#define PR_CreateEventQueue   PL_CreateEventQueue
#define PR_DestroyEventQueue   PL_DestroyEventQueue
#define PR_GetEventQueueMonitor   PL_GetEventQueueMonitor
#define PR_ENTER_EVENT_QUEUE_MONITOR   PL_ENTER_EVENT_QUEUE_MONITOR
#define PR_EXIT_EVENT_QUEUE_MONITOR   PL_EXIT_EVENT_QUEUE_MONITOR
#define PR_PostEvent   PL_PostEvent
#define PR_PostSynchronousEvent   PL_PostSynchronousEvent
#define PR_GetEvent   PL_GetEvent
#define PR_EventAvailable   PL_EventAvailable
#define PREventFunProc   PLEventFunProc
#define PR_MapEvents   PL_MapEvents
#define PR_RevokeEvents   PL_RevokeEvents
#define PR_ProcessPendingEvents   PL_ProcessPendingEvents
#define PR_WaitForEvent   PL_WaitForEvent
#define PR_EventLoop   PL_EventLoop
#define PR_GetEventQueueSelectFD   PL_GetEventQueueSelectFD
#define PRHandleEventProc   PLHandleEventProc
#define PRDestroyEventProc   PLDestroyEventProc
#define PR_InitEvent   PL_InitEvent
#define PR_GetEventOwner   PL_GetEventOwner
#define PR_HandleEvent   PL_HandleEvent
#define PR_DestroyEvent   PL_DestroyEvent
#define PR_DequeueEvent   PL_DequeueEvent
#define PR_GetMainEventQueue   PL_GetMainEventQueue

Typedefs

typedef
typedefPR_BEGIN_EXTERN_C
struct 
PLEvent
typedef struct PLEventQueue
typedef void(PR_CALLBACKPLEventFunProc )(PLEvent *event, void *data, PLEventQueue *queue)
typedef void *(PR_CALLBACKPLHandleEventProc )(PLEvent *self)
typedef void(PR_CALLBACKPLDestroyEventProc )(PLEvent *self)

Functions

NS_COM PLEventQueuePL_CreateEventQueue (const char *name, PRThread *handlerThread)
NS_COM PLEventQueuePL_CreateNativeEventQueue (const char *name, PRThread *handlerThread)
NS_COM PLEventQueuePL_CreateMonitoredEventQueue (const char *name, PRThread *handlerThread)
NS_COM void PL_DestroyEventQueue (PLEventQueue *self)
NS_COM PRMonitorPL_GetEventQueueMonitor (PLEventQueue *self)
NS_COM PRStatus PL_PostEvent (PLEventQueue *self, PLEvent *event)
NS_COM voidPL_PostSynchronousEvent (PLEventQueue *self, PLEvent *event)
NS_COM PLEventPL_GetEvent (PLEventQueue *self)
NS_COM PRBool PL_EventAvailable (PLEventQueue *self)
NS_COM void PL_MapEvents (PLEventQueue *self, PLEventFunProc fun, void *data)
NS_COM void PL_RevokeEvents (PLEventQueue *self, void *owner)
NS_COM void PL_ProcessPendingEvents (PLEventQueue *self)
NS_COM PLEventPL_WaitForEvent (PLEventQueue *self)
NS_COM void PL_EventLoop (PLEventQueue *self)
NS_COM PRInt32 PL_GetEventQueueSelectFD (PLEventQueue *self)
NS_COM PRBool PL_IsQueueOnCurrentThread (PLEventQueue *queue)
NS_COM PRBool PL_IsQueueNative (PLEventQueue *queue)
NS_COM void PL_InitEvent (PLEvent *self, void *owner, PLHandleEventProc handler, PLDestroyEventProc destructor)
NS_COM voidPL_GetEventOwner (PLEvent *self)
NS_COM void PL_HandleEvent (PLEvent *self)
NS_COM void PL_DestroyEvent (PLEvent *self)
NS_COM void PL_DequeueEvent (PLEvent *self, PLEventQueue *queue)
NS_COM void PL_FavorPerformanceHint (PRBool favorPerformanceOverEventStarvation, PRUint32 starvationDelay)

Define Documentation

Definition at line 303 of file plevent.h.

Definition at line 306 of file plevent.h.

Definition at line 634 of file plevent.h.

Definition at line 656 of file plevent.h.

Definition at line 655 of file plevent.h.

Definition at line 635 of file plevent.h.

Definition at line 637 of file plevent.h.

Definition at line 642 of file plevent.h.

Definition at line 648 of file plevent.h.

Definition at line 638 of file plevent.h.

Definition at line 641 of file plevent.h.

Definition at line 653 of file plevent.h.

Definition at line 636 of file plevent.h.

Definition at line 649 of file plevent.h.

#define PR_GetMainEventQueue   PL_GetMainEventQueue

Definition at line 657 of file plevent.h.

#define PR_GetMainEventQueue   PL_GetMainEventQueue
#define PR_GetMainEventQueue   PL_GetMainEventQueue

Definition at line 654 of file plevent.h.

Definition at line 652 of file plevent.h.

Definition at line 644 of file plevent.h.

Definition at line 639 of file plevent.h.

Definition at line 640 of file plevent.h.

Definition at line 646 of file plevent.h.

Definition at line 645 of file plevent.h.

Definition at line 647 of file plevent.h.

Definition at line 651 of file plevent.h.

Definition at line 632 of file plevent.h.

Definition at line 643 of file plevent.h.

Definition at line 633 of file plevent.h.

Definition at line 650 of file plevent.h.


Typedef Documentation

Definition at line 445 of file plevent.h.

typedef typedefPR_BEGIN_EXTERN_C struct PLEvent

Definition at line 211 of file plevent.h.

Definition at line 350 of file plevent.h.

typedef struct PLEventQueue

Definition at line 212 of file plevent.h.

Definition at line 437 of file plevent.h.


Function Documentation

NS_COM PLEventQueue* PL_CreateEventQueue ( const char *  name,
PRThread handlerThread 
)

Definition at line 282 of file plevent.c.

{
    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
}

Here is the call graph for this function:

NS_COM PLEventQueue* PL_CreateMonitoredEventQueue ( const char *  name,
PRThread handlerThread 
)

Definition at line 294 of file plevent.c.

{
    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsMonitored ));
}

Here is the call graph for this function:

NS_COM PLEventQueue* PL_CreateNativeEventQueue ( const char *  name,
PRThread handlerThread 
)

Definition at line 288 of file plevent.c.

{
    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
}

Here is the call graph for this function:

NS_COM void PL_DequeueEvent ( PLEvent self,
PLEventQueue queue 
)

Definition at line 731 of file plevent.c.

{
    if (self == NULL)
        return;

    /* Only the owner is allowed to dequeue events because once the
       client has put it in the queue, they have no idea whether it's
       been processed and destroyed or not. */

    PR_ASSERT(queue->handlerThread == PR_GetCurrentThread());

    PR_EnterMonitor(queue->monitor);

    PR_ASSERT(!PR_CLIST_IS_EMPTY(&self->link));

#if 0
    /*  I do not think that we need to do this anymore.
        if we do not acknowledge and this is the only
        only event in the queue, any calls to process
        the eventQ will be effective noop.
    */
    if (queue->type == EventQueueIsNative)
      _pl_AcknowledgeNativeNotify(queue);
#endif

    PR_REMOVE_AND_INIT_LINK(&self->link);

    PR_ExitMonitor(queue->monitor);
}

Here is the call graph for this function:

Definition at line 708 of file plevent.c.

{
    if (self == NULL)
        return;

    /* This event better not be on an event queue anymore. */
    PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));

    if(self->condVar)
      PR_DestroyCondVar(self->condVar);
    if(self->lock)
      PR_DestroyLock(self->lock);

#ifdef PL_POST_TIMINGS
    s_totalTime += PR_IntervalNow() - self->postTime;
    s_eventCount++;
    printf("$$$ running avg (%d) \n", PR_IntervalToMilliseconds(s_totalTime/s_eventCount));
#endif

    self->destructor(self);
}

Here is the call graph for this function:

Definition at line 313 of file plevent.c.

{
    PR_EnterMonitor(self->monitor);

    /* destroy undelivered events */
    PL_MapEvents(self, _pl_destroyEvent, NULL);

    if ( self->type == EventQueueIsNative )
        _pl_CleanupNativeNotifier(self);

    /* destroying the monitor also destroys the name */
    PR_ExitMonitor(self->monitor);
    PR_DestroyMonitor(self->monitor);
    PR_DELETE(self);

}

Here is the call graph for this function:

Definition at line 476 of file plevent.c.

{
    PRBool result = PR_FALSE;

    if (self == NULL)
        return PR_FALSE;

    PR_EnterMonitor(self->monitor);

    if (!PR_CLIST_IS_EMPTY(&self->queue))
        result = PR_TRUE;

    PR_ExitMonitor(self->monitor);
    return result;
}

Here is the call graph for this function:

Definition at line 818 of file plevent.c.

{
    if (self == NULL)
        return;

    while (PR_TRUE) {
        PLEvent* event = PL_WaitForEvent(self);
        if (event == NULL) {
            /* This can only happen if the current thread is interrupted */
            return;
        }

        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
        PL_HandleEvent(event);
        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
    }
}

Here is the call graph for this function:

NS_COM void PL_FavorPerformanceHint ( PRBool  favorPerformanceOverEventStarvation,
PRUint32  starvationDelay 
)

Definition at line 762 of file plevent.c.

{
#if defined(_WIN32)

    _md_StarvationDelay = starvationDelay;

    if (favorPerformanceOverEventStarvation) {
        _md_PerformanceSetting++;
        return;
    }

    _md_PerformanceSetting--;

    if (_md_PerformanceSetting == 0) {
      /* Switched from allowing event starvation to no event starvation so grab
         the current time to determine when to actually switch to using timers
         instead of posted WM_APP messages. */
      _md_SwitchTime = PR_IntervalToMilliseconds(PR_IntervalNow());
    }

#endif
}

Definition at line 443 of file plevent.c.

{
    PLEvent* event = NULL;
    PRStatus err = PR_SUCCESS;

    if (self == NULL)
        return NULL;

    PR_EnterMonitor(self->monitor);

    if (!PR_CLIST_IS_EMPTY(&self->queue)) {
        if ( self->type == EventQueueIsNative &&
             self->notified                   &&
             !self->processingEvents          &&
             0 == _pl_GetEventCount(self)     )
        {
            err = _pl_AcknowledgeNativeNotify(self);
            self->notified = PR_FALSE;
        }
        if (err)
            goto done;

        /* then grab the event and return it: */
        event = PR_EVENT_PTR(self->queue.next);
        PR_REMOVE_AND_INIT_LINK(&event->link);
    }

  done:
    PR_ExitMonitor(self->monitor);
    return event;
}

Here is the call graph for this function:

Definition at line 673 of file plevent.c.

{
    return self->owner;
}

Definition at line 300 of file plevent.c.

{
    return self->monitor;
}

Definition at line 1368 of file plevent.c.

{
    if (self == NULL)
    return -1;

#if defined(VMS)
    return -(self->efn);
#elif defined(XP_UNIX) && !defined(XP_MACOSX)
    return self->eventPipe[0];
#else
    return -1;    /* other platforms don't handle this (yet) */
#endif
}

Definition at line 679 of file plevent.c.

{
    void* result;
    if (self == NULL)
        return;

    /* This event better not be on an event queue anymore. */
    PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));

    result = self->handler(self);
    if (NULL != self->synchronousResult) {
        PR_Lock(self->lock);
        self->synchronousResult = result;
        self->handled = PR_TRUE;
        PR_NotifyCondVar(self->condVar);
        PR_Unlock(self->lock);
    }
    else {
        /* For asynchronous events, they're destroyed by the event-handler
           thread. See PR_PostSynchronousEvent. */
        PL_DestroyEvent(self);
    }
}

Here is the call graph for this function:

NS_COM void PL_InitEvent ( PLEvent self,
void owner,
PLHandleEventProc  handler,
PLDestroyEventProc  destructor 
)

Definition at line 652 of file plevent.c.

{
#ifdef PL_POST_TIMINGS
    self->postTime = PR_IntervalNow();
#endif
    PR_INIT_CLIST(&self->link);
    self->handler = handler;
    self->destructor = destructor;
    self->owner = owner;
    self->synchronousResult = NULL;
    self->handled = PR_FALSE;
    self->lock = NULL;
    self->condVar = NULL;
#if defined(XP_UNIX) && !defined(XP_MACOSX)
    self->id = 0;
#endif
}

Definition at line 1390 of file plevent.c.

{
    return queue->type == EventQueueIsNative ? PR_TRUE : PR_FALSE;
}

Definition at line 1383 of file plevent.c.

{
    PRThread *me = PR_GetCurrentThread();
    return me == queue->handlerThread;
}

Here is the call graph for this function:

NS_COM void PL_MapEvents ( PLEventQueue self,
PLEventFunProc  fun,
void data 
)

Definition at line 493 of file plevent.c.

{
    PRCList* qp;

    if (self == NULL)
        return;

    PR_EnterMonitor(self->monitor);
    qp = self->queue.next;
    while (qp != &self->queue) {
        PLEvent* event = PR_EVENT_PTR(qp);
        qp = qp->next;
        (*fun)(event, data, self);
    }
    PR_ExitMonitor(self->monitor);
}

Here is the call graph for this function:

NS_COM PRStatus PL_PostEvent ( PLEventQueue self,
PLEvent event 
)

Definition at line 331 of file plevent.c.

{
    PRStatus err = PR_SUCCESS;
    PRMonitor* mon;

    if (self == NULL)
        return PR_FAILURE;

    mon = self->monitor;
    PR_EnterMonitor(mon);

#if defined(XP_UNIX) && !defined(XP_MACOSX)
    if (self->idFunc && event)
        event->id = self->idFunc(self->idFuncClosure);
#endif

    /* insert event into thread's event queue: */
    if (event != NULL) {
        PR_APPEND_LINK(&event->link, &self->queue);
    }

    if (self->type == EventQueueIsNative && !self->notified) {
        err = _pl_NativeNotify(self);

        if (err != PR_SUCCESS)
            goto error;

        self->notified = PR_TRUE;
    }

    /*
     * This may fall on deaf ears if we're really notifying the native
     * thread, and no one has called PL_WaitForEvent (or PL_EventLoop):
     */
    err = PR_Notify(mon);

error:
    PR_ExitMonitor(mon);
    return err;
}

Here is the call graph for this function:

Definition at line 373 of file plevent.c.

{
    void* result;

    if (self == NULL)
        return NULL;

    PR_ASSERT(event != NULL);

    if (PR_GetCurrentThread() == self->handlerThread) {
        /* Handle the case where the thread requesting the event handling
         * is also the thread that's supposed to do the handling. */
        result = event->handler(event);
    }
    else {
        int i, entryCount;

        event->lock = PR_NewLock();
        if (!event->lock) {
          return NULL;
        }
        event->condVar = PR_NewCondVar(event->lock);
        if(!event->condVar) {
          PR_DestroyLock(event->lock);
          event->lock = NULL;
          return NULL;
        }

        PR_Lock(event->lock);

        entryCount = PR_GetMonitorEntryCount(self->monitor);

        event->synchronousResult = (void*)PR_TRUE;

        PL_PostEvent(self, event);

        /* We need temporarily to give up our event queue monitor if
           we're holding it, otherwise, the thread we're going to wait
           for notification from won't be able to enter it to process
           the event. */
        if (entryCount) {
            for (i = 0; i < entryCount; i++)
                PR_ExitMonitor(self->monitor);
        }

        event->handled = PR_FALSE;

        while (!event->handled) {
            /* wait for event to be handled or destroyed */
            PR_WaitCondVar(event->condVar, PR_INTERVAL_NO_TIMEOUT);
        }

        if (entryCount) {
            for (i = 0; i < entryCount; i++)
                PR_EnterMonitor(self->monitor);
        }

        result = event->synchronousResult;
        event->synchronousResult = NULL;
        PR_Unlock(event->lock);
    }

    /* For synchronous events, they're destroyed here on the caller's
       thread before the result is returned. See PL_HandleEvent. */
    PL_DestroyEvent(event);

    return result;
}

Here is the call graph for this function:

Definition at line 592 of file plevent.c.

{
    PRInt32 count;

    if (self == NULL)
        return;


    PR_EnterMonitor(self->monitor);

    if (self->processingEvents) {
        _pl_AcknowledgeNativeNotify(self);
        self->notified = PR_FALSE;
        PR_ExitMonitor(self->monitor);
        return;
    }
    self->processingEvents = PR_TRUE;

    /* Only process the events that are already in the queue, and
     * not any new events that get added. Do this by counting the
     * number of events currently in the queue
     */
    count = _pl_GetEventCount(self);
    PR_ExitMonitor(self->monitor);

    while (count-- > 0) {
        PLEvent* event = PL_GetEvent(self);
        if (event == NULL)
            break;

        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
        PL_HandleEvent(event);
        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
    }

    PR_EnterMonitor(self->monitor);

    if (self->type == EventQueueIsNative) {
        count = _pl_GetEventCount(self);

        if (count <= 0) {
            _pl_AcknowledgeNativeNotify(self);
            self->notified = PR_FALSE;
        }
        else {
            _pl_NativeNotify(self);
            self->notified = PR_TRUE;
        }

    }
    self->processingEvents = PR_FALSE;

    PR_ExitMonitor(self->monitor);
}

Here is the call graph for this function:

NS_COM void PL_RevokeEvents ( PLEventQueue self,
void owner 
)

Definition at line 537 of file plevent.c.

{
    if (self == NULL)
        return;

    PR_LOG(event_lm, PR_LOG_DEBUG,
         ("$$$ revoking events for owner %0x", owner));

    /*
    ** First we enter the monitor so that no one else can post any events
    ** to the queue:
    */
    PR_EnterMonitor(self->monitor);
    PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ owner %0x, entered monitor", owner));

    /*
    ** Discard any pending events for this owner:
    */
    PL_MapEvents(self, _pl_DestroyEventForOwner, owner);

#ifdef DEBUG
    {
        PRCList* qp = self->queue.next;
        while (qp != &self->queue) {
            PLEvent* event = PR_EVENT_PTR(qp);
            qp = qp->next;
            PR_ASSERT(event->owner != owner);
        }
    }
#endif /* DEBUG */

    PR_ExitMonitor(self->monitor);

    PR_LOG(event_lm, PR_LOG_DEBUG,
           ("$$$ revoking events for owner %0x", owner));
}

Here is the call graph for this function:

Definition at line 794 of file plevent.c.

{
    PLEvent* event;
    PRMonitor* mon;

    if (self == NULL)
        return NULL;

    mon = self->monitor;
    PR_EnterMonitor(mon);

    while ((event = PL_GetEvent(self)) == NULL) {
        PRStatus err;
        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ waiting for event"));
        err = PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
        if ((err == PR_FAILURE)
            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
    }

    PR_ExitMonitor(mon);
    return event;
}

Here is the call graph for this function: