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

A better interface for select #4090

Closed
vicuna opened this issue Aug 24, 2006 · 2 comments
Closed

A better interface for select #4090

vicuna opened this issue Aug 24, 2006 · 2 comments

Comments

@vicuna
Copy link

vicuna commented Aug 24, 2006

Original bug ID: 4090
Reporter: n8gray
Status: acknowledged (set by @damiendoligez on 2006-08-29T14:33:23Z)
Resolution: open
Priority: normal
Severity: feature
Version: 3.09.2
Category: otherlibs
Tags: patch

Bug description

The existing interface for Unix.select is adequate, but it's often not so nice to work with. Here's an example using the current API:

(* You have a data structure with some file descriptors and auxilliary data )
let foo = [(fd1, "hello"); (fd2, "world"); (fd3, "baz")] in
(
Now you need a list of file descriptors )
let fds = List.map fst foo in
(
Feed them to select )
let _, outs, _ = Unix.select [] fds [] (-1.0) in
(
Now do something with each active descriptor *)
List.iter (fun fd ->
let data = List.assoc fd foo in
do_something fd data) outs

The problem is that when you select on a file descriptor there's usually some context you care about that's associated with that descriptor -- e.g. some data to write or a buffer to read into. This means that you need to create an otherwise useless list of file descriptors (fds in the example) before calling select, and after you find out that file descriptor x is ready you have to search through some auxilliary data structure to find the data associated with x. This means extra work for the programmer and the program both before and after the select call.

I would like to propose a new, additional interface for the select call, which I'm calling select2. You can probably guess the idea by looking at the type.

val select2:
(Unix.file_descr * 'a) list ->
(Unix.file_descr * 'b) list ->
(Unix.file_descr * 'c) list ->
float ->
(Unix.file_descr * 'a) list *
(Unix.file_descr * 'b) list *
(Unix.file_descr * 'c) list

To be clear, the idea is that each file descriptor can have a value associated with it, and these values are returned along with the file descriptors on output. This interface is much nicer to work with and even slightly more efficient, since there's no need to search for the contextual data after the call. The example becomes:

(* You have a data structure with some file descriptors and auxilliary data )
let foo = [(fd1, "hello"); (fd2, "world"); (fd3, "baz")] in
(
Feed it to select2 )
let _, outs, _ = Unix.select2 [] foo [] (-1.0) in
(
Now do something with the data *)
List.iter (fun (fd, data) -> do_something fd data) outs

I've attached a patch against OCaml 3.09.2 that implements select2 for Unix platforms. The Win32 implementation would be trivial. The vmthreads implementation would probably best be done as an OCaml wrapper of regular select. I will be happy to do this work if the patch is accepted, but first I thought I would see if the OCaml team is interested in the idea.

File attachments

@mshinwell
Copy link
Contributor

I don't think this is worth pursuing. As far as I know, there are very few users nowadays who would directly call select, preferring monadic concurrency libraries instead.

@gasche
Copy link
Member

gasche commented Mar 16, 2019

For the record, I don't really agree that it's not worth improving our select API -- there are a fair number of cases where people reimplement their own concurrency layers on top of the stdlib barebones (eg. Dune, Coq, etc.) instead of using Lwt/Async, so a modest and non-invasive improvement could be nice. The proposal in this issue seems sensible and non-invasive (I would call it select_assoc instead of the ugly select2), and I would be willing to review a PR implementing this. (But the issue itself can be closed as long as no one is actively working on this.)

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

3 participants