caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Win32 Services & O'Caml
@ 2007-01-25 11:53 David Allsopp
  2007-01-25 14:53 ` [Caml-list] " skaller
  0 siblings, 1 reply; 4+ messages in thread
From: David Allsopp @ 2007-01-25 11:53 UTC (permalink / raw)
  To: OCaml List

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 http://tinyurl.com/2suroy ... 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 http://tinyurl.com/2wvd2x ... 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!).

TIA,


David


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] Win32 Services & O'Caml
  2007-01-25 11:53 Win32 Services & O'Caml David Allsopp
@ 2007-01-25 14:53 ` skaller
  2007-01-25 15:35   ` David Allsopp
  0 siblings, 1 reply; 4+ messages in thread
From: skaller @ 2007-01-25 14:53 UTC (permalink / raw)
  To: David Allsopp; +Cc: OCaml List

On Thu, 2007-01-25 at 11:53 +0000, David Allsopp wrote:
> 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.

I'm sure Xavier will fix my misconceptions here, but I suspect
the requirement is that Ocaml threading library must start the
threads so it can arrange for state to be properly shared,
in particular the heap. If other code starts the thread,
when it makes a callback into Ocaml, Ocaml can't find
the shared state because it was never established.

Any system (not just Ocaml) is going to have this problem
if it uses an environment not strictly conforming to that
provided natively. EG .. how do you share a young heap
pointer held in an AMD64 machine register across threads ..
when the OS carefully makes sure registers are not shared?? :)


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [Caml-list] Win32 Services & O'Caml
  2007-01-25 14:53 ` [Caml-list] " skaller
@ 2007-01-25 15:35   ` David Allsopp
  0 siblings, 0 replies; 4+ messages in thread
From: David Allsopp @ 2007-01-25 15:35 UTC (permalink / raw)
  To: 'OCaml List'

I agree --- although, unless my understanding of how Win32 does it is
completely wrong, I don't think there are any non-O'Caml threads in use.
StartServiceCtrlDispatcher is invoked by an O'Caml created thread and it
doesn't return until the very end of the service (i.e. when the service has
been totally shutdown and the process is terminating).

However, what's not clear to me is whether there are implications of an
O'Caml function calling a C-function which calls back to another C-function
which subsequently calls back to O'Caml!!


David

-----Original Message-----
From: skaller [mailto:skaller@users.sourceforge.net] 
Sent: 25 January 2007 14:54
To: David Allsopp
Cc: OCaml List
Subject: Re: [Caml-list] Win32 Services & O'Caml

On Thu, 2007-01-25 at 11:53 +0000, David Allsopp wrote:
> 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.

I'm sure Xavier will fix my misconceptions here, but I suspect
the requirement is that Ocaml threading library must start the
threads so it can arrange for state to be properly shared,
in particular the heap. If other code starts the thread,
when it makes a callback into Ocaml, Ocaml can't find
the shared state because it was never established.

Any system (not just Ocaml) is going to have this problem
if it uses an environment not strictly conforming to that
provided natively. EG .. how do you share a young heap
pointer held in an AMD64 machine register across threads ..
when the OS carefully makes sure registers are not shared?? :)


-- 
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net


^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: Win32 Services & O'Caml
@ 2007-01-25 12:03 David Allsopp
  0 siblings, 0 replies; 4+ messages in thread
From: David Allsopp @ 2007-01-25 12:03 UTC (permalink / raw)
  To: OCaml List

> The code is at http://tinyurl.com/2wvd2x ... 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.

Doh: should probably mention that I'm using OCaml 3.09.3 built from source
using Cygwin/MinGW (i.e gcc) on Windows XP SP2!


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-01-25 15:34 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-25 11:53 Win32 Services & O'Caml David Allsopp
2007-01-25 14:53 ` [Caml-list] " skaller
2007-01-25 15:35   ` David Allsopp
2007-01-25 12:03 David Allsopp

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).