Add _lock,_unlock and header file for them.

Convert all msvcrt locks over to use _lock and _unlock.
Explicitly make msvcrt compile with multithreaded option.
Fix flag handling in _sopen. Add W->A call for new _swopen.
This commit is contained in:
Peter Hunnisett 2002-02-21 20:22:00 +00:00 committed by Alexandre Julliard
parent 22ad2d22b6
commit d1a79ea2eb
11 changed files with 300 additions and 77 deletions

View File

@ -1,4 +1,4 @@
EXTRADEFS = -DUSE_MSVCRT_PREFIX
EXTRADEFS = -DUSE_MSVCRT_PREFIX -D_MT
TOPSRCDIR = @top_srcdir@
TOPOBJDIR = ../..
SRCDIR = @srcdir@
@ -22,6 +22,7 @@ C_SRCS = \
file.c \
heap.c \
locale.c \
lock.c \
main.c \
math.c \
mbcs.c \

View File

@ -12,6 +12,7 @@
#include "msvcrt/conio.h"
#include "msvcrt/malloc.h"
#include "msvcrt/stdio.h"
#include "mtdll.h"
#include "wine/debug.h"
@ -20,9 +21,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_console_cs;
#define LOCK_CONSOLE EnterCriticalSection(&MSVCRT_console_cs)
#define UNLOCK_CONSOLE LeaveCriticalSection(&MSVCRT_console_cs)
#define LOCK_CONSOLE _mlock(_CONIO_LOCK)
#define UNLOCK_CONSOLE _munlock(_CONIO_LOCK)
static HANDLE MSVCRT_console_in = INVALID_HANDLE_VALUE;
static HANDLE MSVCRT_console_out= INVALID_HANDLE_VALUE;

View File

@ -7,16 +7,15 @@
#include "msvcrt/conio.h"
#include "msvcrt/stdlib.h"
#include "mtdll.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_exit_cs;
#define LOCK_EXIT EnterCriticalSection(&MSVCRT_exit_cs)
#define UNLOCK_EXIT LeaveCriticalSection(&MSVCRT_exit_cs)
#define LOCK_EXIT _mlock(_EXIT_LOCK1)
#define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
static _onexit_t *MSVCRT_atexit_table = NULL;
static int MSVCRT_atexit_table_size = 0;

View File

