[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Question on Multithreading from C API



I am a bit confused by the MzScheme's Threading functions
provided in the C API.

Imagine the case of a web server with an embedded Scheme
interpreter.  One of its jobs is to evalute S-expressions
as they are requested by various socket connections.

Currently, there is a perpetual native thread that runs
in a loop waiting for evaluation requests.  When such
a request is received, it then hands the s-expression
over to MzScheme (using scheme_eval) waits for the
response (or exception) and returns the result.

This works fine, but obviously creates a single-threaded
bottleneck in the code.  What I want to do is evaluate
each individual s-expression in its own thread.

Looking at the "Inside PLT MzScheme" manual, I see how to
create a new thread to evaluate the s-expression, but I
don't see a way to join with an MzScheme thread to get
it's response.

For example, let's say I do this:

... get a request ...

Scheme_Object* rval = scheme_thread( thunk, env);

... return the rval ...

I imagine this is just going to block until the evaulation
is done.  This is no better than the single eval loop because
no new requests can be processed until this evaluation completes. 

On the other hand, if "rval" is just a value that indicates
that the thread started successfully, how can you find the
value of the thunk being evaluated?

What I would like to do is have the request thread looping
and periodically checking for new requests (which it does now),
then hand them off to MzScheme to evaluate in their own
threads, then periodically check on each thread to see if there
was a result.

Is this possible using the C API?

At this point, I'm thinking the best I can do is to force the
indvidual evaluations to notify the waiting threads (i.e., the
clients waiting on each HTTP request) that their result is
ready.

This might be done through something like this:

1.  A client hits the HTTP connection, which creates a request
    structure around the s-expression to be evaluted.
2.  The request structure gets stored in a request queue, sets
    a "request ready" condition, and then the thread goes to 
    sleep (waiting on a "done" condition").
3.  The perpetual MzScheme server thread picks up the request,
    removes it from the request queue, puts it in a "pending"
    queue, and wraps the s-expression in a thunk (similar to
    the one outlined in "Inside PLT MzScheme" to catch
    exceptions.  This thunk contains a pointer to the condition
    variable the HTTP client is blocked on.  The thunk evaluates
    the s-expression, stores the result in its structure in the
    "pending queue" and then fires the "done" condition before
    returning (and terminating).
4.  The blocked thread wakes up, retrieves the structure from the
    "pending" queue and does whatever with the result.

Is there an easier way to achieve this result?

Thanks,

-Brent