Skip to content

Commit 7a6777d

Browse files
authored
expression: make sleep function response to the kill statement (pingcap#10959)
1 parent 08d8219 commit 7a6777d

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

expression/builtin_miscellaneous.go

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"math"
2020
"net"
2121
"strings"
22+
"sync/atomic"
2223
"time"
2324

2425
"github.com/google/uuid"
@@ -131,12 +132,25 @@ func (b *builtinSleepSig) evalInt(row chunk.Row) (int64, bool, error) {
131132
if val > math.MaxFloat64/float64(time.Second.Nanoseconds()) {
132133
return 0, false, errIncorrectArgs.GenWithStackByArgs("sleep")
133134
}
135+
134136
dur := time.Duration(val * float64(time.Second.Nanoseconds()))
135-
select {
136-
case <-time.After(dur):
137-
// TODO: Handle Ctrl-C is pressed in `mysql` client.
138-
// return 1 when SLEEP() is KILLed
137+
ticker := time.NewTicker(10 * time.Millisecond)
138+
defer ticker.Stop()
139+
start := time.Now()
140+
finish := false
141+
for !finish {
142+
select {
143+
case now := <-ticker.C:
144+
if now.Sub(start) > dur {
145+
finish = true
146+
}
147+
default:
148+
if atomic.CompareAndSwapUint32(&sessVars.Killed, 1, 0) {
149+
return 1, false, nil
150+
}
151+
}
139152
}
153+
140154
return 0, false, nil
141155
}
142156

expression/evaluator_test.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package expression
1515

1616
import (
17+
"sync/atomic"
1718
"testing"
1819
"time"
1920

@@ -176,23 +177,21 @@ func (s *testEvaluatorSuite) TestSleep(c *C) {
176177
sub := time.Since(start)
177178
c.Assert(sub.Nanoseconds(), GreaterEqual, int64(0.5*1e9))
178179

179-
// quit when context canceled.
180-
// TODO: recover it.
181-
// d[0].SetFloat64(2)
182-
// f, err = fc.getFunction(ctx, s.datumsToConstants(d))
183-
// c.Assert(err, IsNil)
184-
// start = time.Now()
185-
// go func() {
186-
// time.Sleep(1 * time.Second)
187-
// ctx.Cancel()
188-
// }()
189-
// ret, isNull, err = f.evalInt(chunk.Row{})
190-
// sub = time.Since(start)
191-
// c.Assert(err, IsNil)
192-
// c.Assert(isNull, IsFalse)
193-
// c.Assert(ret, Equals, int64(1))
194-
// c.Assert(sub.Nanoseconds(), LessEqual, int64(2*1e9))
195-
// c.Assert(sub.Nanoseconds(), GreaterEqual, int64(1*1e9))
180+
d[0].SetFloat64(3)
181+
f, err = fc.getFunction(ctx, s.datumsToConstants(d))
182+
c.Assert(err, IsNil)
183+
start = time.Now()
184+
go func() {
185+
time.Sleep(1 * time.Second)
186+
atomic.CompareAndSwapUint32(&ctx.GetSessionVars().Killed, 0, 1)
187+
}()
188+
ret, isNull, err = f.evalInt(chunk.Row{})
189+
sub = time.Since(start)
190+
c.Assert(err, IsNil)
191+
c.Assert(isNull, IsFalse)
192+
c.Assert(ret, Equals, int64(1))
193+
c.Assert(sub.Nanoseconds(), LessEqual, int64(2*1e9))
194+
c.Assert(sub.Nanoseconds(), GreaterEqual, int64(1*1e9))
196195
}
197196

198197
func (s *testEvaluatorSuite) TestBinopComparison(c *C) {

0 commit comments

Comments
 (0)