Sync'd with the HEAD branch again. unlabeled-3.19.8
authorcls%seawood.org
Tue, 21 Sep 1999 19:43:23 +0000
branchunlabeled-3.19.8
changeset 817 66850697085c
parent 803 30c5e118074d
push idunknown
push userunknown
push dateunknown
Sync'd with the HEAD branch again.
lib/ds/plevent.c
--- a/lib/ds/plevent.c
+++ b/lib/ds/plevent.c
@@ -333,31 +333,35 @@ PL_GetEvent(PLEventQueue* self)
     PLEvent* event = NULL;
     PRStatus err = PR_SUCCESS;
     PRMonitor* mon;
 
     if (self == NULL)
     return NULL;
 
     mon = self->monitor;
-    PR_EnterMonitor(mon);
+    if (mon) {
+      PR_EnterMonitor(mon);
+    }
 
     if ( self->type == EventQueueIsNative )
         err = _pl_AcknowledgeNativeNotify(self);
 
     if (err) goto done;
 
     if (!PR_CLIST_IS_EMPTY(&self->queue)) {
     /* then grab the event and return it: */
     event = PR_EVENT_PTR(self->queue.next);
     PR_REMOVE_AND_INIT_LINK(&event->link);
     }
 
   done:
-    PR_ExitMonitor(mon);
+    if (mon) {
+      PR_ExitMonitor(mon);
+    }
     return event;
 }
 
 PR_IMPLEMENT(PRBool)
 PL_EventAvailable(PLEventQueue* self)
 {
     PRBool result = PR_FALSE;
 
@@ -457,24 +461,52 @@ PR_IMPLEMENT(void)
 PL_ProcessPendingEvents(PLEventQueue* self)
 {
     if (self == NULL)
     return;
 
   if (PR_FALSE != self->processingEvents) return;
 
     self->processingEvents = PR_TRUE;
+#if !defined(WIN32)
     while (PR_TRUE) {
     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"));
     }
+#else
+    /* Only process the events that are already in the queue, and
+     * not any new events that get added. Do this by making a copy of
+     * the queue
+     */
+    PR_EnterMonitor(self->monitor);
+    if (PR_CLIST_IS_EMPTY(&self->queue)) {
+      PR_ExitMonitor(self->monitor);
+    } else {
+      struct PLEventQueue  tmpQueue;
+      /* Copy the events to a temporary queue */
+      memcpy(&tmpQueue, self, sizeof(tmpQueue));
+      tmpQueue.queue.next->prev = &tmpQueue.queue;
+      tmpQueue.queue.prev->next = &tmpQueue.queue;
+      tmpQueue.monitor = 0; /* don't waste time locking this queue when getting events */
+      PR_INIT_CLIST(&self->queue);
+      PR_ExitMonitor(self->monitor);
+      /* Now process the existing events */
+      while (PR_TRUE) {
+      PLEvent* event = PL_GetEvent(&tmpQueue);
+          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"));
+      }
+    }
+#endif
     self->processingEvents = PR_FALSE;
 }
 
 /*******************************************************************************
  * Event Operations
  ******************************************************************************/
 
 PR_IMPLEMENT(void)