Hi, Luis Lavena wrote: > On Mar 27, 2:41 am, "Just Another Victim of the .. Morality" > <ihates... / hotmail.com> wrote: >> necessarily so or can we change this? Shouldn't we like to change this? >> count += 1 >> end >> end >> gets > > I've asked about this back in September 2007 at ruby-core mailing > list, no answer. I'm copying my post with details more information: > > Hello Ruby Developers. > > I've been trying to determine what is wrong with this simple script: > > http://pastie.caboo.se/101434 > > t = Thread.new { > while true > puts "printing a line" > sleep 2 > end > } > > gets > t.exit > puts "exiting" > > === > > And found that all the IO (stdin) is broken on Windows: > custom build with MinGW (3.4.5 -- mingw special) > custom build with VC8 > official build VC6 > > All behave the same way: just 1 line of "printing a line" gets > actually printed, and the world halt until you hit enter. > > I saw a few post dating 2003 about this... and this brakes the > cross-platform nature of most of ruby: works on some platform, don't > work on other. > > Since 1.8.6 will stay with us a bit longer, any ideas how to solve it? > > Park Heesob posted a patch back then, but it don't work as expected > (this problem didn't get solved). > > For the record: 1.9.0 don't show this issue, but YARV is another > different breed. > > Thanks in advance for your time. > > == > > Even it doesn't solve your issue, explain it better. > > Still, no answer, no solution :'( > > Regards, Here is the patched code of rb_win_selected function (win32.c,ruby-1.8.6-p111) It will fix Thread blocking problem with standard input waiting. long rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, struct timeval *timeout) { DWORD ms_total, limit; HANDLE handles[MAXIMUM_WAIT_OBJECTS]; int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS]; int n_handles = 0, i; fd_set aread, awrite, aexcept; int retcode; long r; fd_set file_rd; fd_set file_wr; #ifdef USE_INTERRUPT_WINSOCK fd_set trap; #endif /* USE_INTERRUPT_WINSOCK */ int file_nfds; #define SAFE_FD_ISSET(fd, set) (set != NULL && rb_w32_fdisset(fd, set)) /* calculate how long we need to wait in milliseconds */ if (timeout == NULL) { ms_total = INFINITE; } else { ms_total = timeout->tv_sec * 1000; ms_total += timeout->tv_usec / 1000; } /* build an array of handles for non-sockets */ for (i = 0; i <= nfds; i++) { if (SAFE_FD_ISSET(i, rd) || SAFE_FD_ISSET(i, wr)) { handles[n_handles] = (HANDLE)TO_SOCKET(i); if ((SOCKET)handles[n_handles]==TO_SOCKET(0)) { /* only treat stdin */ handle_slot_to_fd[n_handles] = i; n_handles++; } } } if (!NtSocketsInitialized) { StartSockets(); } r = 0; if (rd && rd->fd_count > r) r = rd->fd_count; if (wr && wr->fd_count > r) r = wr->fd_count; if (ex && ex->fd_count > r) r = ex->fd_count; if (nfds > r) nfds = r; if (nfds == 0 && timeout) { Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000); return 0; } file_nfds = extract_file_fd(rd, &file_rd); file_nfds += extract_file_fd(wr, &file_wr); if (file_nfds) { if(n_handles>0) { FD_ZERO(&aread); FD_ZERO(&awrite); limit = GetTickCount() + ms_total; do { DWORD wret; retcode = 0; wret = MsgWaitForMultipleObjects(n_handles, handles, FALSE, retcode > 0 ? 0 : 100, QS_ALLEVENTS); if (wret == WAIT_TIMEOUT) { /* set retcode to 0; this is the default. * select() may have set it to something else, * in which case we leave it alone, so this branch * does nothing */ ; } else if (wret == WAIT_FAILED) { if (retcode == 0) { retcode = -1; } } else { if (retcode < 0) { retcode = 0; } for (i = 0; i < n_handles; i++) { if (WAIT_OBJECT_0 == WaitForSingleObject(handles[i], 0)) { if (SAFE_FD_ISSET(handle_slot_to_fd[i], rd)) { rb_w32_fdset(handle_slot_to_fd[i], &aread); } if (SAFE_FD_ISSET(handle_slot_to_fd[i], wr)) { rb_w32_fdset(handle_slot_to_fd[i], &awrite); } retcode++; } } } } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit)); if (rd) *rd = aread; if (wr) *wr = awrite; } else { // assume normal files are always readable/writable // fake read/write fd_set and return value if (rd) *rd = file_rd; if (wr) *wr = file_wr; } return file_nfds; } #if USE_INTERRUPT_WINSOCK if (ex) trap = *ex; else trap.fd_count = 0; if (trap.fd_count < FD_SETSIZE) trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event; // else unable to catch interrupt. ex = &trap; #endif /* USE_INTERRUPT_WINSOCK */ RUBY_CRITICAL({ r = select(nfds, rd, wr, ex, timeout); if (r == SOCKET_ERROR) { errno = map_errno(WSAGetLastError()); } }); return r; } Regards, Park Heesob -- Posted via http://www.ruby-forum.com/.