• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)36 void __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)78 void __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