Hi,

Patch introduces a new macro __MINGW_PRINTF_LOCKING for fprintf and
vfprintf so when called on the same FILE stream, the operations are not
overlapped. __USE_MINGW_ANSI_STDIO must also be set for the new macro to
take effect.

The reason why it is done in such a way is so programs that already
doing their own locking will not be affected.

Idea from user Mateusz of Sourceforge. Patch OK?

diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
index d2d54c4..a9a5ab2 100644
--- a/mingw-w64-crt/Makefile.am
+++ b/mingw-w64-crt/Makefile.am
@@ -293,7 +293,10 @@ src_libmingwex=\
   stdio/mingw_wvfscanf.c   stdio/snprintf.c          stdio/snwprintf.c        
stdio/strtof.c            stdio/truncate.c        \
   stdio/ulltoa.c           stdio/ulltow.c            stdio/vasprintf.c        
stdio/vfscanf.c           stdio/vfwscanf.c        \
   stdio/vscanf.c           stdio/vsnprintf.c         stdio/vsnprintf_s.c      
stdio/vsnwprintf.c        stdio/vsscanf.c         \
-  stdio/vswscanf.c         stdio/vwscanf.c           stdio/wtoll.c            
stdio/mingw_asprintf.c    stdio/mingw_vasprintf.c
+  stdio/vswscanf.c         stdio/vwscanf.c           stdio/wtoll.c            
stdio/mingw_asprintf.c    stdio/mingw_vasprintf.c \
+  stdio/mingw_fprintf_locked.c stdio/mingw_fprintfw_locked.c 
stdio/mingw_pformat_locked.c stdio/mingw_vfprintf_locked.c \
+  stdio/mingw_vfprintfw_locked.c stdio/mingw_pformatw_locked.c
+
 
 # these only go into the 64 bit version:
 src_libmingwex64=\
diff --git a/mingw-w64-crt/stdio/mingw_fprintf_locked.c 
b/mingw-w64-crt/stdio/mingw_fprintf_locked.c
new file mode 100755
index 0000000..b5c0656
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_fprintf_locked.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "mingw_pformat.h"
+
+int __cdecl __fprintf_locked(FILE *, const APICHAR *, ...) __MINGW_NOTHROW;
+
+int __cdecl __fprintf_locked(FILE *stream, const APICHAR *fmt, ...)
+{
+  register int retval;
+  va_list argv; va_start( argv, fmt );
+  retval = __pformat_locked( PFORMAT_TO_FILE | PFORMAT_NOLIMIT, stream, 0, 
fmt, argv );
+  va_end( argv );
+  return retval;
+}
diff --git a/mingw-w64-crt/stdio/mingw_fprintfw_locked.c 
b/mingw-w64-crt/stdio/mingw_fprintfw_locked.c
new file mode 100755
index 0000000..ced5985
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_fprintfw_locked.c
@@ -0,0 +1,3 @@
+#define __BUILD_WIDEAPI 1
+#include "mingw_fprintf_locked.c"
+
diff --git a/mingw-w64-crt/stdio/mingw_pformat.h 
b/mingw-w64-crt/stdio/mingw_pformat.h
index 4777804..73ebd6e 100644
--- a/mingw-w64-crt/stdio/mingw_pformat.h
+++ b/mingw-w64-crt/stdio/mingw_pformat.h
@@ -79,6 +79,10 @@
 # define __vfprintf       __mingw_vfwprintf
 # define __vsprintf       __mingw_vswprintf
 # define __vsnprintf      __mingw_vsnwprintf
+
+# define __vfprintf_locked __mingw_vfwprintf_locked
+# define __fprintf_locked  __mingw_fwprintf_locked
+# define __pformat_locked  __mingw_wpformat_locked
 #else
 # define __pformat        __mingw_pformat
 #define __fputc(X,STR) fputc((X), (STR))
