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

fixing hanging stdin read in the switchboard #46

Merged
merged 4 commits into from
Feb 19, 2024
Merged

fixing hanging stdin read in the switchboard #46

merged 4 commits into from
Feb 19, 2024

Conversation

miki725
Copy link
Contributor

@miki725 miki725 commented Feb 15, 2024

the issue we are trying to solve is:

echo foo | bar --stdin

If bar is reading its input from stdin, stdin needs to close
so that bar can proceed. If stdin is not closed, bar is hang
waiting for the stdin.

In libc if stdin is closed we get a read() output of 0
after a read which returned some data:

read("foo\n") -> 4
read("") -> 0 // as stdin closed

if the stdin is not closed, the second read will hang forever
as it will wait for the stdin to close

What the fix does here is that when it sees a read() returning 0
it passes that indication to all the subscribers to let them know
that the write FD should be closed to mimick what we got on the input
side of the switchboard.

Also it fixes some mixed whitespace as things werent rendering well
in vim.

@miki725 miki725 requested review from drraid and ee7 February 15, 2024 18:06
@miki725 miki725 requested a review from viega as a code owner February 15, 2024 18:06
@miki725 miki725 changed the title passing pty through in runCmdGetEverything fixing hanging stdin read in the switchboard Feb 15, 2024
the issue we are trying to solve is:

```
echo foo | bar --stdin
```

If bar is reading its input from stdin, stdin needs to close
so that bar can proceed. If stdin is not closed, bar is hang
waiting for the stdin.

In libc if stdin is closed we get a `read()` output of 0
after a read which returned some data:

```
read("foo\n") -> 4
read("") -> 0 // as stdin closed
```

if the stdin is not closed, the second read will hang forever
as it will wait for the stdin to close

What the fix does here is that when it sees a read() returning 0
it passes that indication to all the subscribers to let them know
that the write FD should be closed to mimick what we got on the input
side of the switchboard.

Also it fixes some mixed whitespace as things werent rendering well
in vim.
@ee7
Copy link

ee7 commented Feb 16, 2024

Nice work on fixing this.

But can we please:

  • Create a new PR with the whitespace-only changes, and enforce the style in CI
  • Merge that PR
  • Rebase this PR on top

It's straightforward to review this PR without the whitespace changes (well, at least locally; GitHub hides the option somewhat), but a commit should be a single logical unit of change. Somebody who looks at this PR or the merged commit later shouldn't be forced to hide whitespace changes in order to understand the diff.

A PR may be multiple logical units of change, but then it should be multiple commits that are preserved (that is, without squashing) on merging to the main branch.

as such needed to add `close_fd_when_done` to `fd_party_t`
@miki725
Copy link
Contributor Author

miki725 commented Feb 16, 2024

as there is no de-facto autoformatter for C I manually mixed some of the mixed whitespace in C files I had to debug to fix this bug. splitting that out will be much more pain than provide benefit. we can add CI validation for that in the future change. there is more mixed whitespace in the repo

Copy link
Contributor

@viega viega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the work is solid, just not where I think the API change should be made, per my other comment.

The subscription object should track, and the publish needs to consult that before propagating (whereas the typical message gets broadcast to all subscribers).

Possibly it's best to have a separate version of publish for when this situation occurs, to keep it down to a single test per message (and that test is both fine where you have it, and was no net additional cost).

I'm 100% fine if you don't want to make that change, but if not, I'd prefer only addressing this for your current use case, and I can come in and make the change later. Or, you can continue to overachieve, that's fine too :)

@@ -231,31 +232,32 @@ sb_init_party_fd(switchboard_t *ctx, party_t *party, int fd, int perms,
fd_obj->first_msg = NULL;
fd_obj->last_msg = NULL;
fd_obj->subscribers = NULL;
fd_obj->close_fd_when_done = close_when_done;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I'm taking a first scan of the code, I'm confused.

Is this flag going to cause the fd actually closing on its own lead to us PROPAGATING the close? Because:

  1. If so, the name isn't clear.
  2. I don't think this should be done per data source, I think it should be done per SUBSCRIPTION.

As just a real simple example, if I'm multiplexing a shell, and the user's stdin disappears, we established yesterday that I probably don't want to let the child shell know one of the parents is gone. HOWEVER, if that multiplexing is ALSO capturing an input log with a second subscription, I do want to know about that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'd call the flag something like proxy_close at the subscription level, and proxy_stdin_close at the runCmd level?

Really that's the issue, controlling whether to propagate closes for subscriptions (proxy is probably both clearer to more people and more concise?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah right makes sense. Ill adjust. thanks

by configuring each subscriber, whether it should be closed when the
input proxy is closed, will allow for multiplex-type application.
otherwise when the input fd is closed and all subscribers are closed
unilaterally is not necessarily the wanted behavior in all cases
@miki725 miki725 requested a review from viega February 19, 2024 15:45
Copy link
Contributor

@viega viega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done, thanks.

@miki725 miki725 merged commit db04ef1 into dev Feb 19, 2024
1 check passed
@miki725 miki725 deleted the ms/pty branch February 19, 2024 17:04
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