Piotr Caban : msvcrt: Make FILE writing functions thread safe.

Alexandre Julliard julliard at winehq.org
Fri May 20 12:44:33 CDT 2011


Module: wine
Branch: master
Commit: 716a69c6db577fd1015fba70b0877ca73682ca21
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=716a69c6db577fd1015fba70b0877ca73682ca21

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri May 20 13:22:59 2011 +0200

msvcrt: Make FILE writing functions thread safe.

---

 dlls/msvcrt/file.c |  161 +++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 109 insertions(+), 52 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 27b9ef5..90f8a45 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -2563,9 +2563,16 @@ int CDECL MSVCRT__write(int fd, const void* buf, unsigned int count)
 int CDECL MSVCRT__putw(int val, MSVCRT_FILE* file)
 {
   int len;
+
+  MSVCRT__lock_file(file);
   len = MSVCRT__write(file->_file, &val, sizeof(val));
-  if (len == sizeof(val)) return val;
+  if (len == sizeof(val)) {
+    MSVCRT__unlock_file(file);
+    return val;
+  }
+
   file->_flag |= MSVCRT__IOERR;
+  MSVCRT__unlock_file(file);
   return MSVCRT_EOF;
 }
 
@@ -2883,38 +2890,44 @@ MSVCRT_wchar_t * CDECL MSVCRT_fgetws(MSVCRT_wchar_t *s, int size, MSVCRT_FILE* f
  */
 MSVCRT_size_t CDECL MSVCRT_fwrite(const void *ptr, MSVCRT_size_t size, MSVCRT_size_t nmemb, MSVCRT_FILE* file)
 {
-  MSVCRT_size_t wrcnt=size * nmemb;
-  int written = 0;
-  if (size == 0)
-      return 0;
-  if(file->_cnt) {
-	int pcnt=(file->_cnt>wrcnt)? wrcnt: file->_cnt;
-	memcpy(file->_ptr, ptr, pcnt);
-	file->_cnt -= pcnt;
-	file->_ptr += pcnt;
-	written = pcnt;
-	wrcnt -= pcnt;
+    MSVCRT_size_t wrcnt=size * nmemb;
+    int written = 0;
+    if (size == 0)
+        return 0;
+
+    MSVCRT__lock_file(file);
+    if(file->_cnt) {
+        int pcnt=(file->_cnt>wrcnt)? wrcnt: file->_cnt;
+        memcpy(file->_ptr, ptr, pcnt);
+        file->_cnt -= pcnt;
+        file->_ptr += pcnt;
+        written = pcnt;
+        wrcnt -= pcnt;
         ptr = (const char*)ptr + pcnt;
-  } else if(!(file->_flag & MSVCRT__IOWRT)) {
-	if(file->_flag & MSVCRT__IORW) {
-		file->_flag |= MSVCRT__IOWRT;
-	} else
-		return 0;
-  }
-  if(wrcnt) {
-	/* Flush buffer */
-  	int res=msvcrt_flush_buffer(file);
-	if(!res) {
-		int pwritten = MSVCRT__write(file->_file, ptr, wrcnt);
-  		if (pwritten <= 0)
-                {
-                    file->_flag |= MSVCRT__IOERR;
-                    pwritten=0;
-                }
-		written += pwritten;
-	}
-  }
-  return written / size;
+    } else if(!(file->_flag & MSVCRT__IOWRT)) {
+        if(file->_flag & MSVCRT__IORW) {
+            file->_flag |= MSVCRT__IOWRT;
+        } else {
+            MSVCRT__unlock_file(file);
+            return 0;
+        }
+    }
+    if(wrcnt) {
+        /* Flush buffer */
+        int res=msvcrt_flush_buffer(file);
+        if(!res) {
+            int pwritten = MSVCRT__write(file->_file, ptr, wrcnt);
+            if (pwritten <= 0)
+            {
+                file->_flag |= MSVCRT__IOERR;
+                pwritten=0;
+            }
+            written += pwritten;
+        }
+    }
+
+    MSVCRT__unlock_file(file);
+    return written / size;
 }
 
 /*********************************************************************
@@ -3060,18 +3073,26 @@ int CDECL MSVCRT__flsbuf(int c, MSVCRT_FILE* file);
  */
 int CDECL MSVCRT_fputc(int c, MSVCRT_FILE* file)
 {
+  int res;
+
+  MSVCRT__lock_file(file);
   if(file->_cnt>0) {
     *file->_ptr++=c;
     file->_cnt--;
     if (c == '\n')
     {
-      int res = msvcrt_flush_buffer(file);
+      res = msvcrt_flush_buffer(file);
+      MSVCRT__unlock_file(file);
       return res ? res : c;
     }
-    else
+    else {
+      MSVCRT__unlock_file(file);
       return c & 0xff;
+    }
   } else {
-    return MSVCRT__flsbuf(c, file);
+    res = MSVCRT__flsbuf(c, file);
+    MSVCRT__unlock_file(file);
+    return res;
   }
 }
 
@@ -3376,11 +3397,21 @@ int CDECL MSVCRT_fgetpos(MSVCRT_FILE* file, MSVCRT_fpos_t *pos)
 int CDECL MSVCRT_fputs(const char *s, MSVCRT_FILE* file)
 {
     MSVCRT_size_t i, len = strlen(s);
-    if (!(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT))
-      return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
+    int ret;
+
+    MSVCRT__lock_file(file);
+    if (!(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT)) {
+      ret = MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
+      MSVCRT__unlock_file(file);
+      return ret;
+    }
     for (i=0; i<len; i++)
-      if (MSVCRT_fputc(s[i], file) == MSVCRT_EOF) 
-	return MSVCRT_EOF;
+      if (MSVCRT_fputc(s[i], file) == MSVCRT_EOF)  {
+        MSVCRT__unlock_file(file);
+        return MSVCRT_EOF;
+      }
+
+    MSVCRT__unlock_file(file);
     return 0;
 }
 
@@ -3390,15 +3421,23 @@ int CDECL MSVCRT_fputs(const char *s, MSVCRT_FILE* file)
 int CDECL MSVCRT_fputws(const MSVCRT_wchar_t *s, MSVCRT_FILE* file)
 {
     MSVCRT_size_t i, len = strlenW(s);
-    if (!(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT))
-      return MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
-    for (i=0; i<len; i++)
-      {
-        if ((s[i] == '\n') && (MSVCRT_fputc('\r', file) == MSVCRT_EOF))
-	  return MSVCRT_WEOF;
-	if (MSVCRT_fputwc(s[i], file) == MSVCRT_WEOF)
-	  return MSVCRT_WEOF; 
-      }
+    int ret;
+
+    MSVCRT__lock_file(file);
+    if (!(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT)) {
+        ret = MSVCRT_fwrite(s,sizeof(*s),len,file) == len ? 0 : MSVCRT_EOF;
+        MSVCRT__unlock_file(file);
+        return ret;
+    }
+    for (i=0; i<len; i++) {
+        if (((s[i] == '\n') && (MSVCRT_fputc('\r', file) == MSVCRT_EOF))
+                || MSVCRT_fputwc(s[i], file) == MSVCRT_WEOF) {
+            MSVCRT__unlock_file(file);
+            return MSVCRT_WEOF;
+        }
+    }
+
+    MSVCRT__unlock_file(file);
     return 0;
 }
 
@@ -3490,8 +3529,17 @@ int CDECL MSVCRT__putwch(int c)
 int CDECL MSVCRT_puts(const char *s)
 {
     MSVCRT_size_t len = strlen(s);
-    if (MSVCRT_fwrite(s,sizeof(*s),len,MSVCRT_stdout) != len) return MSVCRT_EOF;
-    return MSVCRT_fwrite("\n",1,1,MSVCRT_stdout) == 1 ? 0 : MSVCRT_EOF;
+    int ret;
+
+    MSVCRT__lock_file(MSVCRT_stdout);
+    if(MSVCRT_fwrite(s, sizeof(*s), len, MSVCRT_stdout) != len) {
+        MSVCRT__unlock_file(MSVCRT_stdout);
+        return MSVCRT_EOF;
+    }
+
+    ret = MSVCRT_fwrite("\n",1,1,MSVCRT_stdout) == 1 ? 0 : MSVCRT_EOF;
+    MSVCRT__unlock_file(MSVCRT_stdout);
+    return ret;
 }
 
 /*********************************************************************
@@ -3501,8 +3549,17 @@ int CDECL _putws(const MSVCRT_wchar_t *s)
 {
     static const MSVCRT_wchar_t nl = '\n';
     MSVCRT_size_t len = strlenW(s);
-    if (MSVCRT_fwrite(s,sizeof(*s),len,MSVCRT_stdout) != len) return MSVCRT_EOF;
-    return MSVCRT_fwrite(&nl,sizeof(nl),1,MSVCRT_stdout) == 1 ? 0 : MSVCRT_EOF;
+    int ret;
+
+    MSVCRT__lock_file(MSVCRT_stdout);
+    if(MSVCRT_fwrite(s, sizeof(*s), len, MSVCRT_stdout) != len) {
+        MSVCRT__unlock_file(MSVCRT_stdout);
+        return MSVCRT_EOF;
+    }
+
+    ret = MSVCRT_fwrite(&nl,sizeof(nl),1,MSVCRT_stdout) == 1 ? 0 : MSVCRT_EOF;
+    MSVCRT__unlock_file(MSVCRT_stdout);
+    return ret;
 }
 
 /*********************************************************************




More information about the wine-cvs mailing list