Skip to content

Commit 988b5a9

Browse files
authored
Merge pull request #78 from tomas-abrahamsson/fd-socket-opt
Support the fd socket option when listening
2 parents cbb2961 + 91e7fea commit 988b5a9

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

src/grpcbox_socket.erl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ init([Pool, ListenOpts, PoolOpts]) ->
3030
%% Trapping exit so can close socket in terminate/2
3131
_ = process_flag(trap_exit, true),
3232
Opts = [{active, false}, {mode, binary}, {packet, raw}, {ip, IPAddress} | SocketOpts],
33-
case gen_tcp:listen(Port, Opts) of
33+
{LPort, LOpts} = maybe_adjust_port_opts_for_fdopt(Port, Opts),
34+
case gen_tcp:listen(LPort, LOpts) of
3435
{ok, Socket} ->
3536
%% acceptor could close the socket if there is a problem
3637
MRef = monitor(port, Socket),
@@ -40,6 +41,17 @@ init([Pool, ListenOpts, PoolOpts]) ->
4041
{stop, Reason}
4142
end.
4243

44+
maybe_adjust_port_opts_for_fdopt(Port, Opts) ->
45+
case lists:keymember(fd, 1, Opts) of
46+
true ->
47+
%% If an already opened (bound) file descriptor is passed,
48+
%% we must not set port or ip, or there will be an error
49+
%% when it would have gotten bound again.
50+
{0, lists:keydelete(ip, 1, Opts)};
51+
false ->
52+
{Port, Opts}
53+
end.
54+
4355
handle_call(Req, _, State) ->
4456
{stop, {bad_call, Req}, State}.
4557

test/grpcbox_SUITE.erl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ groups() ->
1313
[{ssl, [], [unary_authenticated]},
1414
{tcp, [], [unary_no_auth, multiple_servers,
1515
unary_garbage_collect_streams]},
16+
{socket_options, [], [fd_socket_option]},
1617
{concurrent, [{repeat_until_any_fail, 5}], [unary_concurrent]},
1718
{negative_tests, [], [unimplemented, closed_stream, generate_error, streaming_generate_error]},
1819
{negative_ssl, [], [unauthorized]},
@@ -22,6 +23,7 @@ groups() ->
2223
all() ->
2324
[{group, ssl},
2425
{group, tcp},
26+
{group, socket_options},
2527
{group, concurrent},
2628
{group, negative_tests},
2729
{group, negative_ssl},
@@ -75,6 +77,14 @@ init_per_group(tcp, Config) ->
7577
transport_opts => #{}}]),
7678
application:ensure_all_started(grpcbox),
7779
Config;
80+
init_per_group(socket_options, Config) ->
81+
application:set_env(grpcbox, client, #{channels => [{default_channel, [{http, "localhost", 8080, []}],
82+
#{}}]}),
83+
application:set_env(grpcbox, servers, [#{grpc_opts => #{service_protos => [route_guide_pb],
84+
services => #{'routeguide.RouteGuide' =>
85+
routeguide_route_guide}},
86+
transport_opts => #{}}]),
87+
Config;
7888
init_per_group(concurrent, Config) ->
7989
application:set_env(grpcbox, client, #{channels => [{default_channel, [{http, "localhost", 8080, []}],
8090
#{}}]}),
@@ -312,6 +322,8 @@ end_per_testcase(multiple_servers, _Config) ->
312322
ok;
313323
end_per_testcase(unary_garbage_collect_streams, _Config) ->
314324
ok;
325+
end_per_testcase(fd_socket_option, _Config) ->
326+
ok;
315327
end_per_testcase(unary_concurrent, _Config) ->
316328
ok;
317329
end_per_testcase(unimplemented, _Config) ->
@@ -564,6 +576,24 @@ multiple_servers(_Config) ->
564576
unary(_Config),
565577
unary(_Config).
566578

579+
fd_socket_option(_Config) ->
580+
%% Use the fd option to dynamically select a free port
581+
{ok, Ip} = inet:getaddr("localhost", inet),
582+
{ok, Sock} = gen_tcp:listen(0, [{ip, Ip}, inet]),
583+
{ok, Fd} = inet:getfd(Sock),
584+
{ok, {_ListenIp, ListenPort}} = inet:sockname(Sock),
585+
application:set_env(grpcbox, client, #{channels => [{default_channel,
586+
[{http, "localhost", ListenPort, []}], #{}}]}),
587+
588+
application:set_env(grpcbox, servers, [#{grpc_opts => #{service_protos => [route_guide_pb],
589+
services => #{'routeguide.RouteGuide' =>
590+
routeguide_route_guide}},
591+
listen_opts => #{socket_options => [{fd, Fd}]}}]),
592+
{ok, _} = application:ensure_all_started(grpcbox),
593+
unary(_Config),
594+
application:stop(grpcbox),
595+
gen_tcp:close(Sock).
596+
567597
unary_concurrent(Config) ->
568598
Nrs = lists:seq(1,100),
569599
ParentPid = self(),

0 commit comments

Comments
 (0)