|
69 | 69 |
|
70 | 70 | -type init_result(StateType) :: |
71 | 71 | {ok, State :: StateType} |
72 | | - | {ok, State :: StateType, timeout() | {continue, term()}} |
| 72 | + | {ok, State :: StateType, timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
73 | 73 | | {stop, Reason :: any()}. |
74 | 74 |
|
75 | 75 | -type handle_continue_result(StateType) :: |
76 | 76 | {noreply, NewState :: StateType} |
77 | | - | {noreply, NewState :: StateType, timeout() | {continue, term()}} |
| 77 | + | {noreply, NewState :: StateType, |
| 78 | + timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
78 | 79 | | {stop, Reason :: term(), NewState :: StateType}. |
79 | 80 |
|
80 | 81 | -type handle_call_result(StateType) :: |
81 | 82 | {reply, Reply :: any(), NewState :: StateType} |
82 | | - | {reply, Reply :: any(), NewState :: StateType, timeout() | {continue, term()}} |
| 83 | + | {reply, Reply :: any(), NewState :: StateType, |
| 84 | + timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
83 | 85 | | {noreply, NewState :: StateType} |
84 | | - | {noreply, NewState :: StateType, timeout() | {continue, term()}} |
| 86 | + | {noreply, NewState :: StateType, |
| 87 | + timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
85 | 88 | | {stop, Reason :: any(), Reply :: any(), NewState :: StateType} |
86 | 89 | | {stop, Reason :: any(), NewState :: StateType}. |
87 | 90 |
|
88 | 91 | -type handle_cast_result(StateType) :: |
89 | 92 | {noreply, NewState :: StateType} |
90 | | - | {noreply, NewState :: StateType, timeout() | {continue, term()}} |
| 93 | + | {noreply, NewState :: StateType, |
| 94 | + timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
91 | 95 | | {stop, Reason :: any(), NewState :: StateType}. |
92 | 96 |
|
93 | 97 | -type handle_info(StateType) :: |
94 | 98 | {noreply, NewState :: StateType} |
95 | | - | {noreply, NewState :: StateType, timeout() | {continue, term()}} |
| 99 | + | {noreply, NewState :: StateType, |
| 100 | + timeout() | {timeout, timeout(), Msg :: any()} | {continue, term()}} |
96 | 101 | | {stop, Reason :: any(), NewState :: StateType}. |
97 | 102 |
|
98 | 103 | -callback init(Args :: any()) -> |
|
103 | 108 | handle_call_result(StateType). |
104 | 109 | -callback handle_cast(Request :: any(), State :: StateType) -> |
105 | 110 | handle_cast_result(StateType). |
106 | | --callback handle_info(Info :: timeout() | any(), State :: StateType) -> |
| 111 | +-callback handle_info(Info :: timeout() | {timeout, timeout(), any()} | any(), State :: StateType) -> |
107 | 112 | handle_info(StateType). |
108 | 113 | -callback terminate(Reason :: normal | any(), State :: any()) -> |
109 | 114 | any(). |
@@ -500,11 +505,47 @@ loop(Parent, #state{mod = Mod, mod_state = ModState} = State, {continue, Continu |
500 | 505 | loop(Parent, State#state{mod_state = NewModState}, infinity); |
501 | 506 | {noreply, NewModState, {continue, NewContinue}} -> |
502 | 507 | loop(Parent, State#state{mod_state = NewModState}, {continue, NewContinue}); |
| 508 | + {noreply, NewModState, Timeout} -> |
| 509 | + loop(Parent, State#state{mod_state = NewModState}, Timeout); |
503 | 510 | {stop, Reason, NewModState} -> |
504 | 511 | do_terminate(State, Reason, NewModState) |
505 | 512 | end; |
| 513 | +loop(Parent, #state{mod = Mod, mod_state = ModState} = State, {timeout, Timeout, Info}) -> |
| 514 | + receive |
| 515 | + Msg -> |
| 516 | + handle_msg(Msg, Parent, State) |
| 517 | + after Timeout -> |
| 518 | + case Mod:handle_info(Info, ModState) of |
| 519 | + {noreply, NewModState} -> |
| 520 | + loop(Parent, State#state{mod_state = NewModState}, infinity); |
| 521 | + {noreply, NewModState, NewTimeout} -> |
| 522 | + loop(Parent, State#state{mod_state = NewModState}, NewTimeout); |
| 523 | + {stop, Reason, NewModState} -> |
| 524 | + do_terminate(State, Reason, NewModState); |
| 525 | + _ -> |
| 526 | + do_terminate(State, {error, unexpected_reply}, ModState) |
| 527 | + end |
| 528 | + end; |
506 | 529 | loop(Parent, #state{mod = Mod, mod_state = ModState} = State, Timeout) -> |
507 | 530 | receive |
| 531 | + Msg -> |
| 532 | + handle_msg(Msg, Parent, State) |
| 533 | + after Timeout -> |
| 534 | + case Mod:handle_info(timeout, ModState) of |
| 535 | + {noreply, NewModState} -> |
| 536 | + loop(Parent, State#state{mod_state = NewModState}, infinity); |
| 537 | + {noreply, NewModState, NewTimeout} -> |
| 538 | + loop(Parent, State#state{mod_state = NewModState}, NewTimeout); |
| 539 | + {stop, Reason, NewModState} -> |
| 540 | + do_terminate(State, Reason, NewModState); |
| 541 | + _ -> |
| 542 | + do_terminate(State, {error, unexpected_reply}, ModState) |
| 543 | + end |
| 544 | + end. |
| 545 | + |
| 546 | +%% @private |
| 547 | +handle_msg(Msg, Parent, #state{mod = Mod, mod_state = ModState} = State) -> |
| 548 | + case Msg of |
508 | 549 | {'$gen_call', {_Pid, _Ref} = From, Request} -> |
509 | 550 | case Mod:handle_call(Request, From, ModState) of |
510 | 551 | {reply, Reply, NewModState} -> |
@@ -558,20 +599,8 @@ loop(Parent, #state{mod = Mod, mod_state = ModState} = State, Timeout) -> |
558 | 599 | _ -> |
559 | 600 | do_terminate(State, {error, unexpected_reply}, ModState) |
560 | 601 | end |
561 | | - after Timeout -> |
562 | | - case Mod:handle_info(timeout, ModState) of |
563 | | - {noreply, NewModState} -> |
564 | | - loop(Parent, State#state{mod_state = NewModState}, infinity); |
565 | | - {noreply, NewModState, NewTimeout} -> |
566 | | - loop(Parent, State#state{mod_state = NewModState}, NewTimeout); |
567 | | - {stop, Reason, NewModState} -> |
568 | | - do_terminate(State, Reason, NewModState); |
569 | | - _ -> |
570 | | - do_terminate(State, {error, unexpected_reply}, ModState) |
571 | | - end |
572 | 602 | end. |
573 | 603 |
|
574 | | -%% @private |
575 | 604 | do_terminate(#state{mod = Mod} = _State, Reason, ModState) -> |
576 | 605 | case erlang:function_exported(Mod, terminate, 2) of |
577 | 606 | true -> |
|
0 commit comments