Michel Schinz <Michel.Schinz@epfl.ch> writes:
> I'm writing an interface to libcurl (http://curl.haxx.se/) for scsh,
> and I've run into a problem I cannot solve.
> It goes as follows: curl has a function (curl_easy_perform) which
> performs the HTTP/FTP/whatever transfer, and the first thing this
> function does is connect with the remote host. It does it by first
> calling connect(), and if it gets an EINPROGRESS error, it does a
> select() to wait for the connection to be established.
> If curl_easy_perform is called by a stand-alone C program, everything
> goes well. If it's called by the scsh VM (through a "call-external"
> call), then the call to select() fails with a EINTR error. This aborts
> the whole connection, which is of course pretty bad.
> Looking at the scsh doc, I read (in section 3.9) this:
> The thread system needs the timer interrupt for its own purpose, ...
> and I guess (without fully understanding the problem) that the reason
> curl's select() gets an EINTR is that it receives some signal used by
> the thread system. Am I right?
Yes, the timer interrupt is send every 200ms or so.
> If yes, is there a solution, or are all libraries which use select()
> (or any signal stuff, I presume) fundamentally incompatible with scsh?
You could block signals using sigprocmask() before calling the C
However one fundamental problem remains: If you call a C function that
takes a very long time to execute, the whole scshvm is blocked for
that time. This means that no other threads are executed during your C
call, i.e. your library cannot be used in a multi-threaded Scsh
program. See our paper
Processes vs. User-Level Threads in Scsh
Martin Gasbichler, Michael Sperber
Proceedings of the Third ACM SIGPLAN 2002 Scheme Workshop, Pittsburgh, PA,
for some discussion on this issue (which is typical for a user-level
Of course this doesn't provide an immediate solution for your concrete
problem as you are faced with a C function you cannot change. I don't
know libcurl but maybe it provides access to the file descriptor that
it passes to select() or the relevant code can be recoded in Scheme
easily. In both cases you can call scsh's SELECT-PORT-CHANNELS
function to do wait for the file descriptor to become ready without
blocking other threads.
We're also thinking about providing some way to start operating system
threads to handle C function calls that may block forever but we
didn't implement anything yet.