Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
nsEventQueueImpl Class Reference

#include <nsEventQueue.h>

Inheritance diagram for nsEventQueueImpl:
Inheritance graph
[legend]
Collaboration diagram for nsEventQueueImpl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsEventQueueImpl ()
NS_IMETHOD AppendQueue (nsIEventQueue *aQueue)
 Add the given queue as the new youngest member of our chain.
NS_IMETHOD Unlink ()
 Remove this element from the chain.
NS_IMETHOD GetYoungest (nsIEventQueue **aQueue)
 Fetch (and addref) the youngest member of the chain.
NS_IMETHOD GetYoungestActive (nsIEventQueue **aQueue)
 Fetch (and addref) the youngest member of the chain which is still accepting events.
NS_IMETHOD SetYounger (nsPIEventQueueChain *aQueue)
NS_IMETHOD GetYounger (nsIEventQueue **aQueue)
NS_IMETHOD SetElder (nsPIEventQueueChain *aQueue)
NS_IMETHOD GetElder (nsIEventQueue **aQueue)
NS_IMETHOD RevokeEventsInternal (void *aOwner)
 Revoke events for aOwner in this queue and all elder queues.
void initEvent (in PLEventPtr aEvent, in voidPtr owner, in PLHandleEventProc handler, in PLDestroyEventProc destructor)
void postSynchronousEvent (in PLEventPtr aEvent, out voidPtr aResult)
boolean pendingEvents ()
void processPendingEvents ()
void eventLoop ()
void eventAvailable (in PRBoolRef aResult)
PLEventPtr getEvent ()
void handleEvent (in PLEventPtr aEvent)
PLEventPtr waitForEvent ()
PRInt32 getEventQueueSelectFD ()
void init (in boolean aNative)
void initFromPRThread (in PRThreadPtr thread, in boolean aNative)
void initFromPLQueue (in PLEventQueuePtr aQueue)
void enterMonitor ()
void exitMonitor ()
void revokeEvents (in voidPtr owner)
 Revoke events in this event queue and all other event queues for this thread that have |owner| as the event owner.
PLEventQueuePtr getPLEventQueue ()
boolean isQueueNative ()
void stopAcceptingEvents ()
void postEvent (in PLEventPtr aEvent)
 Method for posting an asynchronous event to the event target.
boolean isOnCurrentThread ()
 This method returns true if the event target is the current thread.
 NS_DEFINE_STATIC_IID_ACCESSOR (NS_IEVENTQUEUECHAIN_IID)

Static Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIEVENTTARGET static
NS_DECL_NSIEVENTQUEUE
NS_METHOD 
Create (nsISupports *outer, const nsIID &aIID, void **aInstancePtr)
static const nsCIDCID ()

Private Member Functions

 ~nsEventQueueImpl ()
void NotifyObservers (const char *aTopic)
void CheckForDeactivation ()

Private Attributes

PLEventQueuemEventQueue
PRBool mAcceptingEvents
PRBool mCouldHaveEvents
nsCOMPtr< nsPIEventQueueChainmElderQueue
nsPIEventQueueChainmYoungerQueue

Detailed Description

Definition at line 43 of file nsEventQueue.h.


Constructor & Destructor Documentation

Definition at line 95 of file nsEventQueue.cpp.

{
  NS_ADDREF_THIS();
  /* The slightly weird ownership model for eventqueues goes like this:

     General:
       There's an addref from the factory generally held by whoever asked for
     the queue. The queue addrefs itself (right here) and releases itself
     after someone calls StopAcceptingEvents() on the queue and when it is
     dark and empty (in CheckForDeactivation()).

     Chained queues:

       Eldest queue:
         The eldest queue in a chain is held on to by the EventQueueService
       in a hash table, so it is possible that the eldest queue may not be
       released until the EventQueueService is shutdown.
         You may not call StopAcceptingEvents() on this queue until you have
       done so on all younger queues.

       General:
         Each queue holds a reference to their immediate elder link and a weak
       reference to their immediate younger link.  Because you must shut down
       queues from youngest to eldest, all the references will be removed.

       It happens something like:
         queue->StopAcceptingEvents()
         {
           CheckForDeactivation()
           {
             -- hopefully we are able to shutdown now --
             Unlink()
             {
               -- remove the reference we hold to our elder queue  --
               -- NULL out our elder queues weak reference to us --
             }
             RELEASE ourself (to balance the ADDREF here in the constructor)
             -- and we should go away. --
           }
         }


     Notes:
       A dark queue no longer accepts events.  An empty queue simply has no events.
  */

#if defined(PR_LOGGING) && defined(DEBUG_danm)
  PR_LOG(gEventQueueLog, PR_LOG_DEBUG,
         ("EventQueue: Created [queue=%lx]",(long)mEventQueue));
  ++gEventQueueLogCount;
#endif

  mYoungerQueue = nsnull;
  mEventQueue = nsnull;
  mAcceptingEvents = PR_TRUE;
  mCouldHaveEvents = PR_TRUE;
}

