Bug #1162: Build Assertion Failure with VC+++ - Incorrect flushing of stdout/stderr
http://redmine.ruby-lang.org/issues/show/1162

Author: Charlie Savage
Status: Open, Priority: Normal
Category: core
ruby -v: ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32_90]

Build ruby 1.9.1 with VC 2008 using the following flags:

RUNTIMEFLAG = -MDd
OPTFLAGS = -Od -RTC1
LDFLAGS = -link -INCREMENTAL:NO -DEBUG -OPT:REF -OPT:ICF

Failure occurs when running miniruby.exe for the first time:

File: f:\dd\vctools\crt_bld\self_x86\src\commit.c, line 69.
Expression: ("Invalid file descriptor.  File possibly closed by a different thread", 0)

The call sequence:

rb_io_flush -> fsync -> _commit -> FlushFileBuffers

The stream is stdout or stderr.

From Microsoft's documentation of FlushFileBuffers (http://msdn.microsoft.com/en-us/library/aa364439(VS.85).aspx):

The function fails if hFile is a handle to the console output. That is because the console output is not buffered. The function returns FALSE, and GetLastError returns ERROR_INVALID_HANDLE.

Thus calling _commit on STDOUT or STDERR is invalid. 

This patch fixes the problem:

--- io.old.c	2009-02-14 14:27:15 -0700
+++ io.c	2009-02-14 14:27:20 -0700
@@ -1002,7 +1002,8 @@
         if (io_fflush(fptr) < 0)
             rb_sys_fail(0);
 #ifdef _WIN32
-	  fsync(fptr->fd);
+    if (io != rb_stdout && io != rb_stderr)
+	    fsync(fptr->fd);
 #endif
     }
     if (fptr->mode & FMODE_READABLE) {


----------------------------------------
http://redmine.ruby-lang.org