diff options
author | Erlang/OTP <otp@erlang.org> | 2021-06-24 13:30:23 +0200 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2021-06-24 13:30:23 +0200 |
commit | 57accaf9a8f031a0923c94741de04d7c2b96e035 (patch) | |
tree | 5a9e1157952d96fe9513e26b729f90b34d2f17eb /erts/emulator | |
parent | 95fb606dd9f87f3911034d74f86a236ca96af42e (diff) | |
parent | 7760cca94081a9d7d0607967277ea77c5234bc91 (diff) | |
download | erlang-57accaf9a8f031a0923c94741de04d7c2b96e035.tar.gz |
Merge branch 'rickard/cancel_timer_no_info_fix/OTP-17472' into maint-24
* rickard/cancel_timer_no_info_fix/OTP-17472:
Fix erlang:cancel_timer(_, [{info, false}])
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/erl_hl_timer.c | 15 | ||||
-rw-r--r-- | erts/emulator/test/timer_bif_SUITE.erl | 58 |
2 files changed, 66 insertions, 7 deletions
diff --git a/erts/emulator/beam/erl_hl_timer.c b/erts/emulator/beam/erl_hl_timer.c index aef095d7d9..860e98b471 100644 --- a/erts/emulator/beam/erl_hl_timer.c +++ b/erts/emulator/beam/erl_hl_timer.c @@ -1903,7 +1903,7 @@ send_async_info(Process *proc, ErtsProcLocks initial_locks, static ERTS_INLINE Eterm send_sync_info(Process *proc, ErtsProcLocks initial_locks, - Uint32 *refn, int cancel, Sint64 time_left) + Uint32 *refn, int info, int cancel, Sint64 time_left) { ErtsProcLocks locks = initial_locks; ErtsMessage *mp; @@ -1923,7 +1923,9 @@ send_sync_info(Process *proc, ErtsProcLocks initial_locks, ref = make_internal_ref(hp); hp += ERTS_REF_THING_SIZE; - if (time_left < 0) + if (!info) + res = am_ok; + else if (time_left < 0) res = am_false; else if (time_left <= (Sint64) MAX_SMALL) res = make_small((Sint) time_left); @@ -1974,7 +1976,7 @@ access_sched_local_btm(Process *c_p, Eterm pid, time_left = access_btm(tmr, (Uint32) esdp->no, esdp, cancel); - if (!info) + if (async && !info) return am_ok; if (c_p) { @@ -1987,12 +1989,15 @@ access_sched_local_btm(Process *c_p, Eterm pid, } if (!async) { - if (c_p) + if (c_p) { + if (!info) + return am_ok; return return_info(c_p, time_left); + } if (proc) return send_sync_info(proc, proc_locks, - rrefn, cancel, time_left); + rrefn, info, cancel, time_left); } else if (proc) { Eterm ref; diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl index 5316793fed..6e5b672646 100644 --- a/erts/emulator/test/timer_bif_SUITE.erl +++ b/erts/emulator/test/timer_bif_SUITE.erl @@ -23,7 +23,7 @@ -export([all/0, suite/0, init_per_suite/1, end_per_suite/1, init_per_testcase/2,end_per_testcase/2]). -export([start_timer_1/1, send_after_1/1, send_after_2/1, send_after_3/1, - cancel_timer_1/1, + cancel_timer_1/1, cancel_timer_sync/1, start_timer_big/1, send_after_big/1, start_timer_e/1, send_after_e/1, cancel_timer_e/1, read_timer_trivial/1, read_timer/1, read_timer_async/1, @@ -63,7 +63,7 @@ suite() -> all() -> [start_timer_1, send_after_1, send_after_2, - cancel_timer_1, start_timer_e, send_after_e, + cancel_timer_1, cancel_timer_sync, start_timer_e, send_after_e, cancel_timer_e, start_timer_big, send_after_big, read_timer_trivial, read_timer, read_timer_async, cleanup, evil_timers, registered_process, @@ -165,6 +165,60 @@ cancel_timer_1(Config) when is_list(Config) -> ok. +cancel_timer_sync(Config) when is_list(Config) -> + cancel_timer_sync_test(true), + cancel_timer_sync_test(false). + +cancel_timer_sync_test(SameSched) -> + process_flag(scheduler, 1), + + R1 = erlang:send_after(1000, self(), cling), + R2 = erlang:send_after(1000, self(), clong), + R3 = erlang:send_after(1000, self(), clang), + TsSet = erlang:monotonic_time(), + R4 = erlang:send_after(0, self(), pling), + R5 = erlang:send_after(0, self(), plong), + R6 = erlang:send_after(0, self(), plang), + R7 = make_ref(), + R8 = make_ref(), + R9 = make_ref(), + + case SameSched of + true -> + %% Cancel from the same scheduler... + ok; + false-> + %% Cancel from different scheduler... + process_flag(scheduler, erlang:system_info(schedulers_online)) + end, + + C1 = erlang:cancel_timer(R1), + true = is_integer(C1), + C2 = erlang:cancel_timer(R2, [{info, true}]), + true = is_integer(C2), + ok = erlang:cancel_timer(R3, [{info, false}]), + + receive pling -> ok end, + receive plong -> ok end, + receive plang -> ok end, + + false = erlang:cancel_timer(R4), + false = erlang:cancel_timer(R5, [{info, true}]), + ok = erlang:cancel_timer(R6, [{info, false}]), + + false = erlang:cancel_timer(R7), + false = erlang:cancel_timer(R8, [{info, true}]), + ok = erlang:cancel_timer(R9, [{info, false}]), + + Wait = 1500 - erlang:convert_time_unit(erlang:monotonic_time() - TsSet, + native, millisecond), + + receive TMO when TMO == cling; TMO == clang; TMO == clong -> + ct:fail({unexpected_timeout, TMO}) + after Wait -> + ok + end. + %% Error cases for start_timer/3 start_timer_e(Config) when is_list(Config) -> {'EXIT', _} = (catch erlang:start_timer(-4, self(), hej)), |