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