add API to EventQueueService for creating a monitored event queue. part of bug 25979. r=dougt r=jar

This commit is contained in:
danm%netscape.com 2000-03-04 03:17:01 +00:00
Родитель 9180354767
Коммит 155b1b253e
8 изменённых файлов: 103 добавлений и 32 удалений

Просмотреть файл

@ -86,15 +86,19 @@ nsEventQueueImpl::~nsEventQueueImpl()
}
NS_IMETHODIMP
nsEventQueueImpl::Init()
nsEventQueueImpl::Init(PRBool aNative)
{
mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", PR_GetCurrentThread());
PRThread *thread = PR_GetCurrentThread();
if (aNative)
mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", thread);
else
mEventQueue = PL_CreateMonitoredEventQueue("Thread event queue...", thread);
NotifyObservers(gActivatedNotification);
return NS_OK;
}
NS_IMETHODIMP
nsEventQueueImpl::InitFromPRThread(PRThread* thread)
nsEventQueueImpl::InitFromPRThread(PRThread* thread, PRBool aNative)
{
if (thread == NS_CURRENT_THREAD)
{
@ -112,8 +116,11 @@ nsEventQueueImpl::InitFromPRThread(PRThread* thread)
rv = mainIThread->GetPRThread(&thread);
if (NS_FAILED(rv)) return rv;
}
mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", thread);
if (aNative)
mEventQueue = PL_CreateNativeEventQueue("Thread event queue...", thread);
else
mEventQueue = PL_CreateMonitoredEventQueue("Thread event queue...", thread);
NotifyObservers(gActivatedNotification);
return NS_OK;
}
@ -274,6 +281,13 @@ nsEventQueueImpl::IsQueueOnCurrentThread(PRBool *aResult)
}
NS_IMETHODIMP
nsEventQueueImpl::IsQueueNative(PRBool *aResult)
{
*aResult = PL_IsQueueNative(mEventQueue);
return NS_OK;
}
NS_IMETHODIMP
nsEventQueueImpl::ProcessPendingEvents()
{

Просмотреть файл

@ -53,8 +53,8 @@ public:
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD();
NS_IMETHOD Init();
NS_IMETHOD InitFromPRThread(PRThread* thread);
NS_IMETHOD Init(PRBool aNative);
NS_IMETHOD InitFromPRThread(PRThread* thread, PRBool aNative);
NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue);
NS_IMETHOD EnterMonitor();
@ -65,6 +65,7 @@ public:
NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue);
NS_IMETHOD IsQueueOnCurrentThread(PRBool *aResult);
NS_IMETHOD IsQueueNative(PRBool *aResult);
NS_IMETHOD StopAcceptingEvents();

Просмотреть файл

