From: Ivo Palli Date: 2005-01-26T00:00:58+09:00 Subject: In need of Win32 fcntl (non-blocking) Hi there, I am making a multi-user, telnet based, bbs. At work I use Linux Ruby, at home a Win32 port. (http://rubyinstaller.rubyforge.org/wiki/wiki.pl) Now a multi-user server can be done in threads, but since I want to keep it simple and avoid dead-locks and starvation problems, I decided not to use threads. (I also read that threads can block the whole program if they get stuck in system calls. That's not something I want.) Instead I want to use a select, which is thankfully support in Ruby. However a read to a socket which has data open always seems to block, unless I specifically read what is available. Since I cannot know how much data is waiting for me, I really need to do a non-blocking read. In Linux it works, in Windows the fcntl call is not supported. :( As far as I searched and tried, there is no other way to read data without blocking. This guy http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3155 seems to have made a fix some time ago. Can I ask why it is not in the standard distribution? On that note, can somebody point me to a binary win32 distribution that _does_ have this patch incorporated? One last thing. I ran the example below on both Linux and Win32. Normally stdout buffering is done up until a '\n' after which output is flushed (ANSI C, both on Linux and Win32). This behaviour is seen on the Linux Ruby port, but not under Win32 where I had to put in 'STDOUT.sync=true'. Can this be considered a bug? I'm using: ruby 1.8.2 (2004-12-25) [i386-mswin32] ruby 1.8.2 (2004-12-25) [i686-linux] Server example, works on Linux, not on Win32: # socket example - server side # usage: ruby svr.rb require "socket" require "fcntl" gs = TCPserver.open(0) addr = gs.addr addr.shift printf("server is on %s\n", addr.join(":")) socks = [gs] loop do nsock = select(socks); next if nsock == nil for s in nsock[0] if s == gs ns = s.accept ns.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK) socks.push(ns) print(s, " is accepted\n") else if s.eof? print(s, " is gone\n") s.close socks.delete(s) else print "[" + s.read + "]\n" end end end end