From: Bill Kelly Date: 2006-05-02T00:49:52+09:00 Subject: Re: Multiplexed I/O > From: "Robert Klemme" > 2006/5/1, James Edward Gray II : > > On May 1, 2006, at 1:44 AM, Minkoo Seo wrote: > > > > > I can't understand this. If ruby uses non native multithreading, then > > > all threads will run in the same process. And that implies that one > > > blocking I/O operation stop the all threads in the ruby interpreter > > > process, doesn't it? > > > > I'm pretty sure Ruby selects over sockets under the hood, to keep the > > interpreter from blocking. I don't believe that's a perfect solution > > those as something like a large write could still block the process. > > Theoretically yes, but in practice this works pretty well. Could even > be that large writes are split up by the Ruby engine. Also, from looking at differences in the Ruby socket code between 1.8.2 and 1.8.4, it looks like a significant effort was made to handle sockets in nonblocking mode. A grep for EWOULDBLOCK in 1.8.4: ext/socket/socket.c:#ifndef EWOULDBLOCK ext/socket/socket.c:#define EWOULDBLOCK EAGAIN ext/socket/socket.c: case EWOULDBLOCK: ext/socket/socket.c: * * Errno::EWOULDBLOCK - the socket is marked as nonblocking and the ext/socket/socket.c: * * Errno::EWOULDBLOCK - see Errno::EAGAIN ext/socket/socket.c: * * Errno::EWOULDBLOCK - +socket+ is marked as nonblocking and a call to ext/socket/socket.c: * * Errno::EWOULDBLOCK - same as Errno::EAGAIN ext/socket/socket.c: * * Errno::EWOULDBLOCK - +socket+ is marked as nonblocking and no connections are file.c:#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN file.c: case EWOULDBLOCK: file.c:#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN file.c: case EWOULDBLOCK: io.c:#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN io.c: case EWOULDBLOCK: io.c:#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN io.c: case EWOULDBLOCK: io.c:#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN io.c: case EWOULDBLOCK: win32/win32.c:#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError() == ERROR_LOCK_VIOLATION ? EWOULDBLOCK : EACCES)) win32/win32.c: } while (i && errno == EWOULDBLOCK); win32/win32.c: if (r != WSAEWOULDBLOCK) { That said, I haven't actually put it to the test. But looking at the code, it seems nonblocking sockets are being handled these days. So perhaps not even big writes necessarily block anymore, if we put the socket in nonblocking mode. (Anyone know for sure?) Regards, Bill