21
21
-module (test_gen_server ).
22
22
23
23
-export ([test /0 ]).
24
- -export ([init /1 , handle_call /3 , handle_cast /2 , handle_info /2 , terminate /2 ]).
24
+ -export ([init /1 , handle_continue / 2 , handle_call /3 , handle_cast /2 , handle_info /2 , terminate /2 ]).
25
25
26
26
-record (state , {
27
27
num_casts = 0 ,
@@ -36,6 +36,7 @@ test() ->
36
36
ok = test_cast (),
37
37
ok = test_info (),
38
38
ok = test_start_link (),
39
+ ok = test_continue (),
39
40
ok = test_init_exception (),
40
41
ok = test_late_reply (),
41
42
ok = test_concurrent_clients (),
@@ -77,6 +78,50 @@ test_start_link() ->
77
78
true = erlang :process_flag (trap_exit , false ),
78
79
ok .
79
80
81
+ test_continue () ->
82
+ {ok , Pid } = gen_server :start_link (? MODULE , {continue , self ()}, []),
83
+ [{Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
84
+
85
+ gen_server :call (Pid , {continue_reply , self ()}),
86
+ [{Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
87
+
88
+ gen_server :call (Pid , {continue_noreply , self ()}),
89
+ [{Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
90
+
91
+ gen_server :cast (Pid , {continue_noreply , self ()}),
92
+ [{Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
93
+
94
+ Pid ! {continue_noreply , self ()},
95
+ [{Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
96
+
97
+ Pid ! {continue_continue , self ()},
98
+ [{Pid , before_continue }, {Pid , continue }, {Pid , after_continue }] = read_replies (Pid ),
99
+
100
+ Ref = monitor (process , Pid ),
101
+ Pid ! continue_stop ,
102
+ verify_down_reason (Ref , Pid , normal ).
103
+
104
+ read_replies (Pid ) ->
105
+ receive
106
+ {Pid , ack } -> read_replies ()
107
+ after 1000 ->
108
+ error
109
+ end .
110
+
111
+ read_replies () ->
112
+ receive
113
+ Msg -> [Msg | read_replies ()]
114
+ after 0 -> []
115
+ end .
116
+
117
+ verify_down_reason (MRef , Server , Reason ) ->
118
+ receive
119
+ {'DOWN' , MRef , process , Server , Reason } ->
120
+ ok
121
+ after 5000 ->
122
+ error
123
+ end .
124
+
80
125
test_cast () ->
81
126
{ok , Pid } = gen_server :start (? MODULE , [], []),
82
127
@@ -353,11 +398,35 @@ test_stop_noproc() ->
353
398
354
399
init (throwme ) ->
355
400
throw (throwme );
401
+ init ({continue , Pid }) ->
402
+ io :format (" init(continue) -> ~p~n " , [Pid ]),
403
+ self () ! {after_continue , Pid },
404
+ {ok , [], {continue , {message , Pid }}};
356
405
init (_ ) ->
357
406
{ok , # state {}}.
358
407
408
+ handle_continue ({continue , Pid }, State ) ->
409
+ Pid ! {self (), before_continue },
410
+ self () ! {after_continue , Pid },
411
+ {noreply , State , {continue , {message , Pid }}};
412
+ handle_continue (stop , State ) ->
413
+ {stop , normal , State };
414
+ handle_continue ({message , Pid }, State ) ->
415
+ Pid ! {self (), continue },
416
+ {noreply , State };
417
+ handle_continue ({message , Pid , From }, State ) ->
418
+ Pid ! {self (), continue },
419
+ gen_server :reply (From , ok ),
420
+ {noreply , State }.
421
+
359
422
handle_call (ping , _From , State ) ->
360
423
{reply , pong , State };
424
+ handle_call ({continue_reply , Pid }, _From , State ) ->
425
+ self () ! {after_continue , Pid },
426
+ {reply , ok , State , {continue , {message , Pid }}};
427
+ handle_call ({continue_noreply , Pid }, From , State ) ->
428
+ self () ! {after_continue , Pid },
429
+ {noreply , State , {continue , {message , Pid , From }}};
361
430
handle_call (reply_ping , From , State ) ->
362
431
gen_server :reply (From , pong ),
363
432
{noreply , State };
@@ -392,6 +461,9 @@ handle_call(crash_me, _From, State) ->
392
461
handle_call (crash_in_terminate , _From , State ) ->
393
462
{reply , ok , State # state {crash_in_terminate = true }}.
394
463
464
+ handle_cast ({continue_noreply , Pid }, State ) ->
465
+ self () ! {after_continue , Pid },
466
+ {noreply , State , {continue , {message , Pid }}};
395
467
handle_cast (crash , _State ) ->
396
468
throw (test_crash );
397
469
handle_cast (ping , # state {num_casts = NumCasts } = State ) ->
@@ -403,6 +475,17 @@ handle_cast({set_info_timeout, Timeout}, State) ->
403
475
handle_cast (_Request , State ) ->
404
476
{noreply , State }.
405
477
478
+ handle_info ({after_continue , Pid }, State ) ->
479
+ Pid ! {self (), after_continue },
480
+ Pid ! {self (), ack },
481
+ {noreply , State };
482
+ handle_info (continue_stop , State ) ->
483
+ {noreply , State , {continue , stop }};
484
+ handle_info ({continue_noreply , Pid }, State ) ->
485
+ self () ! {after_continue , Pid },
486
+ {noreply , State , {continue , {message , Pid }}};
487
+ handle_info ({continue_continue , Pid }, State ) ->
488
+ {noreply , State , {continue , {continue , Pid }}};
406
489
handle_info (ping , # state {num_infos = NumInfos , info_timeout = InfoTimeout } = State ) ->
407
490
NewState = State # state {num_infos = NumInfos + 1 },
408
491
case InfoTimeout of
0 commit comments