[erlang-questions] gen_tcp server won't release sockets?

Keith Irwin keith.irwin@REDACTED
Tue Apr 21 20:51:17 CEST 2009


On Tue, Apr 21, 2009 at 9:58 AM, Keith Irwin <keith.irwin@REDACTED> wrote:
> On Tue, Apr 21, 2009 at 8:42 AM, Keith Irwin <keith.irwin@REDACTED> wrote:
>> Folks--
>> I've implemented a gen_tcp server based on the example at the end of the
>> gen_tcp man page. In other words, it spawns 5 processes for a process pool.
>> Each process blocks on an accept call to a listen socket, reads an incoming
>> request, responds with a response, then loops around to block on the accept
>> again.
>> The thing is, each of these processes in the process pool seems to hold a
>> link to a port, as in, <#Port 0.123> (or something like that). I know this
>> because I can start up the appmon, click on the process in the pool, and see
>> an ever growing list of Ports inside the { links } tuple.
>> When a certain limit is reached, I get an "enfile" or "emfile" error, the
>> process dies, the ports (or whatever they are), are reclaimed. I then
>> spawn_link a new process to add to the pool, and off I go.
>> Is there some reason a process which loops over an "gen_tcp:accept" would
>> keep holding on to the connections it gets in its link table?
>> Another wrinkle: I'm running the gen_tcp server from within a gen_server
>> instance. The gen_service:init creates the listen socket, then spawns the
>> process pool (via spawn_link). I use handle_info to trap a call to EXIT to
>> spawn a new process pool instance if one of the existing ones dies.
>> (Mac OSX 10.5.6, Erlang R12B-5 via MacPorts)
>> Keith
>
> Here's an example of the process info provided by appmon for one of
> these pooled processes:
>
> Node: nonode@REDACTED, Process: <0.133.0>
> [{current_function,{prim_inet,accept0,2}},
>  {initial_call,{erlang,apply,2}},
>  {status,waiting},
>  {message_queue_len,0},
>  {messages,[]},
>  {links,[#Port<0.4256>,#Port<0.4394>,#Port<0.4510>,#Port<0.4575>,
>         #Port<0.4590>,<0.131.0>,#Port<0.4587>,#Port<0.4540>,#Port<0.4557>,
>         #Port<0.4548>,#Port<0.4529>,#Port<0.4522>,#Port<0.4456>,
>         #Port<0.4474>,#Port<0.4495>,#Port<0.4486>,#Port<0.4468>,
>         #Port<0.4464>,#Port<0.4432>,#Port<0.4452>,#Port<0.4438>,
>         #Port<0.4428>,#Port<0.4414>,#Port<0.4312>,#Port<0.4364>,
>         #Port<0.4384>,#Port<0.4376>,#Port<0.4356>,#Port<0.4350>,
>         #Port<0.4286>,#Port<0.4302>,#Port<0.4292>,#Port<0.4276>,
>         #Port<0.4266>,#Port<0.4008>,#Port<0.4133>,#Port<0.4196>,
>         #Port<0.4226>,#Port<0.4246>,#Port<0.4236>,#Port<0.4216>,
>         #Port<0.4206>,#Port<0.4154>,#Port<0.4172>,#Port<0.4162>,
>         #Port<0.4146>,#Port<0.4139>,#Port<0.4069>,#Port<0.4096>,
>         #Port<0.4129>,#Port<0.4124>,#Port<0.4084>,#Port<0.4074>,
>         #Port<0.4038>,#Port<0.4056>,#Port<0.4040>,#Port<0.4028>,
>         #Port<0.4022>,#Port<0.3884>,#Port<0.3940>,#Port<0.3978>,
>         #Port<0.3996>,#Port<0.3990>,#Port<0.3970>,#Port<0.3947>,
>         #Port<0.3914>,#Port<0.3929>,#Port<0.3924>,#Port<0.3902>,
>         #Port<0.3894>,#Port<0.3824>,#Port<0.3854>,#Port<0.3879>,
>         #Port<0.3864>,#Port<0.3844>,#Port<0.3834>,#Port<0.3794>,
>         #Port<0.3814>,#Port<0.3804>,#Port<0.3784>,#Port<0.3774>]},
>  {dictionary,[]},
>  {trap_exit,false},
>  {error_handler,error_handler},
>  {priority,normal},
>  {group_leader,<0.33.0>},
>  {total_heap_size,10946},
>  {heap_size,4181},
>  {stack_size,10},
>  {reductions,1231748},
>  {garbage_collection,[{fullsweep_after,65535},{minor_gcs,13}]},
>  {suspending,[]}]
>
>
> The Ports in the links list keep growing until (I suspect) I run out
> of file handles. Any reason those aren't being collected? I even issue
> a gen_tcp:close(Socket) on the socket I get from the accept call. No
> good.

To add another detail, the above #Port<0.1234> style numbers are all
one less than the number of the socket I get from the accept call.

Keith



More information about the erlang-questions mailing list