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