From: Eric Wong Date: 2011-04-15T05:39:25+09:00 Subject: [ruby-core:35755] Re: [Ruby 1.9 - Bug #4558] TestSocket#test_closed_read fails after r31230 KOSAKI Motohiro wrote: > > KOSAKI Motohiro wrote: > >> > Issue #4558 has been updated by Eric Wong. > following scenario should be happen too. > > CPU1 CPU2 CPU3 > ------------------------------------------------------------------- > open() -> 5 > close(5) > open() -> 5 > read(5) -> success, but read different data. OK, I'm starting to think there's no safe way to handle these situations, especially with MVM on the horizon. Just telling users to stop doing close() in a different thread is probably the best way to go... > >> Hmm... > >> If windows can't implement close() case, I doubt r30852 is correct fix. > >> Is this really worth that *nix and windows have different spec? > > > > If r30852 is reverted, Linux (and maybe other *nix) will still break > > threads out of blocking read/write with EBADF and > > rb_io_wait_*able(fptr->fd) will raise IOError as long as we > > assign fptr->fd = -1 before the actual close() call in IO#close. > > > > Maybe Windows (and possibly other OS) will be forced to call do_select() > > to implement behavior consistent with Linux. > > ??? > I'm sorry, I haven't catch your point. > Which issue is solved by calling do_select()? It can reduce the likelyhood of read() being uninterruptable since do_select() will sleep in 100ms intervals to check for interrupts on win. There's still a small chance of blocking read() since select() can have false positives and other threads could've drained the data... > > On a related note, r30852 also has the problem with making IO#close an > > O(n) operation since it needs to scan through all threads (and I'd like > > to run thousands of threads :>). > > I have no opinion. I like faster software, but I haven't seen close > makes performance bottleneck. Contrived test case, but it gets worse as nr_thread increases: # ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux] 0.010000 0.000000 0.010000 ( 0.007288) # ruby 1.9.3dev (2011-04-14 trunk 31267) [x86_64-linux] 0.030000 0.000000 0.030000 ( 0.033881) -----------------------------8< ------------------------- require "benchmark" nr_thread = 1_000 nr_close = 1_000 threads = nr_thread.times.map { Thread.new { sleep } } puts(Benchmark.measure do nr_close.times do File.open(__FILE__).close end end) threads.each { |thr| thr.run }.each { |thr| thr.join } -- Eric Wong