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

panic: close of closed channel #121

Open
kke opened this issue Jul 28, 2021 · 3 comments · May be fixed by #122
Open

panic: close of closed channel #121

kke opened this issue Jul 28, 2021 · 3 comments · May be fixed by #122

Comments

@kke
Copy link
Contributor

kke commented Jul 28, 2021

goroutine 1709 [running]:
github.com/masterzen/winrm.(*Command).Close(0xc00017e700, 0x0, 0x0)
    github.com/masterzen/[email protected]/command.go:114

https://github.com/masterzen/winrm/blob/master/command.go#L111-L115

	select { // close cancel channel if it's still open
	case <-c.cancel:
	default:
		close(c.cancel)
	}
@kke kke linked a pull request Jul 29, 2021 that will close this issue
@kke
Copy link
Contributor Author

kke commented Jul 29, 2021

@masterzen I made a PR that attempts to fix this via sync.Once in #122 - PTAL.

@masterzen
Copy link
Owner

@kke , do you by any chance have client code or a unit test that could reproduce the issue so that I understand how the double close was triggered?

@kke
Copy link
Contributor Author

kke commented Jul 29, 2021

It goes something like this:

	shell, err := c.client.CreateShell()
	if err != nil {
		return err
	}
	defer shell.Close()

	command, err := shell.Execute(cmd)
	if err != nil {
		return err
	}

	var wg sync.WaitGroup

	wg.Add(1)
	go func() {
		defer wg.Done()
		defer command.Stdin.Close()
		command.Stdin.Write([]byte(stdin))
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		defer command.Stdout.Close()
		outputScanner := bufio.NewScanner(command.Stdout)

		for outputScanner.Scan() {
			fmt.Print(outputScanner.Text()+"\n", "")
		}
	}()

	command.Wait()
	wg.Wait()
	command.Close()

It seems to occur in situations where a command is periodically retried.

Anyway, to me it seems the select statement does not always do what it is supposed to. If it manages to read from the cancel channel, the channel remains open. Also I'm not sure if it's guaranteed to always hit that branch first.

Also I don't know if it should even proceed to send the signal to endpoint if the channel is already closed.

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 a pull request may close this issue.

2 participants