Pumping Cocoa message loop from background thread - macos

I have a Cocoa-based command line application that programmatically creates an NSWindow + NSView. It uses a nextEventMatchingMask loop to manually pump the event loop and dispatch events. This loop is called by some upper level code periodically to poll for input.
If I run everything on the main thread then this works fine in that the view receives input events correctly.
If instead I move the window creation and message loop to a separate thread then nextEventMatchingMask no longer returns any events and the view doesn't receive input.
I'm aware that only the "main" thread in a Cocoa app is supposed to handle events. This secondary thread however is the only thread that needs to talk to Cocoa, so I would like to use it as the "main" thread as far as Cocoa is concerned. Is this possible? I call NSApplicationLoad from this thread, and as far as I know this is the first Cocoa function called in the process.
If I can't specify which is the main Cocoa thread then, is there any other way to be able to create an NSWindow on a background thread and receive events for it? I can't do something like call NSApplication Run because I am not in control of the application's main loop. I just need to pull input events from the Window when the upper level code requests that I do so.

Maybe you need to start the runloop on the secondary thread. In your main thread, when you spawn off your secondary thread, call something like this:
[NSThread detachNewThreadSelector:#selector(launchThread)
toTarget:[ThreadHandler class]
withObject:nil];
In the ThreadHandler class, have something like:
+ (void)launchThread
{
NSRunLoop *threadRunLoop = [NSRunLoop currentRunLoop];
while (someThreadExitCondition && [threadRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:1]]);
}
This should start your thread runloop processing events. I'm not sure without testing whether this would allow you to process events for a window created in a secondary thread, but it might get you started on how to run the thread's runloop. You could even set up something like a Distributed Objects situation where you pump events from the main event loop through a NSConnection to the secondary thread (example). Hopefully this might at least give you another avenue to pursue.

That's not behavior I would rely on.
If you need to run your backend on a thread which is not restricted by a run loop, then run it on a secondary thread in order to run the UI from the main thread.
Alternatively, you could create another process...

Related

asynctask WAIT mode

