Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Java has it's own event dispatch thread (actually, it can have multiple event dispatch threads). AppKit has it's own event dispatch thread, and (virtually all) AppKit UI operations must take place on that "main" thread, while most (virtually all) Java UI operations must take place on Java's event thread.

When Java needs to affect "native" widgets, it calls through to native; this necessitates using performSelectorOnMainThread:; most of the time it expects that these calls are synchronous, so we need to set wait:YES. (ed. actually, almost all calls without return values can now be done without waiting)

When AppKit needs to ask Java for something, or it needs to perform some operation synchronously against the Java event thread, we do the moral equivalent to performSelectorOnMainThread, but against the Java event thread.

The "trick" in our case, is that when we block the AppKit thread against the Java EDT, we spin the AppKit runloop in a special runloopmode. Calls from Java -> AppKit using performSelectorOnMainThread are allowed to run in that special runloopmode.

So far, this is working "OK" (performance, Accessibility and Printing are the trickiest bits), but it means that we really aren't allowed to "share" locks between Java and AppKit or we get a classic deadlock between the shared lock and the AppKit thread.

...