Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
nsIEventQueueService.idl File Reference
import "nsISupports.idl";
import "nsIEventQueue.idl";
#include "prthread.h"
#include "plevent.h"

Go to the source code of this file.

Classes

struct  PLEvent
interface  nsIEventQueueService

Defines

#define NS_EVENTQUEUESERVICE_CID
#define NS_EVENTQUEUESERVICE_CONTRACTID   "@mozilla.org/event-queue-service;1"
#define NS_EVENTQUEUESERVICE_CLASSNAME   "Event Queue Service"
#define NS_CURRENT_THREAD   ((PRThread*)0)
#define NS_CURRENT_EVENTQ   ((nsIEventQueue*)0)
#define NS_UI_THREAD   ((PRThread*)1)
#define NS_UI_THREAD_EVENTQ   ((nsIEventQueue*)1)

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 63 of file nsIEventQueueService.idl.

Definition at line 62 of file nsIEventQueueService.idl.

Value:
{ 0xbe761f00, 0xa3b0, 0x11d2, \
  {0x99, 0x6c, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x80} }

Definition at line 55 of file nsIEventQueueService.idl.

#define NS_EVENTQUEUESERVICE_CLASSNAME   "Event Queue Service"

Definition at line 60 of file nsIEventQueueService.idl.

#define NS_EVENTQUEUESERVICE_CONTRACTID   "@mozilla.org/event-queue-service;1"

Definition at line 59 of file nsIEventQueueService.idl.

Definition at line 65 of file nsIEventQueueService.idl.

Definition at line 66 of file nsIEventQueueService.idl.


Typedef Documentation

Definition at line 446 of file nsIEventQueueService.idl.

typedef typedefPR_BEGIN_EXTERN_C struct PLEvent

Definition at line 212 of file nsIEventQueueService.idl.

Definition at line 351 of file nsIEventQueueService.idl.

typedef struct PLEventQueue

Definition at line 213 of file nsIEventQueueService.idl.

Definition at line 438 of file nsIEventQueueService.idl.


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 caller 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 ));
}
NS_COM PLEventQueue* PL_CreateNativeEventQueue ( const char *  name,
PRThread handlerThread 
)

Definition at line 288 of file plevent.c.

{
    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
}
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 caller 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);
}

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 caller 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 caller 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"));
    }
}
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
}

Here is the caller graph for this function:

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 caller graph for this function:

Definition at line 673 of file plevent.c.

{
    return self->owner;
}

Here is the caller graph for this function:

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 caller 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;
}

Here is the caller graph for this function:

Definition at line 1383 of file plevent.c.

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

Here is the caller 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 caller 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 caller 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;
}

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);
}
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 caller 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 caller graph for this function: