I guess you’re filling up the queue (underlying mach port)…
You can confirm this using the “scheduling” or “system call” instrument in Instruments. (Create a new blank document, add the instrument, then under File > Record Options...
make sure “deferred mode” is checked.) This will show all thread activity in your app (when threads block, when they sleep, when they are activated, and why).
I would first try raising the thread priority (cf. man 3 PTHREAD_SCHEDPARAM
) of the thread calling CGEventPost
. If your thread is blocked on a lower priority thread, the kernel should temporarily elevate the priority of the blocking thread to avoid priority inversion and help your task complete earlier.
Overall I think you will have to implement a 2-thread solution, as below:
Create a queue for events you want to post. Post events to this queue from your main thread (or event posting thread), then signal a second thread (an event consumer thread you create) to walk the queue and post any outstanding events with CGEventPost
.
When CGEventPost
blocks, your second event-posting thread will block, but this won’t block any other threads. When CGEventPost
eventually unblocks, it will consume any outstanding events posted by your event consumer thread and the event consumer thread can resume posting events.
Another possibility: can you coallesce events? There are certain types of events (mouse moves?) that you could coallesce into fewer events. You will probably still run into the queue limit of CGEventPost
at times, I think the 2-thread approach is probably your best bet.