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

Keith Irwin <>
Tue Apr 21 21:56:57 CEST 2009


I solved this issue.

The handler was calling code which did (basically) an HTTP get, but my
HTTP get class was not closing the socket when it was done.

Keith

On Tue, Apr 21, 2009 at 11:51 AM, Keith Irwin <> wrote:
> On Tue, Apr 21, 2009 at 9:58 AM, Keith Irwin <> wrote:
>> On Tue, Apr 21, 2009 at 8:42 AM, Keith Irwin <> 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: , 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