Re: Max + SWT: Threading issue


Forums > Java > Max + SWT: Threading issue

LR
July 28, 2011 | 4:41 pm

I have spent quite a bit of time trying to understand the scenario, and I believe it is the SWT dispatch loop doesn’t work along side with Max dispatch loop. For any cocoa interaction code must execute in the main thread. So either the SWT dispatch code is running or the max dispatching code. What we see is if we don’t have the following template code, our SWT application doesn’t receive any events (it appears non-responsive). The following is the common example of SWT dispatching code.

while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();

Using the above code in the main java thread (APP-KIT) causes us to exclusively remain in java, and never return this thread back to MAXMSP. What we see is the SWT window is fully responsive, and works perfectly, but our Max requests are not handled. I suspect they are queuing up within MaxMSP. We aren’t returning control of the main thread to Max, so no one is working on those events.

It took a while, but we figured out a very HACKY workaround. We put the above code into a thread that MaxSystem.deferLow(), and if there isn’t any SWT work, we re-queue ourselves deferLow() and continue into MaxMSP. At the sametime, we have a ‘Waker’ thread, that forces us to come out of display.sleep() every 50ms, to ensure we do not sleep forever. So we are sharing the event handling with SWT and MaxMSP.

PROBLEM IS: it makes the ui somewhat unresponsive. Some mouse events are lost. 95% of keystrokes targeted to MaxMSP are ignored. So this hack doesn’t really work.

I am hoping there is a MaxMSP expert who can help us out. Here is the sample code and patch we wrote to understand and "workaround" the problem

The basic example works like this:
- Create an SWT Display object.
- Create a new Thread, and execute it.
- In the execution loop, put the thread to sleep for a very short period of time (ex; 50 ms). When it wakes, send a wake command to the Display, which is most likely put to sleep by a Dispatcher.
- meanwhile, place a Dispatcher object on the Max thread using deferLow and pass in the Display. The Dispatcher, on execute(), checks to see if there is anything in the queue for the Display thread. If there isn’t, it puts Display to sleep. When it awakens, it checks to see if there is anything in the queue for the Display thread. If there isn’t, it puts itself on the queue.