From 1c3b4f75d6aec9376cbcf6e6726f28a81b65b463 Mon Sep 17 00:00:00 2001 From: Jan Uhlig Date: Tue, 2 Jul 2024 18:22:39 +0200 Subject: [PATCH] Draft: stop_listener in ranch_server --- src/ranch.erl | 38 +------------------------------------- src/ranch_server.erl | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/ranch.erl b/src/ranch.erl index d909afd735..3692f50414 100644 --- a/src/ranch.erl +++ b/src/ranch.erl @@ -193,43 +193,7 @@ start_error(_, Error) -> Error. -spec stop_listener(ref()) -> ok | {error, not_found}. stop_listener(Ref) -> - Parent = self(), - Tag = make_ref(), - {StopperPid, StopperMon} = spawn_monitor(fun() -> Parent ! {Tag, stop_listener1(Ref)} end), - receive - {Tag, Result} -> - demonitor(StopperMon, [flush]), - Result; - {'DOWN', StopperMon, process, StopperPid, Error} -> - {error, Error} - end. - -stop_listener1(Ref) -> - TransportAndOpts = maybe_get_transport_and_opts(Ref), - case supervisor:terminate_child(ranch_sup, {ranch_listener_sup, Ref}) of - ok -> - _ = supervisor:delete_child(ranch_sup, {ranch_listener_sup, Ref}), - ranch_server:cleanup_listener_opts(Ref), - stop_listener2(TransportAndOpts); - {error, _} = Error -> - Error - end. - -stop_listener2({Transport, TransOpts}) -> - Transport:cleanup(TransOpts), - ok; -stop_listener2(undefined) -> - ok. - -maybe_get_transport_and_opts(Ref) -> - try - [_, Transport, _, _, _] = ranch_server:get_listener_start_args(Ref), - TransOpts = get_transport_options(Ref), - {Transport, TransOpts} - catch - error:badarg -> - undefined - end. + ranch_server:stop_listener(Ref). -spec suspend_listener(ref()) -> ok | {error, any()}. suspend_listener(Ref) -> diff --git a/src/ranch_server.erl b/src/ranch_server.erl index 3966c1b5a3..f590156f86 100644 --- a/src/ranch_server.erl +++ b/src/ranch_server.erl @@ -40,6 +40,7 @@ -export([get_protocol_options/1]). -export([get_listener_start_args/1]). -export([count_connections/1]). +-export([stop_listener/1]). %% gen_server. -export([init/1]). @@ -180,6 +181,10 @@ count_connections(Ref) -> 0, get_connections_sups(Ref)). +-spec stop_listener(ranch:ref()) -> ok | {error, term()}. +stop_listener(Ref) -> + gen_server:call(?MODULE, {stop_listener, Ref}). + %% gen_server. -spec init([]) -> {ok, #state{}}. @@ -220,6 +225,14 @@ handle_call({set_proto_opts, Ref, Opts}, _, State) -> ets:insert(?TAB, {{proto_opts, Ref}, Opts}), _ = [ConnsSup ! {set_protocol_options, Opts} || {_, ConnsSup} <- get_connections_sups(Ref)], {reply, ok, State}; +handle_call({stop_listener, Ref}, _, State) -> + Reply = try + do_stop_listener(Ref) + catch + _:Reason -> + {error, Reason} + end, + {reply, Reply, State}; handle_call(_Request, _From, State) -> {reply, ignore, State}. @@ -277,3 +290,33 @@ set_monitored_process(Key, Pid, State=#state{monitors=Monitors0}) -> %% Finally we start monitoring this new process. MonitorRef = erlang:monitor(process, Pid), State#state{monitors=[{{MonitorRef, Pid}, Key}|Monitors]}. + +do_stop_listener(Ref) -> + do_stop_listener1(Ref). + +do_stop_listener1(Ref) -> + TransportAndOpts = try + [_, Transport, _, _, _] = get_listener_start_args(Ref), + TransOpts = get_transport_options(Ref), + {Transport, TransOpts} + catch + error:badarg -> + undefined + end, + do_stop_listener2(Ref, TransportAndOpts). + +do_stop_listener2(Ref, TransportAndOpts) -> + case supervisor:terminate_child(ranch_sup, {ranch_listener_sup, Ref}) of + ok -> + _ = supervisor:delete_child(ranch_sup, {ranch_listener_sup, Ref}), + _ = cleanup_listener_opts(Ref), + do_stop_listener3(TransportAndOpts); + {error, _} = Error -> + Error + end. + +do_stop_listener3(undefined) -> + ok; +do_stop_listener3({Transport, TransOpts}) -> + _ = Transport:cleanup(TransOpts), + ok.