Here is the caller graph for this function:

Definition at line 153 of file nsEventQueue.cpp.

{
  Unlink();

#if defined(PR_LOGGING) && defined(DEBUG_danm)
  PR_LOG(gEventQueueLog, PR_LOG_DEBUG,
         ("EventQueue: Destroyed [queue=%lx]",(long)mEventQueue));
  ++gEventQueueLogCount;
#endif

  if (mEventQueue) {
    // Perhaps CheckForDeactivation wasn't called...
    if (mCouldHaveEvents)
      NotifyObservers(gDestroyedNotification);
    PL_DestroyEventQueue(mEventQueue);
  }
}

Here is the call graph for this function:


Member Function Documentation

Add the given queue as the new youngest member of our chain.

It will not be addrefed.

Parameters:
aQueuethe queue. must not be null.
Returns:
error indication

Implements nsPIEventQueueChain.

Definition at line 562 of file nsEventQueue.cpp.

{
  nsresult      rv;
  nsCOMPtr<nsIEventQueue> end;
  nsCOMPtr<nsPIEventQueueChain> queueChain(do_QueryInterface(aQueue));

  if (!aQueue)
    return NS_ERROR_NO_INTERFACE;

/* this would be nice
  NS_ASSERTION(aQueue->mYoungerQueue == NULL && aQueue->mElderQueue == NULL,
               "event queue repeatedly appended to queue chain");
*/
  rv = NS_ERROR_NO_INTERFACE;

#ifdef NS_DEBUG
  int depth = 0;
  nsEventQueueImpl *next = this;
  while (next && depth < 100) {
    next = NS_STATIC_CAST(nsEventQueueImpl *, next->mYoungerQueue);
    ++depth;
  }
  if (depth > 5) {
    char warning[80];
    PR_snprintf(warning, sizeof(warning),
      "event queue chain length is %d. this is almost certainly a leak.", depth);
    NS_WARNING(warning);
  }
#endif

  // (be careful doing this outside nsEventQueueService's mEventQMonitor)

  GetYoungest(getter_AddRefs(end));
  nsCOMPtr<nsPIEventQueueChain> endChain(do_QueryInterface(end));
  if (endChain) {
    endChain->SetYounger(queueChain);
    queueChain->SetElder(endChain);
    rv = NS_OK;
  }
  return rv;
}

Here is the call graph for this function:

Definition at line 273 of file nsEventQueue.cpp.

{
  if (mCouldHaveEvents && !mAcceptingEvents && !PL_EventAvailable(mEventQueue)) {
    if (PL_IsQueueOnCurrentThread(mEventQueue)) {
      mCouldHaveEvents = PR_FALSE;
      NotifyObservers(gDestroyedNotification);
      NS_RELEASE_THIS(); // balance ADDREF from the constructor
    } else
      NS_ERROR("CheckForDeactivation called from wrong thread!");
  }
}

Here is the call graph for this function:

static const nsCID& nsEventQueueImpl::CID ( ) [inline, static]

Definition at line 56 of file nsEventQueue.h.

{ static nsCID cid = NS_EVENTQUEUE_CID; return cid; }
NS_METHOD nsEventQueueImpl::Create ( nsISupports *  outer,
const nsIID aIID,
void **  aInstancePtr 
) [static]

Definition at line 545 of file nsEventQueue.cpp.

{
  nsEventQueueImpl* evt = new nsEventQueueImpl();
  if (evt == NULL)
    return NS_ERROR_OUT_OF_MEMORY;
  nsresult rv = evt->QueryInterface(aIID, aResult);
  if (NS_FAILED(rv)) {
    delete evt;
  }
  return rv;
}

Here is the call graph for this function:

void nsIEventQueue::eventAvailable ( in PRBoolRef  aResult) [inherited]
void nsIEventQueue::eventLoop ( ) [inherited]

Implements nsPIEventQueueChain.

Definition at line 685 of file nsEventQueue.cpp.

{
  if (!mElderQueue) {
    *aQueue = nsnull;
    return NS_OK;
  }
  return mElderQueue->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&aQueue);
}

Implements nsPIEventQueueChain.

Definition at line 675 of file nsEventQueue.cpp.

{
  if (!mYoungerQueue) {
    *aQueue = nsnull;
    return NS_OK;
  }
  return mYoungerQueue->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&aQueue);
}

Fetch (and addref) the youngest member of the chain.

Parameters:
*aQueuethe youngest queue. aQueue must not be null.
Returns:
error indication

Implements nsPIEventQueueChain.

Definition at line 633 of file nsEventQueue.cpp.

