diff options
author | wtc%netscape.com <devnull@localhost> | 2000-01-28 00:29:16 +0000 |
---|---|---|
committer | wtc%netscape.com <devnull@localhost> | 2000-01-28 00:29:16 +0000 |
commit | 58c5ca2ca734d15814d8ae7deef318fb1484e2cd (patch) | |
tree | b176e35498131d4987dcb5d60adb06aad3de56d7 | |
parent | 1dc64d59d4e47ce4af87208b06dfbeafe99d3380 (diff) | |
download | nspr-hg-58c5ca2ca734d15814d8ae7deef318fb1484e2cd.tar.gz |
Bugzilla bug #17101: removed plevent.h and plevent.c. These two files
have been moved to mozilla/xpcom/threads.
-rw-r--r-- | lib/ds/plevent.c | 1114 | ||||
-rw-r--r-- | lib/ds/plevent.h | 497 |
2 files changed, 0 insertions, 1611 deletions
diff --git a/lib/ds/plevent.c b/lib/ds/plevent.c deleted file mode 100644 index 237bffef..00000000 --- a/lib/ds/plevent.c +++ /dev/null @@ -1,1114 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -#if defined(_WIN32) || defined(WIN16) -#include <windows.h> -#endif - -#if defined(XP_OS2) -#define INCL_WIN -#include <os2.h> -#define DefWindowProc WinDefWindowProc -typedef MPARAM WPARAM,LPARAM; -#endif /* XP_OS2 */ - -#include "nspr.h" -#include "plevent.h" - -#if !defined(WIN32) -#include <errno.h> -#include <stddef.h> -#if !defined(XP_OS2) -#include <unistd.h> -#endif /* !XP_OS2 */ -#endif /* !Win32 */ - -#if defined(XP_UNIX) -/* for fcntl */ -#include <sys/types.h> -#include <fcntl.h> -#endif - -#if defined(XP_BEOS) -#include <kernel/OS.h> -#endif - -#if defined(XP_MAC) -#include <AppleEvents.h> -#include "pprthred.h" -#else -#include "private/pprthred.h" -#endif /* XP_MAC */ - -#if defined(VMS) -/* -** On OpenVMS, XtAppAddInput doesn't want a regular fd, instead it -** wants an event flag. So, we don't create and use a pipe for -** notification of when an event queue has something ready, instead -** we use an event flag. Shouldn't be a problem if we only have -** a few event queues. -*/ -#include <lib$routines.h> -#include <starlet.h> -#include <stsdef.h> -#endif /* VMS */ - - -static PRLogModuleInfo *event_lm = NULL; - -/******************************************************************************* - * Private Stuff - ******************************************************************************/ - -/* -** EventQueueType -- Defines notification type for an event queue -** -*/ -typedef enum -{ - EventQueueIsNative = 1, - EventQueueIsMonitored = 2 -} EventQueueType; - - -struct PLEventQueue { - char* name; - PRCList queue; - PRMonitor* monitor; - PRThread* handlerThread; - EventQueueType type; - PRBool processingEvents; -#if defined(VMS) - int efn; - int notifyCount; -#elif defined(XP_UNIX) - PRInt32 eventPipe[2]; - int notifyCount; -#elif defined(_WIN32) || defined(WIN16) - HWND eventReceiverWindow; - PRBool removeMsg; -#elif defined(XP_OS2) - HWND eventReceiverWindow; -#elif defined(XP_BEOS) - port_id eventport; -#endif -}; - -#define PR_EVENT_PTR(_qp) \ - ((PLEvent*) ((char*) (_qp) - offsetof(PLEvent, link))) - -static PRStatus _pl_SetupNativeNotifier(PLEventQueue* self); -static void _pl_CleanupNativeNotifier(PLEventQueue* self); -static PRStatus _pl_NativeNotify(PLEventQueue* self); -static PRStatus _pl_AcknowledgeNativeNotify(PLEventQueue* self); -static void _md_CreateEventQueue( PLEventQueue *eventQueue ); -static PRInt32 _pl_GetEventCount(PLEventQueue* self); - - -#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2) -#if defined(XP_OS2) -ULONG _pr_PostEventMsgId; -static char *_pr_eventWindowClass = "NSPR:EventWindow"; -#else -UINT _pr_PostEventMsgId; -static char *_pr_eventWindowClass = "NSPR:EventWindow"; -#endif /* OS2 */ -#endif /* Win32, Win16, OS2 */ - -/******************************************************************************* - * Event Queue Operations - ******************************************************************************/ - -/* -** _pl_CreateEventQueue() -- Create the event queue -** -** -*/ -static PLEventQueue * - _pl_CreateEventQueue( - char *name, - PRThread *handlerThread, - EventQueueType qtype -) -{ - PRStatus err; - PLEventQueue* self = NULL; - PRMonitor* mon = NULL; - - if (event_lm == NULL) - event_lm = PR_NewLogModule("event"); - - self = PR_NEWZAP(PLEventQueue); - if (self == NULL) return NULL; - - mon = PR_NewNamedMonitor(name); - if (mon == NULL) goto error; - - self->name = name; - self->monitor = mon; - self->handlerThread = handlerThread; - self->processingEvents = PR_FALSE; - self->type = qtype; -#if defined(_WIN32) || defined(WIN16) - self->removeMsg = PR_TRUE; -#endif - PR_INIT_CLIST(&self->queue); - if ( qtype == EventQueueIsNative ) - { - err = _pl_SetupNativeNotifier(self); - if (err) goto error; - } - _md_CreateEventQueue( self ); - return self; - - error: - if (mon != NULL) - PR_DestroyMonitor(mon); - PR_DELETE(self); - return NULL; -} /* end _pl_CreateEventQueue() */ - - -PR_IMPLEMENT(PLEventQueue*) -PL_CreateEventQueue(char* name, PRThread* handlerThread) -{ - return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative )); -} - -PR_EXTERN(PLEventQueue *) - PL_CreateNativeEventQueue( - char *name, - PRThread *handlerThread - ) -{ - return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative )); -} /* --- end PL_CreateNativeEventQueue() --- */ - -PR_EXTERN(PLEventQueue *) - PL_CreateMonitoredEventQueue( - char *name, - PRThread *handlerThread - ) -{ - return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsMonitored )); -} /* --- end PL_CreateMonitoredEventQueue() --- */ - - - -PR_IMPLEMENT(PRMonitor*) -PL_GetEventQueueMonitor(PLEventQueue* self) -{ - return self->monitor; -} - -static void PR_CALLBACK -_pl_destroyEvent(PLEvent* event, void* data, PLEventQueue* queue) -{ -#ifdef XP_MAC -#pragma unused (data, queue) -#endif - PL_DequeueEvent(event, queue); - PL_DestroyEvent(event); -} - -PR_IMPLEMENT(void) -PL_DestroyEventQueue(PLEventQueue* self) -{ - 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); - -} - -PR_IMPLEMENT(PRStatus) -PL_PostEvent(PLEventQueue* self, PLEvent* event) -{ - PRStatus err = PR_SUCCESS; - PRMonitor* mon; - - if (self == NULL) - return PR_FAILURE; - - mon = self->monitor; - PR_EnterMonitor(mon); - - /* insert event into thread's event queue: */ - if (event != NULL) { - PR_APPEND_LINK(&event->link, &self->queue); - } - - /* notify even if event is NULL */ - if ( self->type == EventQueueIsNative ) - err = _pl_NativeNotify(self); - - /* - * 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); - PR_ExitMonitor(mon); - return err; -} - -PR_IMPLEMENT(void*) -PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event) -{ - void* result; - - if (self == NULL) - return NULL; - - PR_ASSERT(event != NULL); - PR_CEnterMonitor(event); - - if (PR_CurrentThread() == 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 = PR_GetMonitorEntryCount(self->monitor); - - event->synchronousResult = (void*)PR_TRUE; - PL_PostEvent(self, event); - /* We need to temporarily 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); - } - PR_CWait(event, PR_INTERVAL_NO_TIMEOUT); /* wait for event to be handled or destroyed */ - if (entryCount) { - for (i = 0; i < entryCount; i++) - PR_EnterMonitor(self->monitor); - } - result = event->synchronousResult; - event->synchronousResult = NULL; - } - - PR_CExitMonitor(event); - - /* 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; -} - -PR_IMPLEMENT(PLEvent*) -PL_GetEvent(PLEventQueue* self) -{ - 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 ) - err = _pl_AcknowledgeNativeNotify(self); - - 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; -} - -PR_IMPLEMENT(PRBool) -PL_EventAvailable(PLEventQueue* self) -{ - 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; -} - -PR_IMPLEMENT(void) -PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data) -{ - 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); -} - -static void PR_CALLBACK -_pl_DestroyEventForOwner(PLEvent* event, void* owner, PLEventQueue* queue) -{ - PR_ASSERT(PR_GetMonitorEntryCount(queue->monitor) > 0); - if (event->owner == owner) { - PR_LOG(event_lm, PR_LOG_DEBUG, - ("$$$ \tdestroying event %0x for owner %0x", event, owner)); - PL_DequeueEvent(event, queue); - if (event->synchronousResult == (void*)PR_TRUE) { - PR_CEnterMonitor(event); - event->synchronousResult = NULL; - PR_CNotify(event); - PR_CExitMonitor(event); - } - else { - PL_DestroyEvent(event); - } - } - else { - PR_LOG(event_lm, PR_LOG_DEBUG, - ("$$$ \tskipping event %0x for owner %0x", event, owner)); - } -} - -PR_IMPLEMENT(void) -PL_RevokeEvents(PLEventQueue* self, void* owner) -{ - 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)); -} - -static PRInt32 -_pl_GetEventCount(PLEventQueue* self) -{ - PRCList* node; - PRInt32 count = 0; - - PR_EnterMonitor(self->monitor); - node = PR_LIST_HEAD(&self->queue); - while (node != &self->queue) { - count++; - node = PR_NEXT_LINK(node); - } - PR_ExitMonitor(self->monitor); - - return count; -} - -PR_IMPLEMENT(void) -PL_ProcessPendingEvents(PLEventQueue* self) -{ - PRInt32 count; - - if (self == NULL) - return; - - if (PR_FALSE != self->processingEvents) 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); - 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")); - } - self->processingEvents = PR_FALSE; -} - -/******************************************************************************* - * Event Operations - ******************************************************************************/ - -PR_IMPLEMENT(void) -PL_InitEvent(PLEvent* self, void* owner, - PLHandleEventProc handler, - PLDestroyEventProc destructor) -{ - PR_INIT_CLIST(&self->link); - self->handler = handler; - self->destructor = destructor; - self->owner = owner; - self->synchronousResult = NULL; -} - -PR_IMPLEMENT(void*) -PL_GetEventOwner(PLEvent* self) -{ - return self->owner; -} - -PR_IMPLEMENT(void) -PL_HandleEvent(PLEvent* self) -{ - 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_CEnterMonitor(self); - self->synchronousResult = result; - PR_CNotify(self); /* wake up the guy waiting for the result */ - PR_CExitMonitor(self); - } - else { - /* For asynchronous events, they're destroyed by the event-handler - thread. See PR_PostSynchronousEvent. */ - PL_DestroyEvent(self); - } -} - -PR_IMPLEMENT(void) -PL_DestroyEvent(PLEvent* self) -{ - if (self == NULL) - return; - - /* This event better not be on an event queue anymore. */ - PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link)); - - (*self->destructor)(self); -} - -PR_IMPLEMENT(void) -PL_DequeueEvent(PLEvent* self, PLEventQueue* queue) -{ -#ifdef XP_MAC -#pragma unused (queue) -#endif - 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_CurrentThread());*/ - - PR_EnterMonitor(queue->monitor); - - PR_ASSERT(!PR_CLIST_IS_EMPTY(&self->link)); - PR_REMOVE_AND_INIT_LINK(&self->link); - - PR_ExitMonitor(queue->monitor); -} - -/******************************************************************************* - * Pure Event Queues - * - * For when you're only processing PLEvents and there is no native - * select, thread messages, or AppleEvents. - ******************************************************************************/ - -PR_IMPLEMENT(PLEvent*) -PL_WaitForEvent(PLEventQueue* self) -{ - 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; -} - -PR_IMPLEMENT(void) -PL_EventLoop(PLEventQueue* self) -{ - 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")); - } -} - -/******************************************************************************* - * Native Event Queues - * - * For when you need to call select, or WaitNextEvent, and yet also want - * to handle PLEvents. - ******************************************************************************/ - -static PRStatus -_pl_SetupNativeNotifier(PLEventQueue* self) -{ -#if defined(XP_MAC) -#pragma unused (self) -#endif - -#if defined(VMS) - { - unsigned int status; - status = LIB$GET_EF(&self->efn); - if (!$VMS_STATUS_SUCCESS(status)) - return PR_FAILURE; - PR_LOG(event_lm, PR_LOG_DEBUG, - ("$$$ Allocated event flag %d", self->efn)); - return PR_SUCCESS; - } -#elif defined(XP_UNIX) - int err; - int flags; - - err = pipe(self->eventPipe); - if (err != 0) { - return PR_FAILURE; - } - - /* make the pipe nonblocking */ - flags = fcntl(self->eventPipe[0], F_GETFL, 0); - if (flags == -1) { - goto failed; - } - err = fcntl(self->eventPipe[0], F_SETFL, flags | O_NONBLOCK); - if (err == -1) { - goto failed; - } - flags = fcntl(self->eventPipe[1], F_GETFL, 0); - if (flags == -1) { - goto failed; - } - err = fcntl(self->eventPipe[1], F_SETFL, flags | O_NONBLOCK); - if (err == -1) { - goto failed; - } - return PR_SUCCESS; - -failed: - close(self->eventPipe[0]); - close(self->eventPipe[1]); - return PR_FAILURE; -#elif defined(XP_BEOS) - /* hook up to the nsToolkit queue, however the appshell - * isn't necessairly started, so we might have to create - * the queue ourselves - */ - char portname[64]; - char semname[64]; - sprintf(portname, "event%lx", self->handlerThread); - sprintf(semname, "sync%lx", self->handlerThread); - - if((self->eventport = find_port(portname)) < 0) - { - /* create port - */ - self->eventport = create_port(100, portname); - - /* We don't use the sem, but it has to be there - */ - create_sem(0, semname); - } - - return PR_SUCCESS; -#else - return PR_SUCCESS; -#endif -} - -static void -_pl_CleanupNativeNotifier(PLEventQueue* self) -{ -#if defined(XP_MAC) -#pragma unused (self) -#endif - -#if defined(VMS) - { - unsigned int status; - PR_LOG(event_lm, PR_LOG_DEBUG, - ("$$$ Freeing event flag %d", self->efn)); - status = LIB$FREE_EF(&self->efn); - } -#elif defined(XP_UNIX) - close(self->eventPipe[0]); - close(self->eventPipe[1]); -#elif defined(_WIN32) || defined(WIN16) - DestroyWindow(self->eventReceiverWindow); -#endif -} - -#if defined(_WIN32) || defined(WIN16) -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ - PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId, - (WPARAM)0, (LPARAM)self); - return PR_SUCCESS; -}/* --- end _pl_NativeNotify() --- */ -#endif - -#if defined(XP_OS2) -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ - BOOL rc = WinPostMsg( self->eventReceiverWindow, _pr_PostEventMsgId, - 0, MPFROMP(self)); - return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE; -}/* --- end _pl_NativeNotify() --- */ -#endif /* XP_OS2 */ - -#if defined(VMS) -/* Just set the event flag */ -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ - unsigned int status; - PR_LOG(event_lm, PR_LOG_DEBUG, - ("_pl_NativeNotify: self=%p notifyCount=%d efn=%d", - self, self->notifyCount, self->efn)); - self->notifyCount++; - status = SYS$SETEF(self->efn); - if ($VMS_STATUS_SUCCESS(status)) - return PR_SUCCESS; - else - return PR_FAILURE; -}/* --- end _pl_NativeNotify() --- */ -#elif defined(XP_UNIX) -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ -#define NOTIFY_TOKEN 0xFA - PRInt32 count; - unsigned char buf[] = { NOTIFY_TOKEN }; - - PR_LOG(event_lm, PR_LOG_DEBUG, - ("_pl_NativeNotify: self=%p notifyCount=%d", - self, self->notifyCount)); - count = write(self->eventPipe[1], buf, 1); - if (count == 1) { - self->notifyCount++; - return PR_SUCCESS; - } else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) { - return PR_SUCCESS; - } else - return PR_FAILURE; -}/* --- end _pl_NativeNotify() --- */ -#endif /* XP_UNIX */ - -#if defined(XP_BEOS) -struct ThreadInterfaceData -{ - void *data; - int32 sync; -}; - -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ - struct ThreadInterfaceData id; - id.data = self; - id.sync = false; - write_port(self->eventport, 'natv', &id, sizeof(id)); - - return PR_SUCCESS; /* Is this correct? */ -} -#endif /* XP_BEOS */ - -#if defined(XP_MAC) -static PRStatus -_pl_NativeNotify(PLEventQueue* self) -{ -#pragma unused (self) - return PR_SUCCESS; /* XXX can fail? */ -} -#endif /* XP_MAC */ - -static PRStatus -_pl_AcknowledgeNativeNotify(PLEventQueue* self) -{ -#if defined(_WIN32) || defined(WIN16) - MSG aMsg; - /* - * only remove msg when we've been called directly by - * PL_ProcessPendingEvents, not when we've been called by - * the window proc because the window proc will remove the - * msg for us. - */ - if (self->removeMsg) { - PR_LOG(event_lm, PR_LOG_DEBUG, - ("_pl_AcknowledgeNativeNotify: self=%p", self)); - PeekMessage(&aMsg, self->eventReceiverWindow, - _pr_PostEventMsgId, _pr_PostEventMsgId, PM_REMOVE); - } - return PR_SUCCESS; -#elif defined(VMS) - PR_LOG(event_lm, PR_LOG_DEBUG, - ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d efn=%d", - self, self->notifyCount, self->efn)); - /* - ** If this is the last entry, then clear the event flag. Also make sure - ** the flag is cleared on any spurious wakeups. - */ - if (self->notifyCount <= 1) - sys$clref(self->efn); - - if (self->notifyCount <= 0) - return PR_SUCCESS; - - self->notifyCount--; - - return PR_SUCCESS; -#elif defined(XP_UNIX) - - PRInt32 count; - unsigned char c; - - PR_LOG(event_lm, PR_LOG_DEBUG, - ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d", - self, self->notifyCount)); - if (self->notifyCount <= 0) return PR_SUCCESS; - /* consume the byte NativeNotify put in our pipe: */ - count = read(self->eventPipe[0], &c, 1); - if ((count == 1) && (c == NOTIFY_TOKEN)) { - self->notifyCount--; - return PR_SUCCESS; - } else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) { - return PR_SUCCESS; - } else - return PR_FAILURE; -#else - -#if defined(XP_MAC) -#pragma unused (self) -#endif - - /* nothing to do on the other platforms */ - return PR_SUCCESS; -#endif -} - -PR_IMPLEMENT(PRInt32) -PL_GetEventQueueSelectFD(PLEventQueue* self) -{ - if (self == NULL) - return -1; - -#if defined(VMS) - return -(self->efn); -#elif defined(XP_UNIX) - return self->eventPipe[0]; -#else - return -1; /* other platforms don't handle this (yet) */ -#endif -} - -PR_IMPLEMENT(PRBool) -PL_IsQueueOnCurrentThread( PLEventQueue *queue ) -{ - PRThread *me = PR_GetCurrentThread(); - if ( me == queue->handlerThread ) - return PR_TRUE; - else - return PR_FALSE; -} /* end PL_IsQueueOnCurrentThread() */ - -#if defined(WIN16) || defined(_WIN32) -/* -** Global Instance handle... -** In Win32 this is the module handle of the DLL. -** -*/ -static HINSTANCE _pr_hInstance; -#endif - -#if defined(WIN16) -/* -** Function LibMain() is required by Win16 -** -*/ -int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, - WORD cbHeapSize, LPSTR lpszCmdLine ) -{ - _pr_hInstance = hInst; - return TRUE; -} -#endif /* WIN16 */ - -#if defined(_WIN32) - -/* -** Initialization routine for the NSPR DLL... -*/ - -BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) -{ - switch (dwReason) - { - case DLL_PROCESS_ATTACH: - _pr_hInstance = hDLL; - break; - - case DLL_THREAD_ATTACH: - break; - - case DLL_THREAD_DETACH: - break; - - case DLL_PROCESS_DETACH: - _pr_hInstance = NULL; - break; - } - - return TRUE; -} -#endif - - -#if defined(WIN16) || defined(_WIN32) || defined(XP_OS2) -#ifdef XP_OS2 -MRESULT EXPENTRY -_md_EventReceiverProc(HWND hwnd, ULONG uMsg, MPARAM wParam, MPARAM lParam) -#else -LRESULT CALLBACK -#if defined(WIN16) -__loadds -#endif -_md_EventReceiverProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -#endif -{ - if (_pr_PostEventMsgId == uMsg ) - { - PREventQueue *queue = (PREventQueue *)lParam; - -#if defined(_WIN32) || defined(WIN16) - queue->removeMsg = PR_FALSE; -#endif - PL_ProcessPendingEvents(queue); -#if defined(_WIN32) || defined(WIN16) - queue->removeMsg = PR_TRUE; -#endif -#ifdef XP_OS2 - return MRFROMLONG(TRUE); -#else - return TRUE; -#endif - } - return DefWindowProc(hwnd, uMsg, wParam, lParam); -} - - -static PRBool isInitialized; -static PRCallOnceType once; -static PRLock *initLock; - -/* -** InitWinEventLib() -- Create the Windows initialization lock -** -*/ -static PRStatus InitEventLib( void ) -{ - PR_ASSERT( initLock == NULL ); - - initLock = PR_NewLock(); - if ( NULL == initLock ) - return PR_FAILURE; - else - return PR_SUCCESS; -} /* end InitWinEventLib() */ - -#endif /* Win16, Win32, OS2 */ - -#if defined(_WIN32) || defined(WIN16) -/* -** _md_CreateEventQueue() -- ModelDependent initializer -*/ -static void _md_CreateEventQueue( PLEventQueue *eventQueue ) -{ - WNDCLASS wc; - - /* - ** If this is the first call to PL_InitializeEventsLib(), - ** make the call to InitWinEventLib() to create the initLock. - ** - ** Then lock the initializer lock to insure that - ** we have exclusive control over the initialization sequence. - ** - */ - - - /* Register the windows message for NSPR Event notification */ - _pr_PostEventMsgId = RegisterWindowMessage("NSPR_PostEvent"); - - /* Register the class for the event receiver window */ - if (!GetClassInfo(_pr_hInstance, _pr_eventWindowClass, &wc)) { - wc.style = 0; - wc.lpfnWndProc = _md_EventReceiverProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = _pr_hInstance; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = (HBRUSH) NULL; - wc.lpszMenuName = (LPCSTR) NULL; - wc.lpszClassName = _pr_eventWindowClass; - RegisterClass(&wc); - } - - /* Create the event receiver window */ - eventQueue->eventReceiverWindow = CreateWindow(_pr_eventWindowClass, - "NSPR:EventReceiver", - 0, 0, 0, 10, 10, - NULL, NULL, _pr_hInstance, - NULL); - PR_ASSERT(eventQueue->eventReceiverWindow); - - return; -} /* end _md_CreateEventQueue() */ -#endif /* Winxx */ - -#if defined(XP_OS2) -/* -** _md_CreateEventQueue() -- ModelDependent initializer -*/ -static void _md_CreateEventQueue( PLEventQueue *eventQueue ) -{ - /* Must have HMQ for this & can't assume we already have appshell */ - if( FALSE == WinQueryQueueInfo( HMQ_CURRENT, NULL, 0)) - { - HAB hab = WinInitialize( 0); - WinCreateMsgQueue( hab, 0); - } - - if( !_pr_PostEventMsgId) - { - WinRegisterClass( 0 /* hab_current */, - _pr_eventWindowClass, - _md_EventReceiverProc, - 0, 0); - - _pr_PostEventMsgId = WinAddAtom( WinQuerySystemAtomTable(), - "NSPR_PostEvent"); - } - - eventQueue->eventReceiverWindow = WinCreateWindow( HWND_DESKTOP, - _pr_eventWindowClass, - "", 0, - 0, 0, 0, 0, - HWND_DESKTOP, - HWND_TOP, - 0, - NULL, - NULL); - PR_ASSERT(eventQueue->eventReceiverWindow); - - return; -} /* end _md_CreateEventQueue() */ -#endif /* XP_OS2 */ - -#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS) -/* -** _md_CreateEventQueue() -- ModelDependent initializer -*/ -static void _md_CreateEventQueue( PLEventQueue *eventQueue ) -{ -#ifdef XP_MAC -#pragma unused(eventQueue) -#endif - - /* there's really nothing special to do here, - ** the guts of the unix stuff is in the setupnativenotify - ** and related functions. - */ - return; -} /* end _md_CreateEventQueue() */ -#endif /* XP_UNIX */ -/* --- end plevent.c --- */ diff --git a/lib/ds/plevent.h b/lib/ds/plevent.h deleted file mode 100644 index 38871055..00000000 --- a/lib/ds/plevent.h +++ /dev/null @@ -1,497 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public License - * Version 1.1 (the "NPL"); you may not use this file except in - * compliance with the NPL. You may obtain a copy of the NPL at - * http://www.mozilla.org/NPL/ - * - * Software distributed under the NPL is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL - * for the specific language governing rights and limitations under the - * NPL. - * - * The Initial Developer of this code under the NPL is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All Rights - * Reserved. - */ - -/********************************************************************** -NSPL Events - -Defining Events ---------------- - -Events are essentially structures that represent argument lists for a -function that will run on another thread. All event structures you -define must include a PLEvent struct as their first field: - - typedef struct MyEventType { - PLEvent e; - // arguments follow... - int x; - char* y; - } MyEventType; - -It is also essential that you establish a model of ownership for each -argument passed in an event record, i.e. whether particular arguments -will be deleted by the event destruction callback, or whether they -only loaned to the event handler callback, and guaranteed to persist -until the time at which the handler is called. - -Sending Events --------------- - -Events are initialized by PL_InitEvent and can be sent via -PL_PostEvent or PL_PostSynchronousEvent. Events can also have an -owner. The owner of an event can revoke all the events in a given -event-queue by calling PL_RevokeEvents. An owner might want -to do this if, for instance, it is being destroyed, and handling the -events after the owner's destruction would cause an error (e.g. an -MWContext). - -Since the act of initializing and posting an event must be coordinated -with it's possible revocation, it is essential that the event-queue's -monitor be entered surrounding the code that constructs, initializes -and posts the event: - - void postMyEvent(MyOwner* owner, int x, char* y) - { - MyEventType* event; - - PL_ENTER_EVENT_QUEUE_MONITOR(myQueue); - - // construct - event = PR_NEW(MyEventType); - if (event == NULL) goto done; - - // initialize - PL_InitEvent(event, owner, - (PLHandleEventProc)handleMyEvent, - (PLDestroyEventProc)destroyMyEvent); - event->x = x; - event->y = strdup(y); - - // post - PL_PostEvent(myQueue, &event->e); - - done: - PL_EXIT_EVENT_QUEUE_MONITOR(myQueue); - } - -If you don't call PL_InitEvent and PL_PostEvent within the -event-queue's monitor, you'll get a big red assert. - -Handling Events ---------------- - -To handle an event you must write a callback that is passed the event -record you defined containing the event's arguments: - - void* handleMyEvent(MyEventType* event) - { - doit(event->x, event->y); - return NULL; // you could return a value for a sync event - } - -Similarly for the destruction callback: - - void destroyMyEvent(MyEventType* event) - { - free(event->y); // created by strdup - free(event); - } - -Processing Events in Your Event Loop ------------------------------------- - -If your main loop only processes events delivered to the event queue, -things are rather simple. You just get the next event (which may -block), and then handle it: - - while (1) { - event = PL_GetEvent(myQueue); - PL_HandleEvent(event); - } - -However, if other things must be waited on, you'll need to obtain a -file-descriptor that represents your event queue, and hand it to select: - - fd = PL_GetEventQueueSelectFD(myQueue); - ...add fd to select set... - while (select(...)) { - if (...fd...) { - PL_ProcessPendingEvents(myQueue); - } - ... - } - -Of course, with Motif and Windows it's more complicated than that, and -on Mac it's completely different, but you get the picture. - -Revoking Events ---------------- -If at any time an owner of events is about to be destroyed, you must -take steps to ensure that no one tries to use the event queue after -the owner is gone (or a crash may result). You can do this by either -processing all the events in the queue before destroying the owner: - - { - ... - PL_ENTER_EVENT_QUEUE_MONITOR(myQueue); - PL_ProcessPendingEvents(myQueue); - DestroyMyOwner(owner); - PL_EXIT_EVENT_QUEUE_MONITOR(myQueue); - ... - } - -or by revoking the events that are in the queue for that owner. This -removes them from the queue and calls their destruction callback: - - { - ... - PL_ENTER_EVENT_QUEUE_MONITOR(myQueue); - PL_RevokeEvents(myQueue, owner); - DestroyMyOwner(owner); - PL_EXIT_EVENT_QUEUE_MONITOR(myQueue); - ... - } - -In either case it is essential that you be in the event-queue's monitor -to ensure that all events are removed from the queue for that owner, -and to ensure that no more events will be delivered for that owner. -**********************************************************************/ - -#ifndef prevent_h___ -#define prevent_h___ - -#include "prtypes.h" -#include "prclist.h" -#include "prthread.h" -#include "prmon.h" - -/* For HWND */ -#if defined(_WIN32) && !defined(__MINGW32__) -#include <windef.h> -#elif defined(WIN16) || defined(__MINGW32__) -#include <windows.h> -#elif defined(XP_OS2) -#define INCL_DOSPROCESS -#include <os2.h> -#endif - -PR_BEGIN_EXTERN_C - -/* Typedefs */ - -typedef struct PLEvent PLEvent; -typedef struct PLEventQueue PLEventQueue; - -/******************************************************************************* - * Event Queue Operations - ******************************************************************************/ - -/* -** Creates a new event queue. Returns NULL on failure. -*/ -PR_EXTERN(PLEventQueue*) -PL_CreateEventQueue(char* name, PRThread* handlerThread); - - -/* ----------------------------------------------------------------------- -** FUNCTION: PL_CreateNativeEventQueue() -** -** DESCRIPTION: -** PL_CreateNativeEventQueue() creates an event queue that -** uses platform specific notify mechanisms. -** -** For Unix, the platform specific notify mechanism provides -** an FD that may be extracted using the function -** PL_GetEventQueueSelectFD(). The FD returned may be used in -** a select() function call. -** -** For Windows, the platform specific notify mechanism -** provides an event receiver window that is called by -** Windows to process the event using the windows message -** pump engine. -** -** INPUTS: -** name: A name, as a diagnostic aid. -** -** handlerThread: A pointer to the PRThread structure for -** the thread that will "handle" events posted to this event -** queue. -** -** RETURNS: -** A pointer to a PLEventQueue structure or NULL. -** -*/ -PR_EXTERN(PLEventQueue *) - PL_CreateNativeEventQueue( - char *name, - PRThread *handlerThread - ); - -/* ----------------------------------------------------------------------- -** FUNCTION: PL_CreateMonitoredEventQueue() -** -** DESCRIPTION: -** PL_CreateMonitoredEventQueue() creates an event queue. No -** platform specific notify mechanism is created with the -** event queue. -** -** Users of this type of event queue must explicitly poll the -** event queue to retreive and process events. -** -** -** INPUTS: -** name: A name, as a diagnostic aid. -** -** handlerThread: A pointer to the PRThread structure for -** the thread that will "handle" events posted to this event -** queue. -** -** RETURNS: -** A pointer to a PLEventQueue structure or NULL. -** -*/ -PR_EXTERN(PLEventQueue *) - PL_CreateMonitoredEventQueue( - char *name, - PRThread *handlerThread - ); - -/* -** Destroys an event queue. -*/ -PR_EXTERN(void) -PL_DestroyEventQueue(PLEventQueue* self); - -/* -** Returns the monitor associated with an event queue. This monitor is -** selectable. The monitor should be entered to protect against anyone -** calling PL_RevokeEvents while the event is trying to be constructed -** and delivered. -*/ -PR_EXTERN(PRMonitor*) -PL_GetEventQueueMonitor(PLEventQueue* self); - -#define PL_ENTER_EVENT_QUEUE_MONITOR(queue) \ - PR_EnterMonitor(PL_GetEventQueueMonitor(queue)) - -#define PL_EXIT_EVENT_QUEUE_MONITOR(queue) \ - PR_ExitMonitor(PL_GetEventQueueMonitor(queue)) - -/* -** Posts an event to an event queue, waking up any threads waiting for an -** event. If event is NULL, notification still occurs, but no event will -** be available. -** -** Any events delivered by this routine will be destroyed by PL_HandleEvent -** when it is called (by the event-handling thread). -*/ -PR_EXTERN(PRStatus) -PL_PostEvent(PLEventQueue* self, PLEvent* event); - -/* -** Like PL_PostEvent, this routine posts an event to the event handling -** thread, but does so synchronously, waiting for the result. The result -** which is the value of the handler routine is returned. -** -** Any events delivered by this routine will be not be destroyed by -** PL_HandleEvent, but instead will be destroyed just before the result is -** returned (by the current thread). -*/ -PR_EXTERN(void*) -PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event); - -/* -** Gets an event from an event queue. Returns NULL if no event is -** available. -*/ -PR_EXTERN(PLEvent*) -PL_GetEvent(PLEventQueue* self); - -/* -** Returns true if there is an event available for PL_GetEvent. -*/ -PR_EXTERN(PRBool) -PL_EventAvailable(PLEventQueue* self); - -/* -** This is the type of the function that must be passed to PL_MapEvents -** (see description below). -*/ -typedef void -(PR_CALLBACK *PLEventFunProc)(PLEvent* event, void* data, PLEventQueue* queue); - -/* -** Applies a function to every event in the event queue. This can be used -** to selectively handle, filter, or remove events. The data pointer is -** passed to each invocation of the function fun. -*/ -PR_EXTERN(void) -PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data); - -/* -** This routine walks an event queue and destroys any event whose owner is -** the owner specified. The == operation is used to compare owners. -*/ -PR_EXTERN(void) -PL_RevokeEvents(PLEventQueue* self, void* owner); - -/* -** This routine processes all pending events in the event queue. It can be -** called from the thread's main event-processing loop whenever the event -** queue's selectFD is ready (returned by PL_GetEventQueueSelectFD). -*/ -PR_EXTERN(void) -PL_ProcessPendingEvents(PLEventQueue* self); - -/******************************************************************************* - * Pure Event Queues - * - * For when you're only processing PLEvents and there is no native - * select, thread messages, or AppleEvents. - ******************************************************************************/ - -/* -** Blocks until an event can be returned from the event queue. This routine -** may return NULL if the current thread is interrupted. -*/ -PR_EXTERN(PLEvent*) -PL_WaitForEvent(PLEventQueue* self); - -/* -** One stop shopping if all you're going to do is process PLEvents. Just -** call this and it loops forever processing events as they arrive. It will -** terminate when your thread is interrupted or dies. -*/ -PR_EXTERN(void) -PL_EventLoop(PLEventQueue* self); - -/******************************************************************************* - * Native Event Queues - * - * For when you need to call select, or WaitNextEvent, and yet also want - * to handle PLEvents. - ******************************************************************************/ - -/* -** This routine allows you to grab the file descriptor associated with an -** event queue and use it in the readFD set of select. Useful for platforms -** that support select, and must wait on other things besides just PLEvents. -*/ -PR_EXTERN(PRInt32) -PL_GetEventQueueSelectFD(PLEventQueue* self); - -/* -** This routine will allow you to check to see if the given eventQueue in -** on the current thread. It will return PR_TRUE if so, else it will return -** PR_FALSE -*/ -PR_EXTERN(PRBool) - PL_IsQueueOnCurrentThread( PLEventQueue *queue ); - -/******************************************************************************* - * Event Operations - ******************************************************************************/ - -/* -** The type of an event handler function. This function is passed as an -** initialization argument to PL_InitEvent, and called by -** PL_HandleEvent. If the event is called synchronously, a void* result -** may be returned (otherwise any result will be ignored). -*/ -typedef void* -(PR_CALLBACK *PLHandleEventProc)(PLEvent* self); - -/* -** The type of an event destructor function. This function is passed as -** an initialization argument to PL_InitEvent, and called by -** PL_DestroyEvent. -*/ -typedef void -(PR_CALLBACK *PLDestroyEventProc)(PLEvent* self); - -/* -** Initializes an event. Usually events are embedded in a larger event -** structure which holds event-specific data, so this is an initializer -** for that embedded part of the structure. -*/ -PR_EXTERN(void) -PL_InitEvent(PLEvent* self, void* owner, - PLHandleEventProc handler, - PLDestroyEventProc destructor); - -/* -** Returns the owner of an event. -*/ -PR_EXTERN(void*) -PL_GetEventOwner(PLEvent* self); - -/* -** Handles an event, calling the event's handler routine. -*/ -PR_EXTERN(void) -PL_HandleEvent(PLEvent* self); - -/* -** Destroys an event, calling the event's destructor. -*/ -PR_EXTERN(void) -PL_DestroyEvent(PLEvent* self); - -/* -** Removes an event from an event queue. -*/ -PR_EXTERN(void) -PL_DequeueEvent(PLEvent* self, PLEventQueue* queue); - -/******************************************************************************* - * Private Stuff - ******************************************************************************/ - -struct PLEvent { - PRCList link; - PLHandleEventProc handler; - PLDestroyEventProc destructor; - void* owner; - void* synchronousResult; - /* other fields follow... */ -}; - -/******************************************************************************/ - -/* -** Returns the event queue associated with the main thread. -** -*/ -#ifdef XP_PC -/* ----------------------------------------------------------------------- -** FUNCTION: PL_GetNativeEventReceiverWindow() -** -** DESCRIPTION: -** PL_GetNativeEventReceiverWindow() returns the windows -** handle of the event receiver window associated with the -** referenced PLEventQueue argument. -** -** INPUTS: -** PLEventQueue pointer -** -** RETURNS: -** event receiver window handle. -** -** RESTRICTIONS: MS-Windows ONLY. -** -*/ -PR_EXTERN(HWND) - PL_GetNativeEventReceiverWindow( - PLEventQueue *eqp - ); - -#endif /* XP_PC */ - -PR_END_EXTERN_C - -#endif /* prevent_h___ */ |