@@ -92,8 +96,13 @@
 # define __vfprintf       __mingw_vfprintf
 # define __vsprintf       __mingw_vsprintf
 # define __vsnprintf      __mingw_vsnprintf
+
+# define __vfprintf_locked __mingw_vfprintf_locked
+# define __fprintf_locked  __mingw_fprintf_locked
+# define __pformat_locked  __mingw_pformat_locked
 #endif /* __BUILD_WIDEAPI */
 #endif
 
 int __cdecl __pformat(int, void *, int, const APICHAR *, va_list) 
__MINGW_NOTHROW;
+int __cdecl __pformat_locked(int, void *, int, const APICHAR *, va_list) 
__MINGW_NOTHROW;
 #endif /* !defined PFORMAT_H */
diff --git a/mingw-w64-crt/stdio/mingw_pformat_locked.c 
b/mingw-w64-crt/stdio/mingw_pformat_locked.c
new file mode 100755
index 0000000..bcd2e84
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_pformat_locked.c
@@ -0,0 +1,17 @@
+#include <intrin.h>
+#include <synchapi.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include "mingw_pformat.h"
+
+int
+__pformat_locked (int flags, void *dest, int max, const APICHAR *fmt, va_list 
argv){
+  int ret;
+  if (flags & PFORMAT_TO_FILE)
+    while(InterlockedBitTestAndSet((volatile __LONG32*)&((FILE*)dest)->_flag, 
27 ))
+      Sleep(0);
+    ret = __pformat(flags, dest, max, fmt, argv);
+  if (flags & PFORMAT_TO_FILE)
+    InterlockedBitTestAndReset((volatile __LONG32*)&((FILE*)dest)->_flag, 27);
+  return ret;
+}
diff --git a/mingw-w64-crt/stdio/mingw_pformatw_locked.c 
b/mingw-w64-crt/stdio/mingw_pformatw_locked.c
new file mode 100755
index 0000000..d391e56
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_pformatw_locked.c
@@ -0,0 +1,3 @@
+#define __BUILD_WIDEAPI 1
+#include "mingw_pformat_locked.c"
+
diff --git a/mingw-w64-crt/stdio/mingw_vfprintf_locked.c 
b/mingw-w64-crt/stdio/mingw_vfprintf_locked.c
new file mode 100755
index 0000000..a0ba721
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_vfprintf_locked.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "mingw_pformat.h"
+
+int __cdecl __vfprintf_locked(FILE *, const APICHAR *, va_list) 
__MINGW_NOTHROW;
+
+int __cdecl __vfprintf_locked(FILE *stream, const APICHAR *fmt, va_list argv)
+{
+  return __pformat_locked( PFORMAT_TO_FILE | PFORMAT_NOLIMIT, stream, 0, fmt, 
argv );
+}
diff --git a/mingw-w64-crt/stdio/mingw_vfprintfw_locked.c 
b/mingw-w64-crt/stdio/mingw_vfprintfw_locked.c
new file mode 100755
index 0000000..f94a2fd
--- /dev/null
+++ b/mingw-w64-crt/stdio/mingw_vfprintfw_locked.c
@@ -0,0 +1,3 @@
+#define __BUILD_WIDEAPI 1
+#include "mingw_vfprintf_locked.c"
+
diff --git a/mingw-w64-headers/crt/stdio.h b/mingw-w64-headers/crt/stdio.h
index 3b49ddd..2155b6e 100644
--- a/mingw-w64-headers/crt/stdio.h
+++ b/mingw-w64-headers/crt/stdio.h
@@ -187,6 +187,14 @@ extern
   __attribute__((__format__ (gnu_printf, 2, 0))) __attribute__((nonnull (1,2)))
   int __cdecl __mingw_vasprintf(char ** __restrict__ , const char * 
__restrict__ , va_list) __MINGW_NOTHROW;
 
