package miou
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=d9ae52113d923f2425a1375c594f4accf61171780af1ef211dbbba38ff51dacf
sha512=f114d1d4b1ff0c7bbe74adbb2fa65a7343064a14ea252b8ae5dbd98c209b3c1d56f2e360422ea8e5cd2656a6f50cb10ae262b0c4e6681724803dd6e8eb1d1653
doc/miou.unix/Miou_unix/index.html
Module Miou_unix
Source
The Unix layer of Miou.
This module offers a re-implementation of the I/O according to Miou's model. This module is essentially concerned with reading and writing Unix.file_descr
from sockets, pipes, fifos, terminals (and pseudo-terminals) and probably devices. For all these types of file_descr
, reading/writing can block (waiting for bytes or waiting for the system's internal buffer to be free).
This is not generally the case for files and folders where read
/write
does not block. So, as far as files/folders are concerned, there is no point in using the suspend/resume mechanisms offered by Miou. These mechanisms (and the use of Unix.select
) could actually degrade performance. It is therefore advisable to use the Unix
module directly rather than Miou_unix
for files/folders.
It should be noted, however, that reading/writing files can take a long time. So, in a cooperative context (with Miou.async
), it may be worthwhile to increase the availability of other tasks to run with Miou.yield
- so associate a Miou.yield
with these operations. However, in the case of parallelization (Miou.call
), it is not necessary to cooperate with the other tasks as they run in parallel. In this sense, and depending on the design of your application, these operations should, or should not, be associated with a Miou.yield
.
How to spawn & handle processes with Miou_unix?
The Miou_unix
module essentially only provides suspension points for reading and writing blocking file_descr
(such as sockets). But users would probably like another type of suspension: namely, suspension until a launched program (via Unix.create_process
) has finished.
The underlying mechanism provided by the system to signal the end of a program's execution is not related to file_descr
but to signals. Here is an example of how to launch and wait for the end of a program using signals and the Miou.Computation
module.
let pid =
Unix.create_process "sleep" [| "sleep"; "1" |] Unix.stdin Unix.stdout
Unix.stderr
in
let c = Miou.Computation.create () in
let handler _sigchld =
match Unix.waitpid [ WNOHANG ] pid with
| 0, _ -> ()
| pid', status when pid' = pid ->
ignore (Miou.sys_signal Sys.sigchld Sys.Signal_default);
assert (Miou.Computation.try_return c status)
in
ignore (Miou.sys_signal Sys.sigchld (Sys.Signal_handle handler));
match Miou.Computation.await_exn c with
| Unix.WEXITED _ -> ()
| Unix.WSIGNALED _ -> ()
| Unix.WSTOPPED _ -> ()
Here are some explanations of the code above.
- There is no reference to the
Miou_unix
module (although there are references toUnix
). As we said,Miou_unix
only managestype:file-descr
. In the code above, it is more about signal management. - First, a program is launched with
Unix.create_process
and a handler is installed on theSIGCHLD
signal. Please refer to theMiou.sys_signal
documentation. - This handler then fills in a
Miou.Computation.t
valuec
which, at the same time, is suspended further on withMiou.Computation.await_exn
.
The suspension performed by Miou.Computation.await_exn
can cooperate with the execution of other Miou tasks. In this way, the termination of the program is no longer blocking and you can, at the same time, execute tasks cooperatively and/or in parallel.
The handler function (which completes our Miou.Computation.t
) is always executed by dom0
(as specified in the Miou.sys_signal
documentation).
Finally, it is entirely possible to extend this code in order to associate our Miou.Computation.t
with the PIDs of several launched programs (in a Hashtbl
, for example) in order to define a more generic handler capable of unblocking several suspension points.
Why not integrate such a mechanism into Miou_unix
?
This code currently has a global side effect: it installs a handler to manage the SIGCHLD
signal. Miou
and Miou_unix
are libraries that should only slightly modify the global state of your program.
Therefore, it is your responsibility to install such a handler in order to enforce the explicit nature of what your program does — and to prevent Miou
and Miou_unix
from doing things implicitly just because you want to depend on these libraries.
Type of file-descriptors.
of_file_descr ?non_blocking ?owner fd
creates a new file_descr
. Depending on non_blocking
(defaults to true
), we set the given fd
to non-blocking mode or not.
to_file_descr fd
returns the real Unix.file_descr
.
tcpv4 ()
allocates a new IPv4 socket.
tcpv6 ()
allocates a new IPv6 socket.
val bind_and_listen :
?backlog:int ->
?reuseaddr:bool ->
?reuseport:bool ->
file_descr ->
Unix.sockaddr ->
unit
bind_and_listen fd sockaddr
binds the given socket to the given sockaddr
and set up the given fd
for receiving connection requests. backlog
is the maximal number of pending requests. The optional argument reuseaddr
(defaults to true
) sets the REUSEADDR
socket option on the given fd
. The optional argument reuseport
(defaults to true
sets the REUSEPORT
socket option on the given fd
.
accept ?cloexec fd
is a Miou friendly Unix.accept
which returns file descriptors in non-blocking mode.
connect fd sockaddr
is a Miou friendly Unix.connect
. The function accepts only file_descr
s in non-blocking mode.
read fd buf ~off ~len
reads up to len
bytes (defaults to Bytes.length buf - off
from the given file-descriptor fd
, storing them in byte sequence buf
, starting at position off
in buf
(defaults to 0
). It returns the actual number of characters read, between 0 and len
(inclusive).
really_read fd buf ~off ~len
reads len
bytes (defaults to Bytes.length buf - off
) from the given file-descriptor fd
, storing them in byte sequence buf
, starting at position off
in buf
(defaults to 0
). If len = 0
, really_read
does nothing.
write fd str ~off ~len
writes len
bytes (defaults to String.length str - off
) from byte sequence buf
, starting at offset off
(defaults to 0
), to the given file-descriptor fd
.
close fd
closes properly the given fd
.
sleep v
suspends the current task and sleeps v
seconds.
/