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

Fix various issues around close/1 and stream realiasing #2818

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

adri326
Copy link
Contributor

@adri326 adri326 commented Feb 6, 2025

Fixes #2806, namely the following issues I spotted around close/1 and '$set_stream_options' (which can currently be accessed through open(stream(S), _, _, NewOptions)); in order:

  • 2fe7b55: current_output(S), close(S). would partially close user_output if it was previously set to a stream other than Stdout
  • 949d316: open(stream(S), ..., [alias(new_alias)]) would leave the stream_aliases map unsynchronized with the new option, causing issues when close(S) was called
  • 7f2ce57: open(stream(S), ..., [alias(user_output)]), close(S) would override user_output and partially close it, making write(user_output, hello) fail unexpectedly
  • d8213e2: set_output(S), write(user_output, hello) would not write hello into S

To fix these issues and prevent similar one from appearing, I have encapsulated accesses to machine.indices.stream and machine.indices.stream_aliases behind a few methods and made direct accesses illegal in 0cf46d3 (the biggest commit of the bunch).

The only remaining pain point is that options_mut() can be used to break the relationship between stream.options().get_alias() and machine.indices.stream_aliases. There's no easy way to enforce this statically other than changing the API for constructing new streams. I chose to lessen the complexity of this PR and instead leave a warning on the affected methods.

I took care to address each issue in a different commit.

These two fields are able to hold `Stream` instances, which predicates like `close/1`
expect to be managed properly for their correctness. To ensure that this is the case,
I have removed direct accesses to those two fields, so that they can be properly managed
in one place.
Before this change, the following set of queries would behave incorrectly:

```
?- open("/tmp/out.log", write, S), set_output(S).
   prints(""), write("/tmp/out.log", "S = stream(...)").
?- write(user_output, hello).
   prints("hello"), unexpected.
   prints(""), write("/tmp/out.log", "hello"). % Expected, but not found.
```

Now, `set_output/1` and `set_input/1` properly bind the `user_output` and
`user_input` aliases, making the queries above behave as expected.
@adri326 adri326 changed the title Fix various issues around stream realiasing Fix various issues around close/1 and stream realiasing Feb 6, 2025
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.

close/1 improperly handles user_input and user_output (and other stream weirdness)
1 participant