Re: select() in dynamically-linked code
Martin Gasbichler <[email protected]>
| Newsgroups | gmane.lisp.scheme.scsh |
|---|---|
| Message-ID | <[email protected]> |
Michel Schinz <[email protected]> writes: > Hello, > > 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 function. 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, 2002 available from <http://www-pu.informatik.uni-tuebingen.de/users/gasbichl/publications/index.html> for some discussion on this issue (which is typical for a user-level thread system). 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. -- Martin