Browse Source

timers: do not restart the interval after close

Partially revert 776b73b243.

Following code crashes after backported timer leak fixes:

```javascript
var timer = setInterval(function() {
  clearInterval(timer);
}, 10);
timer.unref();
```

Note that this is actually tested in a `test-timers-unref.js`, and is
crashing only with 776b73b243.

Calling `clearInterval` leads to the crashes in case of `.unref()`ed
timers, and might lead to a extra timer spin in case of regular
intervals that was closed during the interval callback. All of these
happens because `.unref()`ed timer has it's own `_handle` and was used
after the `.close()`.

PR-URL: https://github.com/iojs/io.js/pull/1330
Reviewed-by: Trevor Norris <trev.norris@gmail.com>
v1.8.0-commit
Fedor Indutny 10 years ago
parent
commit
d22b2a934a
  1. 5
      lib/timers.js
  2. 10
      src/timer_wrap.cc

5
lib/timers.js

@ -272,6 +272,11 @@ exports.setInterval = function(callback, repeat) {
function wrapper() { function wrapper() {
timer._repeat.call(this); timer._repeat.call(this);
// Timer might be closed - no point in restarting it
if (!timer._repeat)
return;
// If timer is unref'd (or was - it's permanently removed from the list.) // If timer is unref'd (or was - it's permanently removed from the list.)
if (this._handle) { if (this._handle) {
this._handle.start(repeat, 0); this._handle.start(repeat, 0);

10
src/timer_wrap.cc

@ -73,6 +73,8 @@ class TimerWrap : public HandleWrap {
static void Start(const FunctionCallbackInfo<Value>& args) { static void Start(const FunctionCallbackInfo<Value>& args) {
TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder()); TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder());
CHECK(HandleWrap::IsAlive(wrap));
int64_t timeout = args[0]->IntegerValue(); int64_t timeout = args[0]->IntegerValue();
int64_t repeat = args[1]->IntegerValue(); int64_t repeat = args[1]->IntegerValue();
int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat); int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
@ -82,6 +84,8 @@ class TimerWrap : public HandleWrap {
static void Stop(const FunctionCallbackInfo<Value>& args) { static void Stop(const FunctionCallbackInfo<Value>& args) {
TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder()); TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder());
CHECK(HandleWrap::IsAlive(wrap));
int err = uv_timer_stop(&wrap->handle_); int err = uv_timer_stop(&wrap->handle_);
args.GetReturnValue().Set(err); args.GetReturnValue().Set(err);
} }
@ -89,6 +93,8 @@ class TimerWrap : public HandleWrap {
static void Again(const FunctionCallbackInfo<Value>& args) { static void Again(const FunctionCallbackInfo<Value>& args) {
TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder()); TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder());
CHECK(HandleWrap::IsAlive(wrap));
int err = uv_timer_again(&wrap->handle_); int err = uv_timer_again(&wrap->handle_);
args.GetReturnValue().Set(err); args.GetReturnValue().Set(err);
} }
@ -96,6 +102,8 @@ class TimerWrap : public HandleWrap {
static void SetRepeat(const FunctionCallbackInfo<Value>& args) { static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder()); TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder());
CHECK(HandleWrap::IsAlive(wrap));
int64_t repeat = args[0]->IntegerValue(); int64_t repeat = args[0]->IntegerValue();
uv_timer_set_repeat(&wrap->handle_, repeat); uv_timer_set_repeat(&wrap->handle_, repeat);
args.GetReturnValue().Set(0); args.GetReturnValue().Set(0);
@ -104,6 +112,8 @@ class TimerWrap : public HandleWrap {
static void GetRepeat(const FunctionCallbackInfo<Value>& args) { static void GetRepeat(const FunctionCallbackInfo<Value>& args) {
TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder()); TimerWrap* wrap = Unwrap<TimerWrap>(args.Holder());
CHECK(HandleWrap::IsAlive(wrap));
int64_t repeat = uv_timer_get_repeat(&wrap->handle_); int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
if (repeat <= 0xfffffff) if (repeat <= 0xfffffff)
args.GetReturnValue().Set(static_cast<uint32_t>(repeat)); args.GetReturnValue().Set(static_cast<uint32_t>(repeat));

Loading…
Cancel
Save