I took some time to analyze my current problem with external semaphores. I was 
just reluctant to raise the limit in my image because I want the problem 
solved. I logged the management of external semaphores and discovered that the 
table fills if a connection times out. 

The problem turns out to be in 

Socket>>#connectTo: hostAddress port: port waitForConnectionFor: timeout 
        "Initiate a connection to the given port at the given host 
        address. Waits until the connection is established or time outs."
        self connectNonBlockingTo: hostAddress port: port.
        self
                waitForConnectionFor: timeout
                ifTimedOut: [ConnectionTimedOut signal: 'Cannot connect to '
                                        , (NetNameResolver stringFromAddress: 
hostAddress) , ':' , port asString]

When a socket is created three external semaphores are registered in the 
ExternalSemaphoreTable. If a connection times out the exception is thrown but 
the Socket still has his resources attached. 

So e.g. in 

SocketStream class>>#openConnectionToHost: hostIP port: portNumber timeout: 
timeout
        | socket |
        socket := Socket new.
        socket connectTo: hostIP port: portNumber waitForConnectionFor: timeout.
        ^self on: socket

it holds locally a socket (with semaphores registered) but on exception time 
the reference to the socket gets lost and the semaphores stay registered. The 
only way to unregister is on finalization time but I think it should work 
better. So I would add a destroy before the exception is raised.

Socket>>#connectTo: hostAddress port: port waitForConnectionFor: timeout 
        "Initiate a connection to the given port at the given host 
        address. Waits until the connection is established or time outs."
        self connectNonBlockingTo: hostAddress port: port.
        self
                waitForConnectionFor: timeout
                ifTimedOut: [
                        self destroy.
                        ConnectionTimedOut signal: 'Cannot connect to '
                                        , (NetNameResolver stringFromAddress: 
hostAddress) , ':' , port asString]

I opened a ticket at https://pharo.fogbugz.com/f/cases/11797 but I'm not sure 
how I am supposed to provide fixes made against a pharo2.0 image. Probably I 
should fix this againt 3.0 but then I'm still a 2.0 user :) 

Norbert

Reply via email to