mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-02 15:17:31 -04:00
unix: fix event port panic after close
Fixes golang/go#54363 Change-Id: I38813aefaf58ef91605e0a6e3e6622c8a39d6a8d Reviewed-on: https://go-review.googlesource.com/c/sys/+/422338 Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
committed by
Gopher Robot
parent
7ac13a9a92
commit
27713097b9
@@ -177,3 +177,60 @@ func TestEventPortDissociateAlreadyGone(t *testing.T) {
|
||||
// The maps should be empty and there should be no pending events
|
||||
port.checkInternals(t, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
// Regression test for spuriously triggering a panic about memory mismanagement
|
||||
// that can be triggered by an event processing thread trying to process an event
|
||||
// after a different thread has already called port.Close().
|
||||
// Implemented as an internal test so that we can just simulate the Close()
|
||||
// because if you call close first in the same thread, things work properly
|
||||
// anyway.
|
||||
func TestEventPortGetAfterClose(t *testing.T) {
|
||||
port, err := NewEventPort()
|
||||
if err != nil {
|
||||
t.Fatalf("NewEventPort failed: %v", err)
|
||||
}
|
||||
// Create, associate, and delete 2 files
|
||||
for i := 0; i < 2; i++ {
|
||||
tmpfile, err := os.CreateTemp("", "eventport")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to create tempfile: %v", err)
|
||||
}
|
||||
path := tmpfile.Name()
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to stat tempfile: %v", err)
|
||||
}
|
||||
err = port.AssociatePath(path, stat, FILE_MODIFIED, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to AssociatePath tempfile: %v", err)
|
||||
}
|
||||
err = os.Remove(path)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to Remove tempfile: %v", err)
|
||||
}
|
||||
}
|
||||
n, err := port.Pending()
|
||||
if err != nil {
|
||||
t.Errorf("Pending failed: %v", err)
|
||||
}
|
||||
if n != 2 {
|
||||
t.Errorf("expected 2 pending events, got %d", n)
|
||||
}
|
||||
// Simulate a close from a different thread
|
||||
port.fds = nil
|
||||
port.paths = nil
|
||||
port.cookies = nil
|
||||
// Ensure that we get back reasonable errors rather than panic
|
||||
_, err = port.GetOne(nil)
|
||||
if err == nil || err.Error() != "this EventPort is already closed" {
|
||||
t.Errorf("didn't receive expected error of 'this EventPort is already closed'; got: %v", err)
|
||||
}
|
||||
events := make([]PortEvent, 2)
|
||||
n, err = port.Get(events, 1, nil)
|
||||
if n != 0 {
|
||||
t.Errorf("expected to get back 0 events, got %d", n)
|
||||
}
|
||||
if err == nil || err.Error() != "this EventPort is already closed" {
|
||||
t.Errorf("didn't receive expected error of 'this EventPort is already closed'; got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user