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

Prepare IO::FileDescriptor to be platform agnostic #4500

Closed
bcardiff opened this issue Jun 3, 2017 · 10 comments
Closed

Prepare IO::FileDescriptor to be platform agnostic #4500

bcardiff opened this issue Jun 3, 2017 · 10 comments

Comments

@bcardiff
Copy link
Member

bcardiff commented Jun 3, 2017

Current IO::FileDescriptor depends on C lib posix functions and has some scheduler related calls.
IO::FileDescriptor is used as a base class for File and it is used independently for pipe, process, stdout/err/in.

IO::FileDescriptor could be refactor to be platform agnostic. Probably introducing a Crystal::System::FileHandle struct to replace the current @fd : Int32.

Along the way FileHandle might need to encapsulate calls to Scheduler.

#3582 can help as a guide to see which abstractions are needed to later create a FileHandle for windows.

@RX14
Copy link
Contributor

RX14 commented Jun 3, 2017

I was thinking about this too and had envisaged a slightly different design. I was thinking of an alias Crystal::System::FileHandle = Int32 and then have static Crystal::System::File.read(handle : FileHandle, data : Bytes) : Int32. This call would be a black box which talked to the scheduler, like in your proposal. However your proposal is likely just as optimisable in llvm and is a nicer design.

@RX14
Copy link
Contributor

RX14 commented Jun 3, 2017

cc @txe, he might have some feedback on this.

@ysbaddaden
Copy link
Contributor

STDOUT, STDIN and STDERR should use a different async solution on POSIX (blocking calls with timers to interrupt calls) since O_NONBLOCK has side effects on other programs.

Socket also extends IO::FileDescriptor. It seems WinSock is based on regular sockets (implements sockaddr, getaddrinfo, socket, bind, listen) but seems to use send and recv for writing and reading to/from the socket.

Simply have a Windows (FileHandle) vs POSIX (fd) may not be enough...

@txe
Copy link
Contributor

txe commented Jun 3, 2017

Actually, it's quite unclear what problem this additional abstract layer is going to solve.
IO::FileDescriptor, File, Scheduler are heavily platform depended and use completely different data and api calls and thus already are spitted in windows and posix files. They are already abstract layers and hide their guts.
I even think it would be better to have different types for @handle and @fd in inner calls, so no one will be ever confused in using them in unappropriated functions. Meanwhile, it would be good if they have the same type for users because they should not know about inner mechanics.
Anyway, I understand, you don't want that windows dependence spreads as a plague.

@ysbaddaden
Copy link
Contributor

Basically the system API boils down to 2 methods: read(Bytes) and write(Bytes) from a provided FD, and whatever happens under the hood (scheduler, events) is a platform detail. We shouldn't double ​the maintainer work by duplicating files for 2 methods that could be abstracted.

A problem is that windows doesn't use FD for files, so maybe IO::FileDescriptor doesn't make much sense as an abstract class (maybe an includeable module?).

@RX14
Copy link
Contributor

RX14 commented Jun 3, 2017

@ysbaddaden I think @txe is referring to the other platform-specific methods on IO::FileDescriptor, for example: close_on_exec, fcntl, stat. And there's much more than that on File. I think the solution is to change IO::FileDescriptor to remove these platform-specifics (fcntl and stat, not close_on_exec).

@txe
Copy link
Contributor

txe commented Jun 3, 2017

If speak about File, we have the following hierarchy:
module IO (platform independent) ->
module IO::Buffered (include IO, platform independent) ->
class IO::FileDescriptor (include IO::Buffered, platform depended) ->
class File < IO::FileDescriptor (platform depended)

I thinks, the current IO::FileDescriptor is quite a misnomer, because it is not just basic read/write and an 'IO' over a file descriptor but async IO over some descriptor (can be file, pipe, console IO): it contains platform specific stuff as timeouts, async read/write and dependency from Scheduler. If remove platform specific things from IO::FileDescriptor then IO::FileDescriptor is going to do just nothing. So far, I cannot see what to add\change in IO::FileDescriptor to make it less platform specific or reduce maintenance.
Edit: we can wait a bit, it can be clearer what to do when Process and sockets for windows will be implemented.

@RX14
Copy link
Contributor

RX14 commented Jul 10, 2017

I think the Crystal::System version should implement asynchronous unbuffered IO, and then IO::FileDescriptor should hook that into IO::Buffered. fcntl isn't used in the stdlib outside IO::Buffered and setting it to protected still compiled all_spec. For this reason I don't think creating a Crystal::System version of IO::FileDescriptor is that hard (i'm working on it now).

@RX14
Copy link
Contributor

RX14 commented Jul 10, 2017

Is the edge-triggered IO option actually useful? I'm thinking of removing it just to simplify IO::FileDescriptor.

@straight-shoota
Copy link
Member

This has been implemented in #5333

@asterite asterite closed this as completed Sep 7, 2018
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

6 participants