[squeak-dev] mar visits callbackEnter/callbackLeave

John M McIntosh johnmci at smalltalkconsulting.com
Fri Mar 6 05:43:15 UTC 2009


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 <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
= 
= 
= 
========================================================================






More information about the Squeak-dev mailing list