Added workaround for apparent bug in OS X 10.3.4. If you started

a synergy client on that OS and pointed it at a system that wasn't
listening for connections then instead of the connection attempt
failing with 'connection refused' the system would claim the
connection succeeded.  A subsequent read would reveal the problem
and synergy would "disconnect" and retry, causing the CPU to spin.
The system does correctly set the socket error state so this
workaround checks for socket errors when connecting whether or not
select reports an error state.

Also, sometimes the system doesn't claim success but doesn't report
an error.  Synergy eventually times out these attempts.
This commit is contained in:
crs 2004-07-28 21:54:39 +00:00
parent 59e466da0a
commit 970c8b2fba
1 changed files with 18 additions and 1 deletions

View File

@ -425,7 +425,24 @@ CTCPSocket::serviceConnecting(ISocketMultiplexerJob* job,
{ {
CLock lock(&m_mutex); CLock lock(&m_mutex);
if (error) { // should only check for errors if error is true but checking a new
// socket (and a socket that's connecting should be new) for errors
// should be safe and Mac OS X appears to have a bug where a
// non-blocking stream socket that fails to connect immediately is
// reported by select as being writable (i.e. connected) even when
// the connection has failed. this is easily demonstrated on OS X
// 10.3.4 by starting a synergy client and telling to connect to
// another system that's not running a synergy server. it will
// claim to have connected then quickly disconnect (i guess because
// read returns 0 bytes). unfortunately, synergy attempts to
// reconnect immediately, the process repeats and we end up
// spinning the CPU. luckily, OS X does set SO_ERROR on the
// socket correctly when the connection has failed so checking for
// errors works. (curiously, sometimes OS X doesn't report
// connection refused. when that happens it at least doesn't
// report the socket as being writable so synergy is able to time
// out the attempt.)
if (true || error) {
try { try {
// connection may have failed or succeeded // connection may have failed or succeeded
ARCH->throwErrorOnSocket(m_socket); ARCH->throwErrorOnSocket(m_socket);