
On 13/03/2010 22:54, Donn Cave wrote:
Quoth Simon Marlow
, ... So it was surprising when this turned out to be incompatible with the -threaded link option. With that option, I get one callback from a non-main thread, and then that native thread will die, shortly after return from the callback.
You'll need to elaborate a little. When you say you "get one callback from a non-main thread", are you saying that the external C++ code makes a call to a Haskell function?
Yes.
Was it Haskell that called C++ in the first place?
Yes.
What do you mean by a non-main thread? Why is the native thread dieing?
By main thread I mean the original thread spawned by the process creation; the thread spawned by the foreign library window code is a non-main thread. I wish I knew why it dies! Without -threaded, I do get tracebacks from the various and sundry stack corruptions and whatever eventually occurs, but with -threaded, death is quick and silent. And, as far as I can tell, it happens in the foreign library code, not while executing a callback. The same type of callback works fine in the main thread (this API uses the same dispatch loop for the application itself, but it just doesn't spawn a new thread in that case.)
It is expected that you'll get problems without -threaded, because -threaded is needed to handle callbacks from different OS threads. Are you using threads in your Haskell code at all? Do you know how bound threads work in GHC? (I'm only asking because if you're already familiar with this stuff I don't need to explain it :-). I suggest the next thing to do is to find out why the thread is dieing.
You said a UI window gets its own thread - who creates that thread? If the app has more than one window, does each window get a different thread?
Yes, each window runs its own thread. If it helps to have names, the BWindow::Show function spawns the thread, and from there its event loop calls virtual functions in the BWindow and BView classes that the application may override. That's where control goes back to the Haskell application, via foreign "wrapper" functions.
But of course all that is perhaps unnecessary elaboration. The key points are, threads of foreign origin, with callbacks to Haskell foreign "wrapper" functions. Does the wrapper rts_lock() account for everything, or do threads need some initial setup I need to account for?
Nope, as long as the RTS is initialised properly via hs_init() you should be able to make callbacks from any OS thread. Cheers, Simon