aboutsummaryrefslogtreecommitdiff
path: root/src/database/sql/sql_test.go
diff options
context:
space:
mode:
authorDaniel Theophanes <kardianos@gmail.com>2017-04-28 14:24:31 -0700
committerDaniel Theophanes <kardianos@gmail.com>2017-04-28 22:55:26 +0000
commit2133d63fa81777315981fbf961338218832e5099 (patch)
tree0b080a9184ba215660db4a9ffa526dc8cf776279 /src/database/sql/sql_test.go
parent295d160e017edce29b3dccfa7bb7a9e5d9434b26 (diff)
downloadgo-2133d63fa81777315981fbf961338218832e5099.tar.xz
database/sql: ensure releaseConn is defined before a possible close
When running a Query on Stmt a dependency is added to the stmt and rows. To do that it needs a reference to Rows, so the releaseConn function is defined after the definition. However the rows.initContextClose was set to run before the releaseConn was set on rows, setting up a situation where the connection could be canceled before the releaseConn was set and resulting in a segfault. Fixes #20160 Change-Id: I5592e7db2cf653dfc48d42cbc2b03ca20501b1a0 Reviewed-on: https://go-review.googlesource.com/42139 Run-TryBot: Daniel Theophanes <kardianos@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/database/sql/sql_test.go')
-rw-r--r--src/database/sql/sql_test.go40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
index 5ea965fb28..2fd81f29a5 100644
--- a/src/database/sql/sql_test.go
+++ b/src/database/sql/sql_test.go
@@ -3044,6 +3044,46 @@ func TestIssue18429(t *testing.T) {
wg.Wait()
}
+// TestIssue20160 attempts to test a short context life on a stmt Query.
+func TestIssue20160(t *testing.T) {
+ db := newTestDB(t, "people")
+ defer closeDB(t, db)
+
+ ctx := context.Background()
+ sem := make(chan bool, 20)
+ var wg sync.WaitGroup
+
+ const milliWait = 30
+
+ stmt, err := db.PrepareContext(ctx, "SELECT|people|name|")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer stmt.Close()
+
+ for i := 0; i < 100; i++ {
+ sem <- true
+ wg.Add(1)
+ go func() {
+ defer func() {
+ <-sem
+ wg.Done()
+ }()
+ ctx, cancel := context.WithTimeout(ctx, time.Duration(rand.Intn(milliWait))*time.Millisecond)
+ defer cancel()
+
+ // This is expected to give a cancel error most, but not all the time.
+ // Test failure will happen with a panic or other race condition being
+ // reported.
+ rows, _ := stmt.QueryContext(ctx)
+ if rows != nil {
+ rows.Close()
+ }
+ }()
+ }
+ wg.Wait()
+}
+
// TestIssue18719 closes the context right before use. The sql.driverConn
// will nil out the ci on close in a lock, but if another process uses it right after
// it will panic with on the nil ref.