summaryrefslogtreecommitdiff
path: root/redo/uitask_darwin.m
diff options
context:
space:
mode:
Diffstat (limited to 'redo/uitask_darwin.m')
-rw-r--r--redo/uitask_darwin.m39
1 files changed, 39 insertions, 0 deletions
diff --git a/redo/uitask_darwin.m b/redo/uitask_darwin.m
index d802911..9d25a61 100644
--- a/redo/uitask_darwin.m
+++ b/redo/uitask_darwin.m
@@ -129,9 +129,48 @@ void uistop(void)
[NSApp postEvent:e atStart:NO]; // let pending events take priority
}
+// because dispatch_suspend()/dispatch_resume() can't be used with the main queue
+static BOOL inmodal = NO;
+static void **modalqueue = NULL;
+static size_t mqlen = 0;
+static size_t mqcap = 0;
+
+void beginModal(void)
+{
+ inmodal = YES;
+ if (modalqueue == NULL) {
+ mqcap = 128;
+ modalqueue = (void **) malloc(mqcap * sizeof (void *));
+ if (modalqueue == NULL)
+ abort();//TODO
+ mqlen = 0;
+ }
+}
+
+void endModal(void)
+{
+ size_t i;
+
+ inmodal = NO;
+ for (i = 0; i < mqlen; i++)
+ doissue(modalqueue[i]);
+ mqlen = 0;
+}
+
// thanks to mikeash in irc.freenode.net/#macdev for suggesting the use of Grand Central Dispatch and blocks for this
void issue(void *what)
{
+ if (inmodal) {
+ modalqueue[mqlen] = what;
+ mqlen++;
+ if (mqlen >= mqcap) {
+ mqcap *= 2;
+ modalqueue = (void **) realloc(modalqueue, mqcap * sizeof (void *));
+ if (modalqueue == NULL)
+ abort();//TODO
+ }
+ return;
+ }
dispatch_async(dispatch_get_main_queue(), ^{
doissue(what);
});