Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at

Browse thread
Win32 Services & O'Caml
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2007-01-25 (11:52)
From: David Allsopp <dra-news@m...>
Subject: Win32 Services & O'Caml
Yesterday I completed a module that allows construction of Win32 Services in
O'Caml. Non-threaded O'Caml apps seem to be working just fine but I've hit a
brick wall with multi-threaded applications.

Win32 Services are started by the SCM and so, with the code I've set-up, we
get the following O'Caml sequence of execution: O'Caml code invokes a C-stub
which calls Win32 StartServiceCtrlDispatcher, Win32 then invokes the
C-function ServiceMain which executes an O'Caml callback for the O'Caml
version of ServiceMain. ServiceMain (in C) also registers a C handler
function which can also make callbacks to another function in O'Caml. 

This model is working perfectly with single-threaded apps. However, as soon
as I enable threading, I get problems (principally associated with I/O).
Experiments so far have shown that the only way I can get close to anything
is to have the O'Caml ServiceMain spawn a thread that runs the service ---
however, in order to get this working I have to keep cycling the
pause/continue controls on the service for the thread to get a little bit of
time. Once the O'Caml main function returns, the C ServiceMain waits on an
Event --- even putting caml_enter_blocking_section around it doesn't seem to
allow other O'Caml threads to execute.

I'm aware of Xavier's comments in ... is that the
problem in this situation? As far as I can see the main thread is still an
O'Caml thread. Interestingly, the I/O functions that cause problems are all
ones which themselves use caml_enter_blocking_section - I can, for example,
use Unix.unlink in the O'Caml ServiceMain without any problems.

Interestingly, with all these problems on the "main" thread, the handler
function and its associated callbacks are always working fine (so I get a
service that does nothing because the main thread seems to have crashed but
that I can still control the service and bring it down successfully [albeit
with sporadic GPFs])

The code is at ... the Makefile contains the
command to build it. Microsoft's SC utility is the easiest way of installing
the service by running sc create Testing binPath= {full path to exe}
You can then either control the service using Services.msc or via the sc
start start/stop/pause/continue commands.

Any comments much appreciated --- my workaround for now is to use a
single-threaded service that forks a multi-threaded process and controls
that via stdin/stdout but I'd be interested to know whether there's
something blindingly wrong in the C file that would prevent the need for
forking a separate process or whether it just can't be done in O'Caml (at
the moment!).