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

Keith Irwin keith.irwin@REDACTED
Tue Apr 21 18:58:44 CEST 2009


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.

Keith



More information about the erlang-questions mailing list