11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci// Checks that setInterval timers keep running even when they're
31cb0ef41Sopenharmony_ci// unrefed within their callback.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciconst common = require('../common');
61cb0ef41Sopenharmony_ciconst net = require('net');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_cilet counter1 = 0;
91cb0ef41Sopenharmony_cilet counter2 = 0;
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci// Test1 checks that clearInterval works as expected for a timer
121cb0ef41Sopenharmony_ci// unrefed within its callback: it removes the timer and its callback
131cb0ef41Sopenharmony_ci// is not called anymore. Note that the only reason why this test is
141cb0ef41Sopenharmony_ci// robust is that:
151cb0ef41Sopenharmony_ci// 1. the repeated timer it creates has a delay of 1ms
161cb0ef41Sopenharmony_ci// 2. when this test is completed, another test starts that creates a
171cb0ef41Sopenharmony_ci//    new repeated timer with the same delay (1ms)
181cb0ef41Sopenharmony_ci// 3. because of the way timers are implemented in libuv, if two
191cb0ef41Sopenharmony_ci//    repeated timers A and B are created in that order with the same
201cb0ef41Sopenharmony_ci//    delay, it is guaranteed that the first occurrence of timer A
211cb0ef41Sopenharmony_ci//    will fire before the first occurrence of timer B
221cb0ef41Sopenharmony_ci// 4. as a result, when the timer created by Test2 fired 11 times, if
231cb0ef41Sopenharmony_ci//    the timer created by Test1 hadn't been removed by clearInterval,
241cb0ef41Sopenharmony_ci//    it would have fired 11 more times, and the assertion in the
251cb0ef41Sopenharmony_ci//    process'exit event handler would fail.
261cb0ef41Sopenharmony_cifunction Test1() {
271cb0ef41Sopenharmony_ci  // Server only for maintaining event loop
281cb0ef41Sopenharmony_ci  const server = net.createServer().listen(0);
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  const timer1 = setInterval(common.mustCall(() => {
311cb0ef41Sopenharmony_ci    timer1.unref();
321cb0ef41Sopenharmony_ci    if (counter1++ === 3) {
331cb0ef41Sopenharmony_ci      clearInterval(timer1);
341cb0ef41Sopenharmony_ci      server.close(() => {
351cb0ef41Sopenharmony_ci        Test2();
361cb0ef41Sopenharmony_ci      });
371cb0ef41Sopenharmony_ci    }
381cb0ef41Sopenharmony_ci  }, 4), 1);
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci// Test2 checks setInterval continues even if it is unrefed within
431cb0ef41Sopenharmony_ci// timer callback. counter2 continues to be incremented more than 11
441cb0ef41Sopenharmony_ci// until server close completed.
451cb0ef41Sopenharmony_cifunction Test2() {
461cb0ef41Sopenharmony_ci  // Server only for maintaining event loop
471cb0ef41Sopenharmony_ci  const server = net.createServer().listen(0);
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  const timer2 = setInterval(() => {
501cb0ef41Sopenharmony_ci    timer2.unref();
511cb0ef41Sopenharmony_ci    if (counter2++ === 3)
521cb0ef41Sopenharmony_ci      server.close();
531cb0ef41Sopenharmony_ci  }, 1);
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ciTest1();
57