Windows DLL with C++ interface

Denys Duchier duchier at ps.uni-sb.de
Wed Feb 12 10:27:29 CET 2003


jvdvorst at iae.nl (Jan van der Vorst) writes:

> E.g. a function like the following 'hello' will print the warning in
> the emulator-window but will not show a message box. Oz will just
> stop responding.

You have to keep in mind that Oz threads are not system threads.  The
Oz thread support is very lightweight and implemented by the Oz
engine.  All Oz threads are run by the Oz emulator (i.e. the main
_system_ thread of the process).  They are scheduled fairly (when
running pure Oz code) and preemptively.  Thus, all primitives (native
extensions - as your example below) are invoked synchronously on the
main system thread.

> OZ_BI_define(BIhello,0,0)
> {
>         OZ_warning("Creating message box");
>         MessageBox(NULL, "Hello World!", "Hello Jan!", MB_OK);
>         return OZ_ENTAILED;
> } OZ_BI_end

Whenever this primitive is invoked, the entire system will block until
MessageBox returns.

A primitive should preferably not block (else the entire system
blocks) and should return promptly (else the fairness of scheduling is
adversely impacted).

You simply cannot do it as you tried above.  A general solution
involves providing support for system threads.  I have an on-going
project for this, but I simply have had too much other work to make
much progress on it at all.

The obvious idea for a possibly blocking service is to start an
additional system thread, and allow Oz threads (executing on the
emulator system thread) to send requests to that service.

<emulator system thread>  --requests-->  <service system thread>

VERY IMPORTANT: the <service system thread> MUST NOT hold any
references to Oz values (i.e. living on the Oz heap).  One reason is
that this would completely break when a garbage collection occurs.

Unfortunately, sometimes we'd like to get replies back to Oz.  We
cannot use the typical trick of handing a variable to the service and
letting it bind that variable to the reply because (1) as mentioned
above, the service cannot hold any refs to an Oz value, i.e. not to a
variable, (2) a fortiori, it absolutely must not attempt to bind a
variable (or even create a value on the heap to bind it to).  There is
no option but for all this to occur synchronously on the <emulator
system thread>.

All that the <service system thread> can do is queue the replies in a
reply queue and you must contrive a way for the emulator to check that
queue.  There are 2 obvious options: (1) polling, which is not very
nice, (2) somehow explicitely causing an event in the emulator that
will wake up a suspended thread which will then check the queue.  For
the latter, without additional support from the emulator itself (not
available at the moment), you basically have only one way, namely IO:
i.e. have an Oz thread block on IO. when the <service system thread>
enqueues a reply, it can write a byte on that IO stream.  Shortly
thereafter the Oz thread will wake up and can check the reply queue
(which you better protect with a mutex).

Yes, this sucks and will suck only slightly less with additional
support in the emulator.

Cheers,

-- 
Dr. Denys Duchier
Équipe Calligramme
LORIA, Nancy, FRANCE
-
Please send submissions to users at mozart-oz.org
and administriva mail to users-request at mozart-oz.org.
The Mozart Oz web site is at http://www.mozart-oz.org/.
Please send bug reports to bugs at mozart-oz.org.





More information about the mozart-users mailing list