blob: e62fe030502f6b175aa4d7695fb3e2cfd1c8009a [file] [log] [blame]
#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 >= (&__iob_func()[0])) && (pf <= (&__iob_func()[_IOB_ENTRIES-1])) )
{
/*
* FILE lies in _iob[] so the lock lies in _locktable[].
*/
_lock( _STREAM_LOCKS + (int)(pf - (&__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) );
}
/***
* _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 >= (&__iob_func()[0])) && (pf <= (&__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 - (&__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) );
}