summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlarryh%netscape.com <devnull@localhost>1999-01-05 00:08:28 +0000
committerlarryh%netscape.com <devnull@localhost>1999-01-05 00:08:28 +0000
commitea46b106dbd6427a3aaaab77bd526ea5159921fe (patch)
treeef6aa43d737dcec17ad94e7828dbfb817b7aacc7
parentabf5ef2fd87e19b700fb1ab31995cbb5e2c08387 (diff)
downloadnspr-hg-ea46b106dbd6427a3aaaab77bd526ea5159921fe.tar.gz
BugZilla: 2131. BugSplat: 337698.
Thanks to "Adam Lock" <locka@iol.ie> for suggestions. Thanks to Rick Potts for suggestions and critique of the design.
-rw-r--r--lib/ds/plevent.c362
-rw-r--r--lib/ds/plevent.h94
2 files changed, 325 insertions, 131 deletions
diff --git a/lib/ds/plevent.c b/lib/ds/plevent.c
index 25f36da2..e0ee94d1 100644
--- a/lib/ds/plevent.c
+++ b/lib/ds/plevent.c
@@ -22,18 +22,20 @@
#define PostMessage WinPostMsg
#define DefWindowProc WinDefWindowProc
typedef MPARAM WPARAM,LPARAM;
-#endif
+#endif /* XP_OS2 */
+
#include "plevent.h"
#include "prmem.h"
#include "prcmon.h"
#include "prlog.h"
+
#if !defined(WIN32)
#include <errno.h>
#include <stddef.h>
#if !defined(XP_OS2)
#include <unistd.h>
-#endif
-#endif
+#endif /* !XP_OS2 */
+#endif /* !Win32 */
#if defined(XP_MAC)
#include <AppleEvents.h>
@@ -42,7 +44,8 @@ typedef MPARAM WPARAM,LPARAM;
#else
#include "private/pprthred.h"
#include "private/primpl.h"
-#endif
+#endif /* XP_MAC */
+
static PRLogModuleInfo *event_lm = NULL;
@@ -50,46 +53,71 @@ 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;
-#ifdef XP_UNIX
- PRInt32 eventPipe[2];
- PRPackedBool nativeNotifier;
- int notifyCount;
+ PRCList queue;
+ PRMonitor* monitor;
+ PRThread* handlerThread;
+ EventQueueType type;
+ PRBool processingEvents;
+#if defined(XP_UNIX)
+ PRInt32 eventPipe[2];
+ int notifyCount;
+#elif defined(_WIN32) || defined(WIN16)
+ HWND eventReceiverWindow;
+#elif defined(XP_OS2)
+ HWND eventReceiverWindow;
#endif
- PRBool processingEvents;
};
#define PR_EVENT_PTR(_qp) \
((PLEvent*) ((char*) (_qp) - offsetof(PLEvent, link)))
static PRStatus _pl_SetupNativeNotifier(PLEventQueue* self);
-static void _pl_CleanupNativeNotifier(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 );
#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
-PLEventQueue * _pr_main_event_queue;
-HWND _pr_eventReceiverWindow;
+PLEventQueue * _pr_MainEventQueue;
+
#if defined(OS2)
BOOL rc;
ULONG _pr_PostEventMsgId;
#else
UINT _pr_PostEventMsgId;
static char *_pr_eventWindowClass = "NSPR:EventWindow";
-#endif
-#endif
+#endif /* OS2 */
+#endif /* Win32, Win16, OS2 */
/*******************************************************************************
* Event Queue Operations
******************************************************************************/
-PR_IMPLEMENT(PLEventQueue*)
-PL_CreateEventQueue(char* name, PRThread* handlerThread)
+/*
+** _pl_CreateEventQueue() -- Create the event queue
+**
+**
+*/
+static PLEventQueue *
+ _pl_CreateEventQueue(
+ char *name,
+ PRThread *handlerThread,
+ EventQueueType qtype
+)
{
PRStatus err;
PLEventQueue* self = NULL;
@@ -108,10 +136,14 @@ PL_CreateEventQueue(char* name, PRThread* handlerThread)
self->monitor = mon;
self->handlerThread = handlerThread;
self->processingEvents = PR_FALSE;
+ self->type = qtype;
PR_INIT_CLIST(&self->queue);
- err = _pl_SetupNativeNotifier(self);
- if (err) goto error;
-
+ if ( qtype == EventQueueIsNative )
+ {
+ err = _pl_SetupNativeNotifier(self);
+ if (err) goto error;
+ }
+ _md_CreateEventQueue( self );
return self;
error:
@@ -119,8 +151,35 @@ PL_CreateEventQueue(char* name, PRThread* handlerThread)
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)
{
@@ -145,7 +204,8 @@ PL_DestroyEventQueue(PLEventQueue* self)
/* destroy undelivered events */
PL_MapEvents(self, _pl_destroyEvent, NULL);
- _pl_CleanupNativeNotifier(self);
+ if ( self->type == EventQueueIsNative )
+ _pl_CleanupNativeNotifier(self);
/* destroying the monitor also destroys the name */
PR_ExitMonitor(self->monitor);
@@ -157,7 +217,7 @@ PL_DestroyEventQueue(PLEventQueue* self)
PR_IMPLEMENT(PRStatus)
PL_PostEvent(PLEventQueue* self, PLEvent* event)
{
- PRStatus err;
+ PRStatus err = PR_SUCCESS;
PRMonitor* mon;
if (self == NULL)
@@ -172,16 +232,14 @@ PL_PostEvent(PLEventQueue* self, PLEvent* event)
}
/* notify even if event is NULL */
- err = _pl_NativeNotify(self);
- if (err != PR_SUCCESS) goto done;
+ 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);
-
- done:
PR_ExitMonitor(mon);
return err;
}
@@ -221,7 +279,7 @@ PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event)
for (i = 0; i < entryCount; i++)
PR_EnterMonitor(self->monitor);
}
- result = event->synchronousResult;
+ result = event->synchronousResult;
event->synchronousResult = NULL;
}
@@ -238,7 +296,7 @@ PR_IMPLEMENT(PLEvent*)
PL_GetEvent(PLEventQueue* self)
{
PLEvent* event = NULL;
- PRStatus err;
+ PRStatus err = PR_SUCCESS;
PRMonitor* mon;
if (self == NULL)
@@ -247,7 +305,9 @@ PL_GetEvent(PLEventQueue* self)
mon = self->monitor;
PR_EnterMonitor(mon);
- err = _pl_AcknowledgeNativeNotify(self);
+ if ( self->type == EventQueueIsNative )
+ err = _pl_AcknowledgeNativeNotify(self);
+
if (err) goto done;
if (!PR_CLIST_IS_EMPTY(&self->queue)) {
@@ -543,47 +603,59 @@ _pl_CleanupNativeNotifier(PLEventQueue* self)
#endif
}
+#if defined(_WIN32) || defined(WIN16)
static PRStatus
_pl_NativeNotify(PLEventQueue* self)
{
-#if defined(XP_UNIX)
-
-# define NOTIFY_TOKEN 0xFA
- PRInt32 count;
- unsigned char buf[] = { NOTIFY_TOKEN };
-
- count = write(self->eventPipe[1], buf, 1);
- self->notifyCount++;
- return (count == 1) ? PR_SUCCESS : PR_FAILURE;
-
-#elif defined(XP_PC)
/*
** Post a message to the NSPR window on the main thread requesting
** it to process the pending events. This is only necessary for the
** main event queue, since the main thread is waiting for OS events.
*/
-#ifndef XP_OS2
- if (self == _pr_main_event_queue) {
- PostMessage( _pr_eventReceiverWindow, _pr_PostEventMsgId,
+ if (self == _pr_MainEventQueue ) {
+ PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId,
(WPARAM)0, (LPARAM)self);
}
return PR_SUCCESS;
-#else
+}/* --- end _pl_NativeNotify() --- */
+#endif
+
+#if defined(XP_OS2)
+static PRStatus
+_pl_NativeNotify(PLEventQueue* self)
+{
+ BOOL rc;
+
if (self == _pr_main_event_queue) {
- rc = WinPostMsg(_pr_eventReceiverWindow, _pr_PostEventMsgId,
+ rc = WinPostMsg( self->eventReceiverWindow, _pr_PostEventMsgId,
0, MPFROMP(self));
}
return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE;
-#endif
-#else
-#if defined(XP_MAC)
+}/* --- end _pl_NativeNotify() --- */
+#endif /* Winxx */
+
+#if defined(XP_UNIX)
+static PRStatus
+_pl_NativeNotify(PLEventQueue* self)
+{
+#define NOTIFY_TOKEN 0xFA
+ PRInt32 count;
+ unsigned char buf[] = { NOTIFY_TOKEN };
+
+ count = write(self->eventPipe[1], buf, 1);
+ self->notifyCount++;
+ return (count == 1) ? PR_SUCCESS : PR_FAILURE;
+}/* --- end _pl_NativeNotify() --- */
+#endif /* XP_UNIX */
+#if defined(XP_MAC)
+static PRStatus
+_pl_NativeNotify(PLEventQueue* self)
+{
#pragma unused (self)
return PR_SUCCESS; /* XXX can fail? */
-
-#endif
-#endif
}
+#endif /* XP_MAC */
static PRStatus
_pl_AcknowledgeNativeNotify(PLEventQueue* self)
@@ -625,14 +697,13 @@ PL_GetEventQueueSelectFD(PLEventQueue* self)
}
-
#if defined(WIN16) || defined(_WIN32)
/*
** Global Instance handle...
** In Win32 this is the module handle of the DLL.
**
*/
-HINSTANCE _pr_hInstance;
+static HINSTANCE _pr_hInstance;
#endif
#if defined(WIN16)
@@ -680,11 +751,11 @@ BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
#if defined(WIN16) || defined(_WIN32) || defined(XP_OS2)
PR_IMPLEMENT(PLEventQueue *)
-PL_GetMainEventQueue()
+ PL_GetMainEventQueue( void )
{
- PR_ASSERT(_pr_main_event_queue);
+ PR_ASSERT( _pr_MainEventQueue );
- return _pr_main_event_queue;
+ return _pr_MainEventQueue;
}
#ifdef XP_OS2
MRESULT EXPENTRY
@@ -728,7 +799,7 @@ static PRLock *initLock;
** InitWinEventLib() -- Create the Windows initialization lock
**
*/
-static PRStatus InitWinEventLib( void )
+static PRStatus InitEventLib( void )
{
PR_ASSERT( initLock == NULL );
@@ -741,31 +812,47 @@ static PRStatus InitWinEventLib( void )
PR_IMPLEMENT(void)
-PL_InitializeEventsLib(char *name)
+ PL_InitializeEventsLib( char *name )
{
-#ifdef XP_OS2
- PSZ _pr_eventWindowClass;
+ PLEventQueue *eventQueue;
- _pr_main_event_queue = PL_CreateEventQueue(name, PR_GetCurrentThread());
+ PR_CallOnce( &once, InitEventLib );
- WinRegisterClass( WinQueryAnchorBlock( HWND_DESKTOP),
- _pr_eventWindowClass,
- _md_EventReceiverProc,
- 0, 0);
+ PR_Lock( initLock );
+ if ( isInitialized == PR_FALSE )
+ {
+ isInitialized = PR_TRUE;
- _pr_eventReceiverWindow = WinCreateWindow( HWND_DESKTOP,
- _pr_eventWindowClass,
- "", 0,
- 0, 0, 0, 0,
- HWND_DESKTOP,
- HWND_TOP,
- 0,
- NULL,
- NULL);
-
- _pr_PostEventMsgId = WinAddAtom(WinQuerySystemAtomTable(),
- "NSPR_PostEvent");
-#else
+ eventQueue = PL_CreateEventQueue( name, PR_GetCurrentThread() );
+ _pr_MainEventQueue = eventQueue;
+ }
+ PR_Unlock( initLock );
+
+ PR_LOG(event_lm, PR_LOG_DEBUG,("PL_InitializeeventsLib(). Done!\n"));
+ return;
+}
+#endif /* Win16, Win32, OS2 */
+
+#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
+
+PR_IMPLEMENT(HWND)
+ PR_GetEventReceiverWindow( void )
+{
+ HWND eventReceiver = _pr_MainEventQueue->eventReceiverWindow;
+
+ if( eventReceiver != 0 )
+ return eventReceiver;
+ else
+ return 0;
+}
+#endif
+
+#if defined(_WIN32) || defined(WIN16)
+/*
+** _md_CreateEventQueue() -- ModelDependent initializer
+*/
+static void _md_CreateEventQueue( PLEventQueue *eventQueue )
+{
WNDCLASS wc;
/*
@@ -776,61 +863,78 @@ PL_InitializeEventsLib(char *name)
** we have exclusive control over the initialization sequence.
**
*/
- PR_CallOnce( &once, InitWinEventLib );
- PR_Lock( initLock );
- if ( isInitialized == PR_FALSE )
- {
- isInitialized = PR_TRUE;
- _pr_main_event_queue = PL_CreateEventQueue(name, PR_GetCurrentThread());
-
- /* 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);
- }
+ /* 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 */
- _pr_eventReceiverWindow = CreateWindow(_pr_eventWindowClass,
- "NSPR:EventReceiver",
- 0, 0, 0, 10, 10,
- NULL, NULL, _pr_hInstance,
- NULL);
- PR_ASSERT(_pr_eventReceiverWindow);
-
- PR_LOG(event_lm, PR_LOG_DEBUG,("PL_InitializeeventsLib(). Done!\n"));
- }
- PR_Unlock( initLock );
-#endif
- return;
-}
-#endif
+ /* 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(_WIN32) || defined(WIN16) || defined(XP_OS2)
-PR_IMPLEMENT(HWND)
-PR_GetEventReceiverWindow()
+#if defined(XP_OS2)
+/*
+** _md_CreateEventQueue() -- ModelDependent initializer
+*/
+static void _md_CreateEventQueue( PLEventQueue *eventQueue )
{
- if(_pr_eventReceiverWindow != 0)
- {
- return _pr_eventReceiverWindow;
- }
+ PSZ _pr_eventWindowClass;
- return 0;
+ WinRegisterClass( WinQueryAnchorBlock( HWND_DESKTOP),
+ _pr_eventWindowClass,
+ _md_EventReceiverProc,
+ 0, 0);
-}
-#endif
+ eventQueue->eventReceiverWindow = WinCreateWindow( HWND_DESKTOP,
+ _pr_eventWindowClass,
+ "", 0,
+ 0, 0, 0, 0,
+ HWND_DESKTOP,
+ HWND_TOP,
+ 0,
+ NULL,
+ NULL);
+
+ eventQueue->postEventMsgId = WinAddAtom(WinQuerySystemAtomTable(),
+ "NSPR_PostEvent");
+ return;
+} /* end _md_CreateEventQueue() */
+#endif /* XP_OS2 */
+#if defined(XP_UNIX)
+/*
+** _md_CreateEventQueue() -- ModelDependent initializer
+*/
+static void _md_CreateEventQueue( PLEventQueue *eventQueue )
+{
+ /* 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 --- */ \ No newline at end of file
diff --git a/lib/ds/plevent.h b/lib/ds/plevent.h
index ff2255b8..7330a8d9 100644
--- a/lib/ds/plevent.h
+++ b/lib/ds/plevent.h
@@ -196,6 +196,70 @@ typedef struct PLEventQueue PLEventQueue;
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.
*/
@@ -397,14 +461,40 @@ struct PLEvent {
/******************************************************************************/
/*
-** Returns the event queue associated with the main thread. Note that
-** the event queue is now created by NSPR.
+** Returns the event queue associated with the main thread.
+**
*/
#ifdef XP_PC
PR_EXTERN(PLEventQueue *)
PL_GetMainEventQueue(void);
+/*
+** Initializes the main event queue.
+*/
PR_EXTERN(void)
PL_InitializeEventsLib(char *name);
+
+/* -----------------------------------------------------------------------
+** 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