{
  if (mYoungerQueue)
    return mYoungerQueue->GetYoungest(aQueue);

  nsIEventQueue *answer = NS_STATIC_CAST(nsIEventQueue *, this);
  NS_ADDREF(answer);
  *aQueue = answer;
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Fetch (and addref) the youngest member of the chain which is still accepting events.

Note that there may be still younger queues which still contain events in need of processing but have already stopped accepting new events.

Parameters:
*aQueuethe youngest such queue. aQueue must not be null. *aQueue will be returned null, if no such queue is found.
Returns:
error indication -- can be NS_OK even if *aQueue is 0

Implements nsPIEventQueueChain.

Definition at line 645 of file nsEventQueue.cpp.

{
  nsCOMPtr<nsIEventQueue> answer;

  if (mYoungerQueue)
    mYoungerQueue->GetYoungestActive(getter_AddRefs(answer));
  if (!answer) {
    if (mAcceptingEvents && mCouldHaveEvents)
      answer = NS_STATIC_CAST(nsIEventQueue *, this);
  }
  *aQueue = answer;
  NS_IF_ADDREF(*aQueue);
  return NS_OK;
}

Here is the call graph for this function:

void nsIEventQueue::handleEvent ( in PLEventPtr  aEvent) [inherited]
void nsIEventQueue::init ( in boolean  aNative) [inherited]
void nsIEventQueue::initEvent ( in PLEventPtr  aEvent,
in voidPtr  owner,
in PLHandleEventProc  handler,
in PLDestroyEventProc  destructor 
) [inherited]
void nsIEventQueue::initFromPRThread ( in PRThreadPtr  thread,
in boolean  aNative 
) [inherited]

This method returns true if the event target is the current thread.

void nsEventQueueImpl::NotifyObservers ( const char *  aTopic) [private]

Definition at line 253 of file nsEventQueue.cpp.

{
  // only send out this notification for native event queues
  if (!PL_IsQueueNative(mEventQueue))
    return;

  // we should not call out to the observer service from background threads!
  NS_ASSERTION(nsIThread::IsMainThread(),
               "Native event queues should only be used on the main thread");

  nsresult rv;
  nsCOMPtr<nsIObserverService> os = do_GetService("@mozilla.org/observer-service;1", &rv);
  if (NS_SUCCEEDED(rv)) {
    nsCOMPtr<nsIEventQueue> kungFuDeathGrip(this);
    nsCOMPtr<nsISupports> us(do_QueryInterface(kungFuDeathGrip));
    os->NotifyObservers(us, aTopic, NULL);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIEventTarget::postEvent ( in PLEventPtr  aEvent) [inherited]

Method for posting an asynchronous event to the event target.

If this method succeeds, then the event will be dispatched on the target thread.

Parameters:
aEventThe event to dispatched.
void nsIEventQueue::postSynchronousEvent ( in PLEventPtr  aEvent,
out voidPtr  aResult 
) [inherited]
void nsIEventQueue::revokeEvents ( in voidPtr  owner) [inherited]

Revoke events in this event queue and all other event queues for this thread that have |owner| as the event owner.

Revoke events for aOwner in this queue and all elder queues.

This differs in behavior from nsIEventQueue::RevokeEvents in that that method revokes events in younger queues too.

Implements nsPIEventQueueChain.

Definition at line 695 of file nsEventQueue.cpp.

{
  PL_RevokeEvents(mEventQueue, aOwner);
  if (mElderQueue) {
    mElderQueue->RevokeEventsInternal(aOwner);
  }
  return NS_OK;
}

Here is the call graph for this function:

Implements nsPIEventQueueChain.

Definition at line 668 of file nsEventQueue.cpp.

{
  mElderQueue = aQueue;
  return NS_OK;
}

Implements nsPIEventQueueChain.

Definition at line 661 of file nsEventQueue.cpp.

{
  mYoungerQueue = aQueue;
  return NS_OK;
}

Remove this element from the chain.

Returns:
NS_OK

Implements nsPIEventQueueChain.

Definition at line 605 of file nsEventQueue.cpp.

{
  nsCOMPtr<nsPIEventQueueChain> young = mYoungerQueue,
                                old = mElderQueue;

#if defined(PR_LOGGING) && defined(DEBUG_danm)
  PR_LOG(gEventQueueLog, PR_LOG_DEBUG,
         ("EventQueue: unlink [queue=%lx, younger=%lx, elder=%lx]",
         (long)mEventQueue,(long)mYoungerQueue, (long)mElderQueue.get()));
  ++gEventQueueLogCount;
#endif

  // this is probably OK, but shouldn't happen by design, so tell me if it does
  NS_ASSERTION(!mYoungerQueue, "event queue chain broken in middle");

  // break links early in case the Release cascades back onto us
  mYoungerQueue = nsnull;
  mElderQueue = nsnull;

  if (young)
    young->SetElder(old);
  if (old) {
    old->SetYounger(young);
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 73 of file nsEventQueue.h.

Definition at line 73 of file nsEventQueue.h.

Definition at line 75 of file nsEventQueue.h.

Definition at line 72 of file nsEventQueue.h.

Definition at line 76 of file nsEventQueue.h.


The documentation for this class was generated from the following files: