| #define _CRTIMP | |
| #include <stdio.h> | |
| #include <synchapi.h> | |
| #include "internal.h" | |
| /*** | |
| * Copy of MS functions _lock_file, _unlock_file which are missing from | |
| * msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio | |
| * functions (printf, fprintf, vprintf, vfprintf). We need exactly the same | |
| * lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with | |
| * original MS functions (puts, fputs for example). | |
| ***/ | |
| _CRTIMP void __cdecl _lock(int locknum); | |
| _CRTIMP void __cdecl _unlock(int locknum); | |
| #define _STREAM_LOCKS 16 | |
| #define _IOLOCKED 0x8000 | |
| /*** | |
| * _lock_file - Lock a FILE | |
| * | |
| *Purpose: | |
| * Assert the lock for a stdio-level file | |
| * | |
| *Entry: | |
| * pf = __piob[] entry (pointer to a FILE or _FILEX) | |
| * | |
| *Exit: | |
| * | |
| *Exceptions: | |
| * | |
| *******************************************************************************/ | |
| void __cdecl _lock_file( FILE *pf ) | |
| { | |
| /* | |
| * The way the FILE (pointed to by pf) is locked depends on whether | |
| * it is part of _iob[] or not | |
| */ | |
| if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) | |
| { | |
| /* | |
| * FILE lies in _iob[] so the lock lies in _locktable[]. | |
| */ | |
| _lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); | |
| /* We set _IOLOCKED to indicate we locked the stream */ | |
| pf->_flag |= _IOLOCKED; | |
| } | |
| else | |
| /* | |
| * Not part of _iob[]. Therefore, *pf is a _FILEX and the | |
| * lock field of the struct is an initialized critical | |
| * section. | |
| */ | |
| EnterCriticalSection( &(((_FILEX *)pf)->lock) ); | |
| } | |
| void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file; | |
| /*** | |
| * _unlock_file - Unlock a FILE | |
| * | |
| *Purpose: | |
| * Release the lock for a stdio-level file | |
| * | |
| *Entry: | |
| * pf = __piob[] entry (pointer to a FILE or _FILEX) | |
| * | |
| *Exit: | |
| * | |
| *Exceptions: | |
| * | |
| *******************************************************************************/ | |
| void __cdecl _unlock_file( FILE *pf ) | |
| { | |
| /* | |
| * The way the FILE (pointed to by pf) is unlocked depends on whether | |
| * it is part of _iob[] or not | |
| */ | |
| if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) | |
| { | |
| /* | |
| * FILE lies in _iob[] so the lock lies in _locktable[]. | |
| * We reset _IOLOCKED to indicate we unlock the stream. | |
| */ | |
| pf->_flag &= ~_IOLOCKED; | |
| _unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); | |
| } | |
| else | |
| /* | |
| * Not part of _iob[]. Therefore, *pf is a _FILEX and the | |
| * lock field of the struct is an initialized critical | |
| * section. | |
| */ | |
| LeaveCriticalSection( &(((_FILEX *)pf)->lock) ); | |
| } | |
| void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file; |