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

Add ev/to-file for synchronous resource operations #1533

Merged
merged 7 commits into from
Dec 18, 2024

Conversation

pyrmont
Copy link
Contributor

@pyrmont pyrmont commented Dec 15, 2024

This PR adds ev/to-file as a way to allow synchronous operations with stream-based resources (e.g. sockets).

Background

Janet supports non-blocking IO operations via the ev module. While this is desirable in many cases, there are situations where a user wants to ensure that an operation is synchronous. Janet does not currently offer a mechanism to do this with stream-based resources (e.g. sockets).

As discussed in #1531, one way to address this is is to offer a function that would create a core/file object based on the core/stream object. The core/file object could then be used with the synchronous operations in the file module.

Implementation

The src/core/ev.c file is modified to add an ev/to-file function. The function takes a stream object and attempts to return a file object. This can then be used in the same way as other file objects:

(with [conn (net/connect host port)]
  (def f (ev/to-file conn))
  (file/write ffoo”)
  (file/write fbar”)
  (file/flush f))

Limitations

I wasn’t able to get this working on MinGW. Based on some cursory reading, I think this might be a limitation in how MinGW handles the use of Windows sockets via file descriptors. As a result, calling this function in a MinGW environment will raise an error.

@sogaiu
Copy link
Contributor

sogaiu commented Dec 15, 2024

I think carol needs to be added to the test suite.

@sogaiu
Copy link
Contributor

sogaiu commented Dec 15, 2024

I got a tip that may be dup is needed because of this:

Another reason for duplicating a file descriptor is using it with fdopen. fclose closes the file descriptor that was passed to fdopen, so if you don't want the original file descriptor to be closed, you have to duplicate it with dup first.

Does that seem right?

@bakpakin
Copy link
Member

I don't think dup is strictly needed, but it is probably the best way to ensure that we don't accidentally close a file descriptor used by another object. It also gets a bit confusing when we throw marshaling and sharing streams between threads in the loop, so it's probably the most practical thing to do.

@bakpakin
Copy link
Member

bakpakin commented Dec 15, 2024

I wasn’t able to get this working on MinGW. Based on some cursory reading, I think this might be a limitation in how MinGW handles the use of Windows sockets via file descriptors. As a result, calling this function in a MinGW environment will raise an error.

That is strange to me, since the windows path should be used on windows and mingw

src/core/ev.c Outdated Show resolved Hide resolved
@pyrmont
Copy link
Contributor Author

pyrmont commented Dec 15, 2024

I wasn’t able to get this working on MinGW. Based on some cursory reading, I think this might be a limitation in how MinGW handles the use of Windows sockets via file descriptors. As a result, calling this function in a MinGW environment will raise an error.

That is strange to me, since the windows path should be used on windows and mingw

I don't have a MinGW environment that I can test to explore further. You can see the errors that were occurring for various approaches in my Actions history. A sample error:

Starting suite test/suite-ev.janet...
error: could not flush file
  in file/flush [src/core/io.c] on line 284
  in thunk [test/suite-ev.janet] (tail call) on line 425, column 1

and if I disable buffering:

Starting suite test/suite-ev.janet...
error: error writing to file
  in file/write [src/core/io.c] on line 251
  in thunk [test/suite-ev.janet] (tail call) on line 424, column 1

I've removed the special casing in e94e8dc and, while the test suite includes a check to avoid testing in MinGW, the current commit can be experimented with in MinGW.

@bakpakin
Copy link
Member

Thanks for the work here, @pyrmont! Looks pretty solid to me, and we can investigate the mingw issue later, as I also don't have a mingw setup handy for testing right now.

@bakpakin bakpakin merged commit b16cf17 into janet-lang:master Dec 18, 2024
13 checks passed
@pyrmont pyrmont deleted the feature.file-socket branch December 18, 2024 20:40
@pyrmont
Copy link
Contributor Author

pyrmont commented Dec 18, 2024

Great! Thanks for merging it in! I’m looking forward to using it in my project with the next Janet release :D

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

Successfully merging this pull request may close these issues.

3 participants