@ -24,6 +24,7 @@
#include "msvcrt/sys/stat.h"
#include "msvcrt/sys/utime.h"
#include "msvcrt/time.h"
#include "msvcrt/share.h"
#include "wine/debug.h"
@ -719,18 +720,23 @@ WCHAR *_wmktemp(WCHAR *pattern)
}
/*********************************************************************
* _open (MSVCRT.@)
* _sopen (MSVCRT.@)
*/
int _open(const char *path,int flags,...)
int MSVCRT__sopen( const char *path, int oflags, int shflags, ... )
{
va_list ap;
int pmode;
DWORD access = 0, creation = 0;
DWORD sharing;
int ioflag = 0, fd;
HANDLE hand;
SECURITY_ATTRIBUTES sa;
TRACE(":file (%s) mode 0x%04x\n",path,flags);
switch(flags & (_O_RDONLY | _O_WRONLY | _O_RDWR))
TRACE(":file (%s) oflags: 0x%04x shflags: 0x%04x\n",
path, oflags, shflags);
switch(oflags & (_O_RDONLY | _O_WRONLY | _O_RDWR))
{
case _O_RDONLY:
access |= GENERIC_READ;
@ -746,49 +752,73 @@ int _open(const char *path,int flags,...)
break;
}
if (flags & _O_CREAT)
if (oflags & _O_CREAT)
{
if (flags & _O_EXCL)
va_start(ap, shflags);
pmode = va_arg(ap, int);
va_end(ap);
FIXME(": pmode 0x%04x ignored\n", pmode);
if (oflags & _O_EXCL)
creation = CREATE_NEW;
else if (flags & _O_TRUNC)
else if (oflags & _O_TRUNC)
creation = CREATE_ALWAYS;
else
creation = OPEN_ALWAYS;
}
else /* no _O_CREAT */
{
if (flags & _O_TRUNC)
if (oflags & _O_TRUNC)
creation = TRUNCATE_EXISTING;
else
creation = OPEN_EXISTING;
}
if (flags & _O_APPEND)
if (oflags & _O_APPEND)
ioflag |= MSVCRT__IOAPPEND;
flags |= _O_BINARY; /* FIXME: Default to text */
oflags |= _O_BINARY; /* FIXME: Default to text */
if (flags & _O_TEXT)
if (oflags & _O_TEXT)
{
/* Dont warn when writing */
if (ioflag & GENERIC_READ)
FIXME(":TEXT node not implemented\n");
flags &= ~_O_TEXT;
oflags &= ~_O_TEXT;
}
if (flags & ~(_O_BINARY|_O_TEXT|_O_APPEND|_O_TRUNC|_O_EXCL
|_O_CREAT|_O_RDWR|_O_TEMPORARY))
TRACE(":unsupported flags 0x%04x\n",flags);
switch( shflags )
{
case _SH_DENYRW:
sharing = 0L;
break;
case _SH_DENYWR:
sharing = FILE_SHARE_READ;
break;
case _SH_DENYRD:
sharing = FILE_SHARE_WRITE;
break;
case _SH_DENYNO:
sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
break;
default:
ERR( "Unhandled shflags 0x%x\n", shflags );
return -1;
}
if (oflags & ~(_O_BINARY|_O_TEXT|_O_APPEND|_O_TRUNC|_O_EXCL
|_O_CREAT|_O_RDWR|_O_TEMPORARY|_O_NOINHERIT))
TRACE(":unsupported oflags 0x%04x\n",oflags);
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
sa.bInheritHandle = (oflags & _O_NOINHERIT) ? FALSE : TRUE;
hand = CreateFileA(path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
hand = CreateFileA(path, access, sharing,
&sa, creation, FILE_ATTRIBUTE_NORMAL, 0);
if (hand == INVALID_HANDLE_VALUE)
{
if (hand == INVALID_HANDLE_VALUE) {
WARN(":failed-last error (%ld)\n",GetLastError());
MSVCRT__set_errno(GetLastError());
return -1;
@ -800,7 +830,7 @@ int _open(const char *path,int flags,...)
if (fd > 0)
{
if (flags & _O_TEMPORARY)
if (oflags & _O_TEMPORARY)
MSVCRT_tempfiles[fd] = _strdup(path);
if (ioflag & MSVCRT__IOAPPEND)
_lseek(fd, 0, FILE_END);
@ -810,15 +840,22 @@ int _open(const char *path,int flags,...)
}
/*********************************************************************
* _wopen (MSVCRT.@)
* _wsopen (MSVCRT.@)
*/
int _wopen(const WCHAR *path,int flags,...)
int MSVCRT__wsopen( const WCHAR* path, int oflags, int shflags, ... )
{
const unsigned int len = strlenW(path);
char *patha = MSVCRT_calloc(len + 1,1);
va_list ap;
int pmode;
va_start(ap, shflags);
pmode = va_arg(ap, int);
va_end(ap);
if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL))
{
int retval = _open(patha,flags);
int retval = MSVCRT__sopen(patha,oflags,shflags,pmode);
MSVCRT_free(patha);
return retval;
}
@ -828,11 +865,43 @@ int _wopen(const WCHAR *path,int flags,...)
}
/*********************************************************************
* _sopen (MSVCRT.@)
* _open (MSVCRT.@)
*/
int MSVCRT__sopen(const char *path,int oflags,int shflags)
int _open( const char *path, int flags, ... )
{
return _open(path, oflags | shflags);
va_list ap;
int pmode;
va_start(ap, flags);
pmode = va_arg(ap, int);
va_end(ap);
return MSVCRT__sopen( path, flags, _SH_DENYNO, pmode );
}
/*********************************************************************
* _wopen (MSVCRT.@)
*/
int _wopen(const WCHAR *path,int flags,...)
{
const unsigned int len = strlenW(path);
char *patha = MSVCRT_calloc(len + 1,1);
va_list ap;
int pmode;
va_start(ap, flags);
pmode = va_arg(ap, int);
va_end(ap);
if (patha && WideCharToMultiByte(CP_ACP,0,path,len,patha,len,NULL,NULL))
{
int retval = _open(patha,flags,pmode);
MSVCRT_free(patha);
return retval;
}
MSVCRT__set_errno(GetLastError());
return -1;
}
/*********************************************************************

View File

@ -11,16 +11,16 @@
#include "ms_errno.h"
#include "msvcrt/malloc.h"
#include "mtdll.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* MT */
extern CRITICAL_SECTION MSVCRT_heap_cs;
#define LOCK_HEAP EnterCriticalSection(&MSVCRT_heap_cs)
#define UNLOCK_HEAP LeaveCriticalSection(&MSVCRT_heap_cs)
#define LOCK_HEAP _mlock( _HEAP_LOCK )
#define UNLOCK_HEAP _munlock( _HEAP_LOCK )
typedef void (*MSVCRT_new_handler_func)(unsigned long size);

View File

@ -9,6 +9,7 @@
#include "msvcrt.h"
#include "msvcrt/locale.h"
#include "mtdll.h"
#include "wine/debug.h"
@ -24,9 +25,8 @@ LCID MSVCRT_current_lc_all_lcid;
int MSVCRT_current_lc_all_cp;
/* MT */
extern CRITICAL_SECTION MSVCRT_locale_cs;
#define LOCK_LOCALE EnterCriticalSection(&MSVCRT_locale_cs)
#define UNLOCK_LOCALE LeaveCriticalSection(&MSVCRT_locale_cs)
#define LOCK_LOCALE _mlock(_SETLOCALE_LOCK);
#define UNLOCK_LOCALE _munlock(_SETLOCALE_LOCK);
/* ctype data modified when the locale changes */
extern WORD MSVCRT__ctype [257];

122
dlls/msvcrt/lock.c Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2002, TransGaming Technologies Inc.
*/
#include "mtdll.h"
#include "debugtools.h"
#include "winbase.h"
DEFAULT_DEBUG_CHANNEL(msvcrt);
typedef struct
{
BOOL bInit;
CRITICAL_SECTION crit;
} LOCKTABLEENTRY;
static LOCKTABLEENTRY lock_table[ _TOTAL_LOCKS ];
static inline void msvcrt_mlock_set_entry_initialized( int locknum, BOOL initialized )
{
lock_table[ locknum ].bInit = initialized;
}
static inline void msvcrt_initialize_mlock( int locknum )
{
InitializeCriticalSection( &(lock_table[ locknum ].crit) );
msvcrt_mlock_set_entry_initialized( locknum, TRUE );
}
static inline void msvcrt_uninitialize_mlock( int locknum )
{
DeleteCriticalSection( &(lock_table[ locknum ].crit) );
msvcrt_mlock_set_entry_initialized( locknum, FALSE );
}
/**********************************************************************
* msvcrt_init_mt_locks (internal)
*
* Initialize the table lock. All other locks will be initialized
* upon first use.
*
*/
void msvcrt_init_mt_locks(void)
{
int i;
TRACE( "initializing mtlocks\n" );
/* Initialize the table */
for( i=0; i < _TOTAL_LOCKS; i++ )
{
msvcrt_mlock_set_entry_initialized( i, FALSE );
}
/* Initialize our lock table lock */
msvcrt_initialize_mlock( _LOCKTAB_LOCK );
}
/**********************************************************************
* msvcrt_free_mt_locks (internal)
*
* Uninitialize all mt locks. Assume that neither _lock or _unlock will
* be called once we're calling this routine (ie _LOCKTAB_LOCK can be deleted)
*
*/
void msvcrt_free_mt_locks(void)
{
int i;
TRACE( ": uninitializing all mtlocks\n" );
/* Uninitialize the table */
for( i=0; i < _TOTAL_LOCKS; i++ )
{
if( lock_table[ i ].bInit == TRUE )
{
msvcrt_uninitialize_mlock( i );
}
}
}
/**********************************************************************
* _lock (MSVCRT.@)
*/
void _lock( int locknum )
{
TRACE( "(%d)\n", locknum );
/* If the lock doesn't exist yet, create it */
if( lock_table[ locknum ].bInit == FALSE )
{
/* Lock while we're changing the lock table */
_lock( _LOCKTAB_LOCK );
/* Check again if we've got a bit of a race on lock creation */
if( lock_table[ locknum ].bInit == FALSE )
{
TRACE( ": creating lock #%d\n", locknum );
msvcrt_initialize_mlock( locknum );
}
/* Unlock ourselves */
_unlock( _LOCKTAB_LOCK );
}
EnterCriticalSection( &(lock_table[ locknum ].crit) );
}
/**********************************************************************
* _unlock (MSVCRT.@)
*
* NOTE: There is no error detection to make sure the lock exists and is acquired.
*/
void _unlock( int locknum )
{
TRACE( "(%d)\n", locknum );
LeaveCriticalSection( &(lock_table[ locknum ].crit) );
}

View File

@ -8,7 +8,6 @@
#include "msvcrt/locale.h"
#include "msvcrt/stdio.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
@ -16,17 +15,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* Index to TLS */
DWORD MSVCRT_tls_index;
/* MT locks */
CRITICAL_SECTION MSVCRT_heap_cs;
CRITICAL_SECTION MSVCRT_file_cs;
CRITICAL_SECTION MSVCRT_exit_cs;
CRITICAL_SECTION MSVCRT_console_cs;
CRITICAL_SECTION MSVCRT_locale_cs;
static inline BOOL msvcrt_init_tls(void);
static inline BOOL msvcrt_free_tls(void);
static inline void msvcrt_init_critical_sections(void);
static inline void msvcrt_free_critical_sections(void);
const char* msvcrt_get_reason(DWORD reason) WINE_UNUSED;
void msvcrt_init_io(void);
@ -56,8 +46,8 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_ATTACH:
if (!msvcrt_init_tls())
return FALSE;
msvcrt_init_mt_locks();
msvcrt_init_vtables();
msvcrt_init_critical_sections();
msvcrt_init_io();
msvcrt_init_console();
msvcrt_init_args();
@ -77,7 +67,7 @@ BOOL WINAPI MSVCRT_Init(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
TRACE("finished thread init\n");
break;
case DLL_PROCESS_DETACH:
msvcrt_free_critical_sections();
msvcrt_free_mt_locks();
_fcloseall();
msvcrt_free_console();
msvcrt_free_args();
@ -123,24 +113,6 @@ static inline BOOL msvcrt_free_tls(void)
return TRUE;
}
static inline void msvcrt_init_critical_sections(void)
{
InitializeCriticalSectionAndSpinCount(&MSVCRT_heap_cs, 4000);
InitializeCriticalSection(&MSVCRT_file_cs);
InitializeCriticalSection(&MSVCRT_exit_cs);
InitializeCriticalSection(&MSVCRT_console_cs);
InitializeCriticalSection(&MSVCRT_locale_cs);
}
static inline void msvcrt_free_critical_sections(void)
{
DeleteCriticalSection(&MSVCRT_locale_cs);
DeleteCriticalSection(&MSVCRT_console_cs);
DeleteCriticalSection(&MSVCRT_exit_cs);
DeleteCriticalSection(&MSVCRT_file_cs);
DeleteCriticalSection(&MSVCRT_heap_cs);
}
const char* msvcrt_get_reason(DWORD reason)
{
switch (reason)

View File

@ -40,4 +40,8 @@ LPWSTR msvcrt_wstrndup(LPCWSTR, unsigned int);
*/
int MSVCRT__set_new_mode(int mode);
/* Setup and teardown multi threaded locks */
void msvcrt_init_mt_locks(void);
void msvcrt_free_mt_locks(void);
#endif /* __WINE_MSVCRT_H */

View File

@ -325,7 +325,7 @@ debug_channels (msvcrt)
@ cdecl _lfind(ptr ptr ptr long ptr) _lfind
@ cdecl _loaddll(str) _loaddll
@ cdecl _local_unwind2(ptr long) _local_unwind2
@ stub _lock
@ cdecl _lock(long) _lock
@ stub _locking #(long long long)
@ cdecl _logb( double ) _logb
@ stub _longjmpex
@ -441,7 +441,7 @@ debug_channels (msvcrt)
@ cdecl _sleep(long) _sleep
@ varargs _snprintf(str long str) snprintf
@ forward -noimport _snwprintf ntdll._snwprintf
@ cdecl _sopen(str long long) MSVCRT__sopen
@ varargs _sopen(str long long) MSVCRT__sopen
@ varargs _spawnl(long str str) _spawnl
@ stub _spawnle #(str str) varargs
@ varargs _spawnlp(long str str) _spawnlp
@ -488,7 +488,7 @@ debug_channels (msvcrt)
@ cdecl _ungetch(long) _ungetch
@ cdecl _unlink(str) _unlink
@ cdecl _unloaddll(long) _unloaddll
@ stub _unlock
@ cdecl _unlock(long) _unlock
@ cdecl _utime(str ptr) _utime
@ cdecl _vsnprintf(ptr long ptr ptr) vsnprintf
@ cdecl _vsnwprintf(ptr long wstr long) _vsnwprintf
@ -548,7 +548,7 @@ debug_channels (msvcrt)
@ cdecl _wrmdir(wstr) _wrmdir
@ stub _wsearchenv #(wstr wstr wstr)
@ stub _wsetlocale #(long wstr)
@ stub _wsopen #(wstr long long) varargs
@ varargs _wsopen (wstr long long) MSVCRT__wsopen
@ stub _wspawnl #(long wstr wstr) varargs
@ stub _wspawnle #(long wstr wstr) varargs
@ stub _wspawnlp #(long wstr wstr) varargs

56
dlls/msvcrt/mtdll.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef WINE_MTDLL_H
#define WINE_MTDLL_H
#if defined(_MT)
#define _mlock(locknum) _lock(locknum)
#define _munlock(locknum) _unlock(locknum)
void _unlock( int locknum );
void _lock( int locknum );
#else
#define _mlock(locknum) do {} while(0)
#define _munlock(locknum) do {} while(0)
#endif
#define _SIGNAL_LOCK 1
#define _IOB_SCAN_LOCK 2
#define _TMPNAM_LOCK 3
#define _INPUT_LOCK 4
#define _OUTPUT_LOCK 5
#define _CSCANF_LOCK 6
#define _CPRINTF_LOCK 7
#define _CONIO_LOCK 8
#define _HEAP_LOCK 9
#define _BHEAP_LOCK 10 /* No longer used? */
#define _TIME_LOCK 11
#define _ENV_LOCK 12
#define _EXIT_LOCK1 13
#define _EXIT_LOCK2 14 /* No longer used? */
#define _THREADDATA_LOCK 15 /* No longer used? */
#define _POPEN_LOCK 16
#define _LOCKTAB_LOCK 17
#define _OSFHND_LOCK 18
#define _SETLOCALE_LOCK 19
#define _LC_COLLATE_LOCK 20 /* No longer used? */
#define _LC_CTYPE_LOCK 21 /* No longer used? */
#define _LC_MONETARY_LOCK 22 /* No longer used? */
#define _LC_NUMERIC_LOCK 23 /* No longer used? */
#define _LC_TIME_LOCK 24 /* No longer used? */
#define _MB_CP_LOCK 25
#define _NLG_LOCK 26
#define _TYPEINFO_LOCK 27
#define _STREAM_LOCKS 28
/* Must match definition in msvcrt/stdio.h */
#define _IOB_ENTRIES 20
#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_IOB_ENTRIES-1)
#define _TOTAL_LOCKS (_LAST_STREAM_LOCK+1)
#endif /* WINE_MTDLL_H */