winemac: Don't use the main dispatch queue to implement OnMainThread() for a thread with no event queue.
The main dispatch queue is a serial queue and is a shared resource. If we submit a long-running task to it, then no other tasks, including those submitted by the system frameworks, can run until it completes.
This commit is contained in:
parent
a5b51a766b
commit
2f68e47167
|
@ -460,42 +460,55 @@ void OnMainThread(dispatch_block_t block)
|
|||
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
|
||||
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
|
||||
WineEventQueue* queue = [threadDict objectForKey:WineEventQueueThreadDictionaryKey];
|
||||
dispatch_semaphore_t semaphore;
|
||||
__block BOOL finished;
|
||||
|
||||
if (!queue)
|
||||
{
|
||||
/* Fall back to synchronous dispatch without handling query events. */
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
[pool release];
|
||||
return;
|
||||
semaphore = dispatch_semaphore_create(0);
|
||||
dispatch_retain(semaphore);
|
||||
}
|
||||
|
||||
finished = FALSE;
|
||||
OnMainThreadAsync(^{
|
||||
block();
|
||||
finished = TRUE;
|
||||
[queue signalEventAvailable];
|
||||
if (queue)
|
||||
[queue signalEventAvailable];
|
||||
else
|
||||
{
|
||||
dispatch_semaphore_signal(semaphore);
|
||||
dispatch_release(semaphore);
|
||||
}
|
||||
});
|
||||
|
||||
while (!finished)
|
||||
if (queue)
|
||||
{
|
||||
MacDrvEvent* macDrvEvent;
|
||||
struct kevent kev;
|
||||
|
||||
while (!finished &&
|
||||
(macDrvEvent = [queue getEventMatchingMask:event_mask_for_type(QUERY_EVENT)]))
|
||||
while (!finished)
|
||||
{
|
||||
queue->event_handler(macDrvEvent->event);
|
||||
}
|
||||
MacDrvEvent* macDrvEvent;
|
||||
struct kevent kev;
|
||||
|
||||
if (!finished)
|
||||
{
|
||||
[pool release];
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
while (!finished &&
|
||||
(macDrvEvent = [queue getEventMatchingMask:event_mask_for_type(QUERY_EVENT)]))
|
||||
{
|
||||
queue->event_handler(macDrvEvent->event);
|
||||
}
|
||||
|
||||
kevent(queue->kq, NULL, 0, &kev, 1, NULL);
|
||||
if (!finished)
|
||||
{
|
||||
[pool release];
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
kevent(queue->kq, NULL, 0, &kev, 1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
||||
dispatch_release(semaphore);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue