Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VM-threads prevent unblocked I/O #2873

Closed
vicuna opened this issue Jun 27, 2004 · 3 comments
Closed

VM-threads prevent unblocked I/O #2873

vicuna opened this issue Jun 27, 2004 · 3 comments

Comments

@vicuna
Copy link

vicuna commented Jun 27, 2004

Original bug ID: 2873
Reporter: administrator
Status: closed
Resolution: won't fix
Priority: normal
Severity: feature
Category: ~DO NOT USE (was: OCaml general)

Bug description

Hi,

VM-threads obviously do not allow me to use unblocked I/O on sockets.

If I set a timeout on some socket, e.g.

setsockopt_float sock SO_SNDTIMEO 3.141

then the timeout ("Sys_blocked_io" or Unix_error EAGAIN/EWOULDBLOCK)
will be caught in the VM-thread specific pervasives.ml or unix.ml,
and then the operation blocks (or loops).

Unfortunately, since POSIX-threads, which do not have a problem with this,
currently seem to cause problems on Linux 2.6, this is quite annoying.
What else could I do without resorting to signficantly more complex I/O
without threads?

The functions "wait_timed_read" and "wait_timed_write" are not
particularly helpful, because they only tell me whether some characters
can be written, which does not imply that all of them can - in which
case the I/O-operation blocks again.

Best regards,
Markus

--
Markus Mottl http://www.oefai.at/~markus markus@oefai.at

@vicuna
Copy link
Author

vicuna commented Jun 28, 2004

Comment author: administrator

Dear Markus,

VM-threads obviously do not allow me to use unblocked I/O on sockets.
[...]

You're indeed looking for trouble. VM threads use non-blocking I/O
for internal purposes, and this isn't going to change.

May I suggest you think again at what you're trying to achieve?
Generally speaking, systems programs are either written with multiple
threads and blocking I/O, or with non-blocking I/O and a single
thread. Non-blocking I/O in a multithreaded context is combining the
difficulties of both approaches....

Unfortunately, since POSIX-threads, which do not have a problem with this,
currently seem to cause problems on Linux 2.6, this is quite annoying.

I'm working on this issue, which is really not as bad as Raffalli
makes it sound on the list.

Best wishes,

  • Xavier Leroy

@vicuna
Copy link
Author

vicuna commented Jun 28, 2004

Comment author: administrator

VM threads cannot (reasonably) be made compatible with non-blocking I/O

@vicuna vicuna closed this as completed Jun 28, 2004
@vicuna
Copy link
Author

vicuna commented Jun 28, 2004

Comment author: administrator

Dear Xavier,

On Mon, 28 Jun 2004, Xavier Leroy wrote:

You're indeed looking for trouble. VM threads use non-blocking I/O
for internal purposes, and this isn't going to change.

May I suggest you think again at what you're trying to achieve?
Generally speaking, systems programs are either written with multiple
threads and blocking I/O, or with non-blocking I/O and a single
thread. Non-blocking I/O in a multithreaded context is combining the
difficulties of both approaches....

Yes, that's the normal case. In my case I don't need non-blocking I/O
for performance reasons, but for aborting transactions in a distributed
filesystem. Each thread handles a connection request, which is by far
the most elegant way to do things. But to prevent faulty applications
from holding connections for an indefinite amount of time without
performing I/O, I need to specify timeouts after which the server will
close the connection again. Otherwise it won't be possible to perform
destructive operations, because of locks associated with a transaction.
This works all very nicely with POSIX-threads, which, however, currently
cause other problems.

I think it should not be too difficult to handle non-blocking I/O with
VM-threads: each such channel could contain fields that store the time
of the last read/write operation. When the runtime detects that a
channel with timeouts hasn't seen I/O within the given period of time,
it could raise a Sys_blocked_io-exception in the corresponding thread.
It could use a different exception internally for handling threads with
blocked I/O.

I have written a short example of a workaround now - just in case somebody
else needs a solution for this some time. It is definitely a bit heavy,
but seems to work:


open Unix

let watchdog time v =
let evc = Event.new_channel () in
let thread () =
Thread.delay time;
Event.sync (Event.send evc v) in
Thread.create thread (), Event.receive evc

let timed_sync time v ev =
let wtid, wev = watchdog time v in
wtid, Event.sync (Event.choose [ev; wev])

let uses_posix_threads =
let mtx = Mutex.create () in
let f () = Mutex.lock mtx in
let tid = Thread.create f () in
try Thread.kill tid; false
with _ -> Mutex.unlock mtx; true

let unblocked_really_input ic buf ofs len =
if uses_posix_threads then really_input ic buf ofs len
else (
let maybe_timeout =
try Some (getsockopt_float (descr_of_in_channel ic) SO_RCVTIMEO)
with _ -> None in
match maybe_timeout with
| Some timeout when timeout <> 0.0 ->
let evc = Event.new_channel () in
let handle () =
really_input ic buf ofs len;
Event.sync (Event.send evc true) in
let tid = Thread.create handle () in
let wtid, success = timed_sync timeout false (Event.receive evc) in
if success then try Thread.kill wtid with _ -> ()
else (
(try Thread.kill tid with _ -> ());
raise Sys_blocked_io)
| _ -> really_input ic buf ofs len)

It's a pity that standard I/O-functions don't support this... :-(

I'm working on this issue, which is really not as bad as Raffalli
makes it sound on the list.

Sounds good!

Best regards,
Markus

--
Markus Mottl http://www.oefai.at/~markus markus@oefai.at

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant