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

termbox.PollEvent wait forever after reading from Stdin from tmux command #88

Open
vheon opened this issue Jun 9, 2015 · 25 comments
Open
Labels

Comments

@vheon
Copy link

vheon commented Jun 9, 2015

I don't know if this is a problem with termbox-go per se.

I have this simple program https://gist.github.com/vheon/74388c0dd68e21413eb8. If I ran this as

printf "foo\nbar\nqux" | ./simplebox

everything works fine, if I press <C-n> or <C-p> the selected line change.

if I have multiple sessions inside tmux and run

tmux list-sessions | ./simplebox

everything freeze and the only way to exit is to killall "simplebox" from another shell. I checked and the program is blocked on PollEvent.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Works on my machine. Also your program expects "Esc" key which is available only in termbox.InputEsc mode. Add that line after termbox init:

termbox.SetInputMode(termbox.InputEsc)

What's the shortest way to reproduce it with tmux? You're saying it hands with multiple tmux sessions, does it hang with just one session? Is there some connection to number of sessions in general? I've noticed that the program hangs if stdin is empty, i.e. if you run it without sending stdin. What tmux list-sessions returns without redirecting it to simplebox?

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Oh, sorry. InputEsc is the default one. No need to add that line.

@vheon
Copy link
Author

vheon commented Jun 9, 2015

On my machine this is the output of tmux list-sessions is

jedihttp: 4 windows (created Thu May 21 11:29:37 2015) [158x43]
misc: 1 windows (created Thu May 21 11:29:38 2015) [158x43]
picker: 4 windows (created Thu May 21 11:29:38 2015) [158x43] (attached)

and it freeze. I tried with just one session and the same thing happened.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

What about random output? Like ls ~ | ./simplebox. Does it freeze too?

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Also what tmux -V says? Mine:

[nsf @ ~]$ tmux -V
tmux 2.0

@vheon
Copy link
Author

vheon commented Jun 9, 2015

I'm on 1.9a.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Could you try 2.0 then? Maybe it will just work, who knows.

@vheon
Copy link
Author

vheon commented Jun 9, 2015

Nope. It works the first time I launch it, and from the second time, nothing.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Can you tell me exactly how to reproduce it? This is what I do:

tmux
ls ~ | ./simplebox
# all works fine here
<C-b> <d> # detaching from session
tmux attach
ls ~ | ./simplebox
# all still works just fine

I've deleted my tmux config file just in case. I don't see any hangs.

@vheon
Copy link
Author

vheon commented Jun 9, 2015

That is what I did:

tmux new-session -s test1
<C-b>d
tmux new-session -s test2
ls ~ | ./simplebox
# all works fine
tmux list-session | ./simplebox
# it hangs

@vheon
Copy link
Author

vheon commented Jun 9, 2015

I tried without my tmux.conf and same results.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

It's really weird. I tried to do the same what you suggested. Works fine.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Well, I remember there were some issues with termbox closing stdin or something like that. Try go get -u github.com/nsf/termbox-go, and then rebuild your app, maybe termbox version is out of date.

@vheon
Copy link
Author

vheon commented Jun 9, 2015

If it is not much trouble could you try as before but:

tmux new-session -s test1
<C-b>d
tmux new-session -s test2
ls ~ | ./simplebox
# all works fine
tmux list-session | ./simplebox
# if it works try again
tmux list-session | ./simplebox

Sometimes it works a first time and then hangs.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Tried 10 times or so. Works.

@nsf nsf added the Bug label Jun 9, 2015
@nsf
Copy link
Owner

nsf commented Jun 9, 2015

It sucks that I can't reproduce it. I guess the issue will keep hanging there.

Oh and I haven't asked what's your OS? Because I'm running it on linux and if it's a MacOSX, it changes everything. :D

@vheon
Copy link
Author

vheon commented Jun 9, 2015

yes, I'm on Mac

@vheon
Copy link
Author

vheon commented Jun 9, 2015

I should've told you sooner, sorry.

@nsf
Copy link
Owner

nsf commented Jun 9, 2015

Yeah, could be the mac issue, because I don't have a mac and therefore it's the least tested OS when it comes to termbox-go. Yeah, it's mostly POSIX and the implementation is similar, but there could be slight differences in syscalls behaviour. Like when SIGIO is sent and what Read returns. Sadly I don't have a mac, so at this moment I can't help you. Maybe I'll eventually try to get hackintosh running in a virtualbox or something.

@vheon
Copy link
Author

vheon commented Jun 9, 2015

If you need some testing I could do it, just tell me what to do :) Anyway thanks for your time 👍

@syohex
Copy link

syohex commented Jul 17, 2015

There is a same issue(peco/peco#255).
We can reproduce this issue without go(also termbox-go). peco/peco#255 (comment)

So I also think this is MacOSX kernel issue.

@nsf
Copy link
Owner

nsf commented Jul 17, 2015

Well, I'm sure any modern OS has some proper way of doing async I/O. That's what termbox requires. The reason for this is a need to be able to do graceful shutdown. We can't just block a goroutine waiting for input, because if library user decides to quit, you can't unblock a read syscall. That's how I do it on windows (btw, haven't tested enough, not sure if it even works correctly):

https://github.com/nsf/termbox-go/blob/master/termbox_windows.go#L743-L813

Basically a similar solution to POSIX's select. Initially termbox was designed with select in mind. There was a unix pipe delivering SIGWINCH which is an object you can wait for using select call. So, similarly we can make a pipe which is used to interrupt a blocking select call. But the question is - is it the best way to do it? Is it the best way to do it on linux? on darwin?

I'm pretty sure it's all possible on all OSes. All OSes have some kind of a semaphore implementation (that is a waiting queue for threads and a way to wake them up) and some kind of a multi-object management system, be it select or WaitForMultipleObjects. Sadly I'm completely unfamiliar with darwin OS.

@syohex
Copy link

syohex commented Jul 17, 2015

But the question is - is it the best way to do it? Is it the best way to do it on linux? on darwin?

I have no idea yet.

@nsf
Copy link
Owner

nsf commented Jul 17, 2015

And I have no time to figure that out. When I have, I will.

@gdamore
Copy link

gdamore commented Sep 22, 2015

I believe there is an excellent chance that my fix in PR #99 will solve this. After that change is pulled, termbox-go no longer depends on or uses either SIGIO or async/IO. Please give it a whirl.

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

No branches or pull requests

4 participants