When i press button1 (execute) on UI i run AsyncTask. The task was run success.
I press another button2 (cancel) to stop asynctask from main thread
asynctask.cancel(true);
but AsyncTask thread dont self kill! (see second screenshot)
The asynctask switch to WAIT mode
then i can press button1 (execute) again and run NEW task and press button2 (cancel)
And i have queations:
Why task dont selfkill after used cancel(true)?
And whay mean WAIT mode?
AsyncTask under the hood uses a ThreadPoolExecutor. Those threads might not go away for a bit because it'd be a waste to keep creating and tearing down those threads too often. After a while if you create more AsyncTasks you'll find that it'll stop creating new threads and it'll re-use the old ones.
Update to address some details:
You would think that if there are free threads in the pool, it wouldn't create new ones, but this isn't exactly true. The idea is that there's a certain number of threads that are useful to have around to keep processing asynchronous tasks. This is called the core pool size. In Android's AsyncTask case, they seem to have set it to 5. If you look at the documentation for ThreadPoolExecutor it says:
When a new task is submitted in method execute(Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle.
There's also a maximum fittingly called the maximum pool size.

Continuously running code in Win32 app

I have a working GUI and now need to add some code that will need to run continuously and update the GUI with data. Where should this code go? I know that it should not go into the message loop because it might block incoming messages to the window, but I'm confused on where in my window process this code could run.
You have a choice: you can use a thread and post messages back to the main thread to update the GUI (or update the GUI directly, but don't try this if you used MFC), or you can use a timer that will post you messages periodically, you then simply implement a handler for the timer and do whatever you need to there.
The thread is best for a complicated, slow process that might block. If the process of getting data is quick (and/or can be set to timeout on error) then a timer is simpler.
Have you looked into threading at all?
Typically, you would create one thread that performs the background task (in this case, reading the voltage data) and storing it into a shared buffer. The GUI thread simply reads that buffer every so often (on redraw, every 30 seconds, when the user clicks refresh, etc) and displays the data.
Your background thread runs on its own schedule, getting CPU time from the OS, and is not bound to the UI or message pump. It can use some type of timer to monitor the data source and read things in as necessary.
Now, since the threads run separately and may run at the same time, you need to make them aware of one another. This can be done with locks (look into mutexes). For example:
The monitor reads the current voltage and stores it in the buffer.
The background/monitor thread locks the buffer holding the latest sample.
The monitor copies the internal buffer to the shared one.
The monitor unlocks the buffer.
Simultaneously, but separately, the UI thread:
Gets a redraw call.
Waits for the buffer to be unlocked, then reads the value.
Draws the UI with the buffer value.
Setting up a new thread and using it, in most Windows GUI-producing languages, is pretty simple. C/++ and C# both have very simple APIs for creating a new thread and having it work on some task, you usually just need to provide a function for the thread to process. See the MSDN docs on CreateThread for a C example.
The concept of threading and locking is for the most part language-agnostic, and similar in most C-inspired languages. You'll need to have your main (in this case, probably UI) thread control the lifetime of the worker: start the worker after the UI is created, and kill it before the UI is shut down.
This approach has a little bit of overhead up front, especially if your data fetch is very simple. If your data source changes (a network request, some blocking data source, reading over actual wires from a physical sensor, etc) then you only need to change the monitor thread and the UI doesn't need to know.

Are aysnchronous NSURLConnections multi-threaded

I've noticed that if I create an NSURLConnection and fire the request, all is well. My delegate methods get called and the last delegate method get's called well after the code block invoking the connection completes. Great.
That leads me to believe the connections are asynchronous which implies that they're multi-threaded. Is that correct? Could they be asynchronous but in the same thread? No, that's crazy - right?
But, in every example I've seen using an NSOperation, NSURLConnections are always scheduledInRunLoop after which [runLoop runMode ...] is invoked in a while loop.
Can someone explain exactly what is happening here? It seems to me that the first case requires spawning secondary threads but no manual invocation of the run loop (on those threads) while NSOperation (in a new thread) does require manual invocation of the run loop.
Why is no manual invocation required for the first case?
NSURLConnection does spawn a single background thread to manage all instances of itself, but this is generally irrelevant to the caller, since the delegate calls are made on whatever thread owns the runloop the connection was scheduled in. (This fact turned out to be very relevant to me recently, but these things really only come up when dealing with insane crashers in multi-threaded apps.)
For more caller-relevant details, you should look at the docs for -[NSURLConnection scheduleInRunLoop:forMode:]. It explains how to manually handle scheduling and unscheduling, and how NSURLConnections behave in a multi-threaded environment.
If you are unclear on how run loops work and how they perform asynchronous actions without requiring additional threads, you should read Run Loops in the Threading Programming Guide. This is a very important topic for moving to more advanced Cocoa development.
Because the main thread already has a run loop, I'd imagine.
If you want to run NSURLConnection in another thread, you should create a run loop like this in your thread's main method:
while (!finished)
{
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}

What is a browser event loop?

I have been doing some web application programming using GWT and have been confused by the term "browser event loop".
I have encountered situations where I need to execute deferred commands and "do something" after the browser event loop completes.
I would like to know as to what exactly it is and what happens during the event loop process and in which order?
A browser event loop is a thread started by the browser that is constantly scanning for and running different events, just like it sounds. As events occur they are put in the event queue and run in turn by the one event thread. Your javascript should not create its own loops waiting for it to complete or anything like that...it will block that one continuous event loop thread. Instead you would use something like setTimeout or setInterval and check for whatever conditions you are waiting for so the browser can do work while it 'waits'.
GWT is nice in that it can co-opt this process somewhat using the scheduler -- in your case where you want to run something after the event loop 'completes' you will probably want to use scheduleFinally or scheduleDeferred. It will inject a handler for a piece of code into the event queue so that it will run after all other code in the current execution context (current execution context == where ever you are in the current JavaScript object hierarchy with the window as the root object) is run but before the next event that is placed in the queue.

Question about multiple callbacks occurring at the same time

I have a thread watching for file system events on Mac OS X. If I copy 100 files into a folder that is being watched, I obviously get multiple file system events, and therefore multiple callback calls. I'm wondering if these callback calls are processed one after another? Or does each event invoke an OS thread, which in turn calls the callback function, in which case we would have multiple threads each executing the same callback function?
It depends which mechanism you're using to watch file system events.
Every access to a file generates a notification inside a kernel.
If you use the public FSEvents API, too frequent updates are coalesced to a single notification. This case, the receiving end is managed by a run loop, i.e. the callback is not called in the new background thread, or the context of the OS thread. It's run in the event loop you specified, usually the main thread which runs the main event-processing loop.
If you directly tap into /dev/fsevents (see e.g. the OS X book), you get all the events in the calling thread one by one, with possibly multiple events returned by one call.
Similarly, if you instead use BSD-derived kqueue, you would get multiple events from the call of kqueue if the events are frequent.
In any case the OS don't run your callback in a new/OS thread, nor magically duplicate your thread watching the file system activity, so that they can process the events simultaneously.

Resources