Ken Thomases : winemac: Add a delivery limit to events.

Alexandre Julliard julliard at winehq.org
Thu Apr 4 13:54:15 CDT 2013


Module: wine
Branch: master
Commit: ca2d7140fb6f183f7924767afddddd7557c1dc05
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ca2d7140fb6f183f7924767afddddd7557c1dc05

Author: Ken Thomases <ken at codeweavers.com>
Date:   Wed Apr  3 18:56:41 2013 -0500

winemac: Add a delivery limit to events.

Some events are application-wide, not specific to a thread.  Such an event
needs to be broadcast to all GUI-attached threads because we don't know which
are handling events, but we don't want the event to be processed in each.
Often it should only be processed by the first to pull it from its queue.

---

 dlls/winemac.drv/cocoa_app.m    |    7 +++++++
 dlls/winemac.drv/cocoa_event.m  |   30 ++++++++++++++++++------------
 dlls/winemac.drv/macdrv_cocoa.h |    1 +
 3 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m
index e0a29ee..afb290f 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -413,6 +413,13 @@ int macdrv_err_on;
         event->displays_changed.activating = activating;
 
         [eventQueuesLock lock];
+
+        // If we're activating, then we just need one of our threads to get the
+        // event, so it can send it directly to the desktop window.  Otherwise,
+        // we need all of the threads to get it because we don't know which owns
+        // the desktop window and only that one will do anything with it.
+        if (activating) event->deliver = 1;
+
         for (queue in eventQueues)
             [queue postEvent:event];
         [eventQueuesLock unlock];
diff --git a/dlls/winemac.drv/cocoa_event.m b/dlls/winemac.drv/cocoa_event.m
index 78a2f94..366aa46 100644
--- a/dlls/winemac.drv/cocoa_event.m
+++ b/dlls/winemac.drv/cocoa_event.m
@@ -198,7 +198,7 @@ static NSString* const WineEventQueueThreadDictionaryKey = @"WineEventQueueThrea
         char buf[512];
         int rc;
         NSUInteger index;
-        MacDrvEvent* event;
+        MacDrvEvent* ret = nil;
 
         /* Clear the pipe which signals there are pending events. */
         do
@@ -217,22 +217,27 @@ static NSString* const WineEventQueueThreadDictionaryKey = @"WineEventQueueThrea
         [eventsLock lock];
 
         index = 0;
-        for (event in events)
+        while (index < [events count])
         {
+            MacDrvEvent* event = [events objectAtIndex:index];
             if (event_mask_for_type(event->event->type) & mask)
-                break;
-
-            index++;
-        }
-
-        if (event)
-        {
-            [event retain];
-            [events removeObjectAtIndex:index];
+            {
+                [[event retain] autorelease];
+                [events removeObjectAtIndex:index];
+
+                if (event->event->deliver == INT_MAX ||
+                    OSAtomicDecrement32Barrier(&event->event->deliver) >= 0)
+                {
+                    ret = event;
+                    break;
+                }
+            }
+            else
+                index++;
         }
 
         [eventsLock unlock];
-        return [event autorelease];
+        return ret;
     }
 
     - (void) discardEventsMatchingMask:(macdrv_event_mask)mask forWindow:(NSWindow*)window
@@ -416,6 +421,7 @@ macdrv_event* macdrv_create_event(int type, WineWindow* window)
 
     event = calloc(1, sizeof(*event));
     event->refs = 1;
+    event->deliver = INT_MAX;
     event->type = type;
     event->window = (macdrv_window)[window retain];
     return event;
diff --git a/dlls/winemac.drv/macdrv_cocoa.h b/dlls/winemac.drv/macdrv_cocoa.h
index c12545a..ae11b32 100644
--- a/dlls/winemac.drv/macdrv_cocoa.h
+++ b/dlls/winemac.drv/macdrv_cocoa.h
@@ -176,6 +176,7 @@ typedef uint32_t macdrv_event_mask;
 
 typedef struct macdrv_event {
     int                 refs;
+    int                 deliver;
     int                 type;
     macdrv_window       window;
     union {




More information about the wine-cvs mailing list