A few weeks back Esteban Lorenzano of Mars fame http://news.squeak.org/2009/01/08/squeak-goes-to-mars/
asked about the SqueakProxy and Objective C Bridge I've been working on, could he use it to get a callback for oh say windowShouldClose: from an NSWindow instance then have some smalltalk code run, and determine YES or NO? Well that sounds simple, should only take a bit of time,... time passes (lots) and lots of iChat and email pass by too. Now it seems the issue is that on OSX and the iPhone UI related things can only run on the main thread, so let's talk a bit about that history. When the Carbon Squeak VM was ported from OS-9 we actually started the interpreter on a background thread. This worked fine until Apple started enforcing the rule about UI related things can only be run on the main thread as they quickly revised the operating system. The VM was patched to ensure any UI related things were performed on the main thread via a cross thread callback. This worked fine until the Sophie team started to exploit Quicktime for audio/video and graphics. It turned out QuickTime calls *really* needed to be on the UI thread. We could funnel *ALL* the FFI calls to the main thread, but that is expensive. So the carbon VM was changed to co-execute interpreter() on the UI thread via polling logic, where the interpreter runs and polls for UI events to service. This solved the problem of deciding should this FFI call be on the UI thread or the background squeak thread, plus then ensured any plugins etc would always have logic that ran on the main UI thread without having the developers worry their brains over it. The curious might note this explains the odd behaviour of the carbon VM when you toast the morphic event polling process, then it fails to service macintosh menus because it's really waiting for some squeak process to invoke get next event so it can service the pending menu interaction. Now the Unix os-x vm using cocoa is less affected by this, but it will NOT run FFI based quicktime calls, also the iPhone VM is *extremely* broken if you do any UIKit stuff (even allocating UIKit objects) from a background thread. For the iPhone VM you *must* remember to execute objective C calls either on the main UI thread, or the background thread. We have to run the iPhone VM on a background thread because the trick we use for the carbon VM to make it run on the foreground thread is broken on the iPhone. Plus if you don't service UI events fast enough on the foreground thread, then the iPhone watchdog will kill you with exception code 0x0badf00d (yes really). Ok, but given the Squeak VM is running on the UI thread then why can we just deal with the windowShouldClose: Well good question, and days of work. Now it seems when get next event is called, we ask the operating system if there are any pending UI events, if so we ask the operating system to service them. Fine, now the SqueakProxy object enters the mix. On the windowShouldClose: the SqueakProxy instance at some point into this operating system call stack gets the windowShouldClose: message. So what does it want to do, well it wants to let the Squeak interpreter *run* so it can convert the NSInvocation instance into a squeak message send, send a windowShouldClose: to the Smalltalk SqueakProxy instance and set the return value, then of course return back to the caller which is 238 levels (well maybe 10) down from the Interpreter's call to the operating system request to service the UI event. Well see the problem I'm already buried in the Interpreter, but need to go back. Now fortunately others have had this *same* issue. http://bugs.squeak.org/view.php?id=6669 I note the Smalltalk code has been integrated into VMMaker many months/ years ago, but the virtualMachine.c/h has not been updated. I further note it works just like advertised. So now when the UI thread enters the SqueakProxy objective-c instance I just do if (isCarbonVM) interpreterProxy->callbackEnter(&callbackid); The simplistic viewpoint is that this call lurches the interpeter() awake (well and lots of other stuff). The smalltalk code runs, and then invokes a primitive to do the interpreterProxy->callbackLeave(callbackid) which longjmps me back to the original point of the callbackEnter() so I continue the flow of finishing up servicing the windowShouldClose: And everyone is happy. Well assuming this stuff actually works, and there isn't some pending callbackEnter/callbackLeave VM changes that have never flowed into the mix, and where how does the Alien support collide, or not collide with all this trickery. Anyway it seems Esteban might get his windowShouldClose: tomorrow. Certainly he can be the first beta tester. -- = = = ======================================================================== John M. McIntosh <[hidden email]> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com = = = ======================================================================== |
Free forum by Nabble | Edit this page |