1 #define _CRTIMP 2 #include <stdio.h> 3 #include <synchapi.h> 4 #include "internal.h" 5 6 /*** 7 * Copy of MS functions _lock_file, _unlock_file which are missing from 8 * msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio 9 * functions (printf, fprintf, vprintf, vfprintf). We need exactly the same 10 * lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with 11 * original MS functions (puts, fputs for example). 12 ***/ 13 14 15 _CRTIMP void __cdecl _lock(int locknum); 16 _CRTIMP void __cdecl _unlock(int locknum); 17 #define _STREAM_LOCKS 16 18 #define _IOLOCKED 0x8000 19 20 21 /*** 22 * _lock_file - Lock a FILE 23 * 24 *Purpose: 25 * Assert the lock for a stdio-level file 26 * 27 *Entry: 28 * pf = __piob[] entry (pointer to a FILE or _FILEX) 29 * 30 *Exit: 31 * 32 *Exceptions: 33 * 34 *******************************************************************************/ 35 _lock_file(FILE * pf)36void __cdecl _lock_file( FILE *pf ) 37 { 38 /* 39 * The way the FILE (pointed to by pf) is locked depends on whether 40 * it is part of _iob[] or not 41 */ 42 if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) 43 { 44 /* 45 * FILE lies in _iob[] so the lock lies in _locktable[]. 46 */ 47 _lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); 48 /* We set _IOLOCKED to indicate we locked the stream */ 49 pf->_flag |= _IOLOCKED; 50 } 51 else 52 /* 53 * Not part of _iob[]. Therefore, *pf is a _FILEX and the 54 * lock field of the struct is an initialized critical 55 * section. 56 */ 57 EnterCriticalSection( &(((_FILEX *)pf)->lock) ); 58 } 59 60 void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file; 61 62 63 /*** 64 * _unlock_file - Unlock a FILE 65 * 66 *Purpose: 67 * Release the lock for a stdio-level file 68 * 69 *Entry: 70 * pf = __piob[] entry (pointer to a FILE or _FILEX) 71 * 72 *Exit: 73 * 74 *Exceptions: 75 * 76 *******************************************************************************/ 77 _unlock_file(FILE * pf)78void __cdecl _unlock_file( FILE *pf ) 79 { 80 /* 81 * The way the FILE (pointed to by pf) is unlocked depends on whether 82 * it is part of _iob[] or not 83 */ 84 if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) 85 { 86 /* 87 * FILE lies in _iob[] so the lock lies in _locktable[]. 88 * We reset _IOLOCKED to indicate we unlock the stream. 89 */ 90 pf->_flag &= ~_IOLOCKED; 91 _unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); 92 } 93 else 94 /* 95 * Not part of _iob[]. Therefore, *pf is a _FILEX and the 96 * lock field of the struct is an initialized critical 97 * section. 98 */ 99 LeaveCriticalSection( &(((_FILEX *)pf)->lock) ); 100 } 101 102 void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file; 103