@ -78,16 +78,17 @@ public:
class EventQueueEntry : public nsISupports
{
public:
EventQueueEntry(nsEventQueueServiceImpl *aService, ThreadKey &aKey);
EventQueueEntry(nsEventQueueServiceImpl *aService, ThreadKey &aKey,
PRBool aNative);
virtual ~EventQueueEntry();
// nsISupports interface...
NS_DECL_ISUPPORTS
nsIEventQueue* GetEventQueue(void); // addrefs!
nsresult MakeNewQueue(PRThread* thread, nsIEventQueue **aQueue);
nsresult AddQueue(void);
void RemoveQueue(nsIEventQueue *aQueue); // queue goes dark, and is released
ThreadKey *TheThreadKey(void)
{ return &mHashKey; }
@ -99,6 +100,9 @@ public:
{ return mNextEntry; }
private:
nsresult MakeNewQueue(PRThread* thread, PRBool aNative,
nsIEventQueue **aQueue);
nsIEventQueue *mQueue;
ThreadKey mHashKey;
nsEventQueueServiceImpl *mService; // weak reference, obviously
@ -109,12 +113,12 @@ private:
/* nsISupports interface implementation... */
NS_IMPL_ISUPPORTS0(EventQueueEntry)
EventQueueEntry::EventQueueEntry(nsEventQueueServiceImpl *aService, ThreadKey &aKey) :
EventQueueEntry::EventQueueEntry(nsEventQueueServiceImpl *aService, ThreadKey &aKey, PRBool aNative) :
mHashKey(aKey), mPrevEntry(0), mNextEntry(0)
{
NS_INIT_REFCNT();
mService = aService;
MakeNewQueue(aKey.id, &mQueue);
MakeNewQueue(aKey.id, aNative, &mQueue);
NS_ASSERTION(mQueue, "EventQueueEntry constructor failed");
if (mService)
mService->AddEventQueueEntry(this);
@ -144,7 +148,9 @@ nsIEventQueue* EventQueueEntry::GetEventQueue(void)
return answer;
}
nsresult EventQueueEntry::MakeNewQueue(PRThread* thread, nsIEventQueue **aQueue)
nsresult EventQueueEntry::MakeNewQueue(PRThread* thread,
PRBool aNative,
nsIEventQueue **aQueue)
{
nsIEventQueue *queue = 0;
nsresult rv;
@ -153,7 +159,7 @@ nsresult EventQueueEntry::MakeNewQueue(PRThread* thread, nsIEventQueue **aQueue)
NS_GET_IID(nsIEventQueue), (void**) &queue);
if (NS_SUCCEEDED(rv)) {
rv = queue->InitFromPRThread(thread);
rv = queue->InitFromPRThread(thread, aNative);
if (NS_FAILED(rv)) {
NS_RELEASE(queue);
queue = 0; // redundant, but makes me feel better
@ -165,11 +171,13 @@ nsresult EventQueueEntry::MakeNewQueue(PRThread* thread, nsIEventQueue **aQueue)
nsresult EventQueueEntry::AddQueue(void)
{
PRBool native;
nsIEventQueue *newQueue = NULL;
nsresult rv = NS_ERROR_NOT_INITIALIZED;
if (mQueue) {
rv = MakeNewQueue(PR_GetCurrentThread(), &newQueue);
mQueue->IsQueueNative(&native);
rv = MakeNewQueue(PR_GetCurrentThread(), native, &newQueue);
// add it to our chain of queues
if (NS_SUCCEEDED(rv)) {
@ -301,21 +309,27 @@ NS_IMPL_ISUPPORTS1(nsEventQueueServiceImpl,nsIEventQueueService)
/* nsIEventQueueService interface implementation... */
NS_IMETHODIMP
nsEventQueueServiceImpl::CreateThreadEventQueue(void)
nsEventQueueServiceImpl::CreateThreadEventQueue()
{
return CreateEventQueue(PR_GetCurrentThread());
return CreateEventQueue(PR_GetCurrentThread(), PR_TRUE);
}
NS_IMETHODIMP
nsEventQueueServiceImpl::CreateMonitoredThreadEventQueue()
{
return CreateEventQueue(PR_GetCurrentThread(), PR_FALSE);
}
NS_IMETHODIMP
nsEventQueueServiceImpl::CreateFromIThread(
nsIThread *aThread, nsIEventQueue **aResult)
nsIThread *aThread, PRBool aNative, nsIEventQueue **aResult)
{
nsresult rv;
PRThread *prThread;
rv = aThread->GetPRThread(&prThread);
if (NS_SUCCEEDED(rv)) {
rv = CreateEventQueue(prThread); // addrefs
rv = CreateEventQueue(prThread, aNative); // addrefs
if (NS_SUCCEEDED(rv))
rv = GetThreadEventQueue(prThread, aResult); // doesn't addref
}
@ -323,7 +337,7 @@ nsEventQueueServiceImpl::CreateFromIThread(
}
NS_IMETHODIMP
nsEventQueueServiceImpl::CreateEventQueue(PRThread *aThread)
nsEventQueueServiceImpl::CreateEventQueue(PRThread *aThread, PRBool aNative)
{
nsresult rv = NS_OK;
ThreadKey key(aThread);
@ -335,7 +349,7 @@ nsEventQueueServiceImpl::CreateEventQueue(PRThread *aThread)
/* create only one event queue chain per thread... */
evQueueEntry = (EventQueueEntry*)mEventQTable->Get(&key);
if (NULL == evQueueEntry) {
evQueueEntry = new EventQueueEntry(this, key);
evQueueEntry = new EventQueueEntry(this, key, aNative);
if (NULL == evQueueEntry) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;
@ -447,8 +461,10 @@ nsEventQueueServiceImpl::PushThreadEventQueue(nsIEventQueue **aNewQueue)
PR_EnterMonitor(mEventQMonitor);
evQueueEntry = (EventQueueEntry*)mEventQTable->Get(&key);
NS_ASSERTION(evQueueEntry, "pushed event queue on top of nothing");
if (NULL == evQueueEntry) {
evQueueEntry = new EventQueueEntry(this, key);
// shouldn't happen. as a fallback, we guess you wanted a native queue
evQueueEntry = new EventQueueEntry(this, key, PR_TRUE);
if (NULL == evQueueEntry) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;

Просмотреть файл

@ -57,12 +57,14 @@ public:
NS_DECL_ISUPPORTS
// nsIEventQueueService interface...
NS_IMETHOD CreateThreadEventQueue(void);
NS_IMETHOD CreateThreadEventQueue();
NS_IMETHOD CreateMonitoredThreadEventQueue();
NS_IMETHOD DestroyThreadEventQueue(void);
NS_IMETHOD GetThreadEventQueue(PRThread* aThread, nsIEventQueue** aResult);
NS_IMETHOD ResolveEventQueue(nsIEventQueue* queueOrConstant, nsIEventQueue* *resultQueue);
NS_IMETHOD CreateFromIThread(nsIThread *aThread, nsIEventQueue **aResult);
NS_IMETHOD CreateFromIThread(nsIThread *aThread, PRBool aNative,
nsIEventQueue **aResult);
NS_IMETHOD CreateFromPLEventQueue(PLEventQueue* aPLEventQueue, nsIEventQueue** aResult);
NS_IMETHOD PushThreadEventQueue(nsIEventQueue **aNewQueue);
@ -70,7 +72,10 @@ public:
private:
NS_IMETHOD CreateEventQueue(PRThread *aThread);
/* Create a queue for the given thread if one does not exist.
Addref the descriptor in any case. parameter aNative is
ignored if the queue already exists. */
NS_IMETHOD CreateEventQueue(PRThread *aThread, PRBool aNative);
void AddEventQueueEntry(EventQueueEntry *aEntry);
void RemoveEventQueueEntry(EventQueueEntry *aEntry);

Просмотреть файл

@ -60,8 +60,8 @@ public:
NS_IMETHOD_(PRInt32) GetEventQueueSelectFD() = 0;
NS_IMETHOD Init() = 0;
NS_IMETHOD InitFromPRThread(PRThread* thread) = 0;
NS_IMETHOD Init(PRBool aNative) = 0;
NS_IMETHOD InitFromPRThread(PRThread* thread, PRBool aNative) = 0;
NS_IMETHOD InitFromPLQueue(PLEventQueue* aQueue) = 0;
NS_IMETHOD EnterMonitor() = 0;
@ -71,6 +71,7 @@ public:
NS_IMETHOD GetPLEventQueue(PLEventQueue** aEventQueue) = 0;
NS_IMETHOD IsQueueOnCurrentThread(PRBool *aResult) = 0;
NS_IMETHOD IsQueueNative(PRBool *aResult) = 0;
// effectively kill the queue. warning: the queue is allowed to delete
// itself any time after this.

Просмотреть файл

@ -55,10 +55,33 @@ class nsIEventQueueService : public nsISupports
public:
static const nsIID& GetIID() { static nsIID iid = NS_IEVENTQUEUESERVICE_IID; return iid; }
NS_IMETHOD CreateThreadEventQueue(void) = 0;
/**
* Creates and holds a native event queue for the current thread.
* "Native" queues have an associated callback mechanism which is
* automatically triggered when an event is posted. See plevent.c for details.
* @return NS_OK on success, or a host of failure indications
*/
NS_IMETHOD CreateThreadEventQueue() = 0;
/**
* Creates and hold a monitored event queue for the current thread.
* "Monitored" queues have no callback processing mechanism.
* @return NS_OK on success, or a host of failure indications
*/
NS_IMETHOD CreateMonitoredThreadEventQueue() = 0;
/**
* Somewhat misnamed, this method releases the service's hold on the event
* queue(s) for this thread. Subsequent attempts to access this thread's
* queue (GetThreadEventQueue, for example) may fail, though the queue itself
* will be destroyed only after all references to it are released and the
* queue itself is no longer actively processing events.
* @return nonsense.
*/
NS_IMETHOD DestroyThreadEventQueue(void) = 0;
NS_IMETHOD CreateFromIThread(nsIThread *aThread, nsIEventQueue **aResult) = 0;
NS_IMETHOD CreateFromIThread(nsIThread *aThread, PRBool aNative,
nsIEventQueue **aResult) = 0;
NS_IMETHOD CreateFromPLEventQueue(PLEventQueue* aPLEventQueue, nsIEventQueue** aResult) = 0;
// Add a new event queue for the current thread, making it the "current"

Просмотреть файл

@ -168,17 +168,16 @@ static PLEventQueue *
self->removeMsg = PR_TRUE;
#endif
PR_INIT_CLIST(&self->queue);
if ( qtype == EventQueueIsNative )
{
if ( qtype == EventQueueIsNative ) {
err = _pl_SetupNativeNotifier(self);
if (err) goto error;
_md_CreateEventQueue( self );
}
_md_CreateEventQueue( self );
return self;
error:
if (mon != NULL)
PR_DestroyMonitor(mon);
PR_DestroyMonitor(mon);
PR_DELETE(self);
return NULL;
} /* end _pl_CreateEventQueue() */
@ -929,6 +928,12 @@ PL_IsQueueOnCurrentThread( PLEventQueue *queue )
return PR_FALSE;
} /* end PL_IsQueueOnCurrentThread() */
PR_EXTERN(PRBool)
PL_IsQueueNative(PLEventQueue *queue)
{
return queue->type == EventQueueIsNative ? PR_TRUE : PR_FALSE;
}
#if defined(WIN16) || defined(_WIN32)
/*
** Global Instance handle...

Просмотреть файл

@ -393,6 +393,12 @@ PL_GetEventQueueSelectFD(PLEventQueue* self);
PR_EXTERN(PRBool)
PL_IsQueueOnCurrentThread( PLEventQueue *queue );
/*
** Returns whether the queue is native (true) or monitored (false)
*/
PR_EXTERN(PRBool)
PL_IsQueueNative(PLEventQueue *queue);
/*******************************************************************************
* Event Operations
******************************************************************************/