+/* with file locking */
+extern
+  __attribute__((__format__ (gnu_printf, 2, 3))) __MINGW_ATTRIB_NONNULL(2)
+  int __cdecl __mingw_fprintf_locked (FILE * __restrict__ , const char * 
__restrict__ , ...) __MINGW_NOTHROW;
+extern
+  __attribute__((__format__ (gnu_printf, 2, 0))) __MINGW_ATTRIB_NONNULL(2)
+  int __cdecl __mingw_vfprintf_locked (FILE * __restrict__ , const char * 
__restrict__ , va_list) __MINGW_NOTHROW;
+
 #if __USE_MINGW_ANSI_STDIO
 /*
  * User has expressed a preference for C99 conformance...
@@ -286,7 +294,11 @@ int fprintf (FILE *__stream, const char *__format, ...)
 {
   register int __retval;
   __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
+#if defined(__MINGW_PRINTF_LOCKING)
+  __retval = __mingw_vfprintf_locked( __stream, __format, __local_argv );
+#else
   __retval = __mingw_vfprintf( __stream, __format, __local_argv );
+#endif
   __builtin_va_end( __local_argv );
   return __retval;
 }
@@ -317,7 +329,11 @@ __mingw_ovr
 __attribute__((__format__ (gnu_printf, 2, 0))) __MINGW_ATTRIB_NONNULL(2)
 int vfprintf (FILE *__stream, const char *__format, __builtin_va_list 
__local_argv)
 {
+#if defined(__MINGW_PRINTF_LOCKING)
+  return __mingw_vfprintf_locked( __stream, __format, __local_argv );
+#else
   return __mingw_vfprintf( __stream, __format, __local_argv );
+#endif
 }
 
 __mingw_ovr
@@ -601,6 +617,13 @@ int snprintf (char * __restrict__ __stream, size_t __n, 
const char * __restrict_
 /* __attribute__((__format__ (gnu_wprintf, 2, 0))) */ __MINGW_ATTRIB_NONNULL(2)
   int __cdecl __mingw_vswprintf(wchar_t * __restrict__ , const wchar_t * 
__restrict__ ,va_list);
 
+/* with file locking */
+/* __attribute__((__format__ (gnu_wprintf, 1, 2))) */ __MINGW_ATTRIB_NONNULL(1)
+  int __cdecl __mingw_wprintf_locked(const wchar_t * __restrict__ _Format,...);
+/* __attribute__((__format__ (gnu_wprintf, 2, 0))) */__MINGW_ATTRIB_NONNULL(2)
+  int __cdecl __mingw_vfwprintf_locked(FILE * __restrict__ _File,const wchar_t 
* __restrict__ _Format,va_list _ArgList);
+
+
 #if __USE_MINGW_ANSI_STDIO
 /*
  * User has expressed a preference for C99 conformance...
@@ -670,7 +693,11 @@ int fwprintf (FILE *__stream, const wchar_t *__format, ...)
 {
   register int __retval;
   __builtin_va_list __local_argv; __builtin_va_start( __local_argv, __format );
+#if defined(__MINGW_PRINTF_LOCKING)
+  __retval = __mingw_vfwprintf_locked( __stream, __format, __local_argv );
+#else
   __retval = __mingw_vfwprintf( __stream, __format, __local_argv );
+#endif
   __builtin_va_end( __local_argv );
   return __retval;
 }
@@ -690,7 +717,11 @@ __mingw_ovr
 /* __attribute__((__format__ (gnu_wprintf, 2, 0))) */ __MINGW_ATTRIB_NONNULL(2)
 int vfwprintf (FILE *__stream, const wchar_t *__format, __builtin_va_list 
__local_argv)
 {
+#if defined(__MINGW_PRINTF_LOCKING)
+  return __mingw_vfwprintf_locked( __stream, __format, __local_argv );
+#else
   return __mingw_vfwprintf( __stream, __format, __local_argv );
+#endif
 }
 
 __mingw_ovr

Attachment: 0xD4EBC740.asc
Description: application/pgp-keys

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to