mirror of
https://github.com/asciinema/asciinema.git
synced 2025-12-16 19:58:03 +01:00
Workaround race condition when child process exits
There's race condition happening (so far observed only on CentOS) at the moment when child process exits. Sometimes reading from master fd blocks forever even when the process is already reaped and there's no more data to be read. Not sure what's the reason, it may be some CentOS specific bug. Using timeout does the job and seems to be relatively harmless.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"code.google.com/p/go.crypto/ssh/terminal"
|
||||
|
||||
@@ -53,7 +54,7 @@ func (p *Pty) Record(command string, stdoutCopy io.Writer) error {
|
||||
}()
|
||||
defer close(signals)
|
||||
|
||||
// put stdin into raw mode (if it's a tty)
|
||||
// put stdin in raw mode (if it's a tty)
|
||||
fd := int(p.Stdin.Fd())
|
||||
if terminal.IsTerminal(fd) {
|
||||
oldState, err := terminal.MakeRaw(fd)
|
||||
@@ -71,7 +72,23 @@ func (p *Pty) Record(command string, stdoutCopy io.Writer) error {
|
||||
|
||||
// copy pty master -> p.stdout & stdoutCopy
|
||||
stdout := io.MultiWriter(p.Stdout, stdoutCopy)
|
||||
stdoutWaitChan := make(chan struct{})
|
||||
go func() {
|
||||
io.Copy(stdout, master)
|
||||
stdoutWaitChan <- struct{}{}
|
||||
}()
|
||||
|
||||
// wait for the process to exit and reap it
|
||||
cmd.Wait()
|
||||
|
||||
// wait for master -> stdout copying to finish
|
||||
//
|
||||
// sometimes after process exits reading from master blocks forever (race condition?)
|
||||
// we're using timeout here to overcome this problem
|
||||
select {
|
||||
case <-stdoutWaitChan:
|
||||
case <-time.After(200 * time.Millisecond):
|
||||
}
|
||||
|
||||
// stop stdin -> master copying
|
||||
stop()
|
||||
|
||||
Reference in New Issue
Block a user