It appears that Hubbe tested socketpair() and found it to return EAGAIN and EADDRINUSE on occasion on AmigaOS? Even though all the UNIX manpages list it as incapable of returning either EAGAIN or EADDRINUSE? Anyone here who can still recall the circumstances?
I can't even begin to imagine why the socketpair() call would fail with an EADDRINUSE. Any clues?
It appears that Hubbe tested socketpair() and found it to return EAGAIN and EADDRINUSE on occasion on AmigaOS? Even though all the UNIX manpages list it as incapable of returning either EAGAIN or EADDRINUSE? Anyone here who can still recall the circumstances?
AmigaOS (at the time, not sure about now) probably doesn't have true AF_UNIX sockets, and simulates them with AF_INET sockets (just like socketpair_ultra), which can run out of ports on the loopback-interface, which will fail with EADDRINUSE. Note the following comment in src/modules/files/file.c:
/* Don't try to use socketpair() on AmigaOS, socketpair_ultra works better */
I can't even begin to imagine why the socketpair() call would fail with an EADDRINUSE. Any clues? -- Sincerely, Stephen R. van den Berg.
It appears that Hubbe tested socketpair() and found it to return EAGAIN and EADDRINUSE on occasion on AmigaOS? Even though all the UNIX manpages list it as incapable of returning either EAGAIN or EADDRINUSE? Anyone here who can still recall the circumstances?
AmigaOS (at the time, not sure about now) probably doesn't have true AF_UNIX sockets, and simulates them with AF_INET sockets (just like socketpair_ultra), which can run out of ports on the loopback-interface, which will fail with EADDRINUSE. Note the following comment in src/modules/files/file.c:
/* Don't try to use socketpair() on AmigaOS, socketpair_ultra works better */
BTW: I don't believe Hubbe ever compiled Pike for AmigaOS himself, but that most of the AmigaOS patches came from Bernhard Fastenrath and Marcus Comstedt. I seem to remember Bernhard Fastenrath reporting lots of bugs in ixemul.library that Pike's testsuite detected.
AmigaOS (at the time, not sure about now) probably doesn't have true AF_UNIX sockets, and simulates them with AF_INET sockets (just like socketpair_ultra), which can run out of ports on the loopback-interface, which will fail with EADDRINUSE. Note the following comment in src/modules/files/file.c:
/* Don't try to use socketpair() on AmigaOS, socketpair_ultra works better */
What I don't like about this EADDRINUSE-retry-loop is that an EADDRINUSE condition (in these cases) is dependent on the fact that *at the time of the systemcall* there are no available spare ports. Now, if this is a temporary condition, because some of the occupied ports are already lingering (i.e. already closed, but still blocked due to lingering timers), then it is dependent on these timers when the next port will become available.
This means that there is nothing inherently smart about repeatedly trying the systemcall in a tight loop. The only reason it eventually seems to work is because apparently the wall clock time that has passed before all ten retries have been exhausted is just large enough for a new port to become available. I.e. the upper limit to the number of retries needed to succeed is dependent on the CPU speed of the machine. If the machine is too fast, then retrying the systemcall a few times is just plain silly.
The best solution would probably be actually waiting for a millisecond (or more) upon getting an EADDRINUSE in those cases, then retry. That would, at least, take out the CPU dependency. What isn't good about such a solution is that it introduces hidden delays which are not apparent at the Pike level. Also, determining the proper amount of delay requires knowledge of the timers involved (which should be consistent across all TCP/IP stacks, but not always is).
pike-devel@lists.lysator.liu.se