Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
baa15566
Commit
baa15566
authored
Sep 29, 2000
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved critical section implementation to ntdll.
parent
15bfcd03
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
315 additions
and
164 deletions
+315
-164
kernel32.spec
dlls/kernel/kernel32.spec
+4
-4
Makefile.in
dlls/ntdll/Makefile.in
+4
-1
critsection.c
dlls/ntdll/critsection.c
+272
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+5
-5
ntddk.h
include/ntddk.h
+7
-0
winbase.h
include/winbase.h
+14
-2
critsection.c
scheduler/critsection.c
+9
-152
No files found.
dlls/kernel/kernel32.spec
View file @
baa15566
...
...
@@ -201,7 +201,7 @@ import ntdll.dll
182 stdcall DefineDosDeviceA(long str str) DefineDosDeviceA
183 stub DefineDosDeviceW
184 stdcall DeleteAtom(long) DeleteAtom
185
stdcall DeleteCriticalSection(ptr)
DeleteCriticalSection
185
forward DeleteCriticalSection ntdll.Rtl
DeleteCriticalSection
186 stdcall DeleteFileA(str) DeleteFileA
187 stdcall DeleteFileW(wstr) DeleteFileW
188 stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) DeviceIoControl
...
...
@@ -211,7 +211,7 @@ import ntdll.dll
192 stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle
193 stub EndUpdateResourceA
194 stub EndUpdateResourceW
195
stdcall EnterCriticalSection(ptr)
EnterCriticalSection
195
forward EnterCriticalSection ntdll.Rtl
EnterCriticalSection
196 stdcall EnumCalendarInfoA(ptr long long long) EnumCalendarInfoA
197 stub EnumCalendarInfoW
198 stdcall EnumDateFormatsA(ptr long long) EnumDateFormatsA
...
...
@@ -510,7 +510,7 @@ import ntdll.dll
491 register K32Thk1632Prolog() K32Thk1632Prolog
492 stdcall LCMapStringA(long long str long ptr long) LCMapStringA
493 stdcall LCMapStringW(long long wstr long ptr long) LCMapStringW
494
stdcall LeaveCriticalSection(ptr)
LeaveCriticalSection
494
forward LeaveCriticalSection ntdll.Rtl
LeaveCriticalSection
495 stdcall LoadLibraryA(str) LoadLibraryA
496 stdcall LoadLibraryExA( str long long) LoadLibraryExA
497 stdcall LoadLibraryExW(wstr long long) LoadLibraryExW
...
...
@@ -914,7 +914,7 @@ import ntdll.dll
895 stub SignalObjectAndWait
896 stub SwitchToFiber
897 stub SwitchToThread
898
stdcall TryEnterCriticalSection(ptr)
TryEnterCriticalSection
898
forward TryEnterCriticalSection ntdll.Rtl
TryEnterCriticalSection
899 stdcall VirtualAllocEx(long ptr long long long) VirtualAllocEx
900 stub VirtualFreeEx
901 stub WriteFileGather
...
...
dlls/ntdll/Makefile.in
View file @
baa15566
...
...
@@ -8,6 +8,7 @@ MODULE = ntdll
SPEC_SRCS
=
ntdll.spec
C_SRCS
=
\
critsection.c
\
exception.c
\
error.c
\
file.c
\
...
...
@@ -29,5 +30,7 @@ all: $(MODULE).o
@MAKE_RULES@
### Dependencies:
$(MODULE).o
:
$(OBJS) Makefile.in $(TOPSRCDIR)/Make.rules.in
$(LDCOMBINE)
$(OBJS)
-o
$@
### Dependencies:
dlls/ntdll/critsection.c
0 → 100644
View file @
baa15566
/*
* Win32 critical sections
*
* Copyright 1998 Alexandre Julliard
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include "winerror.h"
#include "ntddk.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL
(
ntdll
);
DECLARE_DEBUG_CHANNEL
(
relay
);
/* Define the atomic exchange/inc/dec functions.
* These are available in kernel32.dll already,
* but we don't want to import kernel32 from ntdll.
*/
#ifdef __i386__
# ifdef __GNUC__
inline
static
PVOID
interlocked_cmpxchg
(
PVOID
*
dest
,
PVOID
xchg
,
PVOID
compare
)
{
PVOID
ret
;
__asm__
__volatile__
(
"lock; cmpxchgl %2,(%1)"
:
"=a"
(
ret
)
:
"r"
(
dest
),
"r"
(
xchg
),
"0"
(
compare
)
:
"memory"
);
return
ret
;
}
inline
static
LONG
interlocked_inc
(
PLONG
dest
)
{
LONG
ret
;
__asm__
__volatile__
(
"lock; xaddl %0,(%1)"
:
"=r"
(
ret
)
:
"r"
(
dest
),
"0"
(
1
)
:
"memory"
);
return
ret
+
1
;
}
inline
static
LONG
interlocked_dec
(
PLONG
dest
)
{
LONG
ret
;
__asm__
__volatile__
(
"lock; xaddl %0,(%1)"
:
"=r"
(
ret
)
:
"r"
(
dest
),
"0"
(
-
1
)
:
"memory"
);
return
ret
-
1
;
}
# else
/* __GNUC__ */
PVOID
WINAPI
interlocked_cmpxchg
(
PVOID
*
dest
,
PVOID
xchg
,
PVOID
compare
);
__ASM_GLOBAL_FUNC
(
interlocked_cmpxchg
,
"movl 12(%esp),%eax
\n\t
"
"movl 8(%esp),%ecx
\n\t
"
"movl 4(%esp),%edx
\n\t
"
"lock; cmpxchgl %ecx,(%edx)
\n\t
"
"ret $12"
);
LONG
WINAPI
interlocked_inc
(
PLONG
dest
);
__ASM_GLOBAL_FUNC
(
interlocked_inc
,
"movl 4(%esp),%edx
\n\t
"
"movl $1,%eax
\n\t
"
"lock; xaddl %eax,(%edx)
\n\t
"
"incl %eax
\n\t
"
"ret $4"
);
LONG
WINAPI
interlocked_dec
(
PLONG
dest
);
__ASM_GLOBAL_FUNC
(
interlocked_dec
,
"movl 4(%esp),%edx
\n\t
"
"movl $-1,%eax
\n\t
"
"lock; xaddl %eax,(%edx)
\n\t
"
"decl %eax
\n\t
"
"ret $4"
);
# endif
/* __GNUC__ */
#elif defined(__sparc__) && defined(__sun__)
/*
* As the earlier Sparc processors lack necessary atomic instructions,
* I'm simply falling back to the library-provided _lwp_mutex routines
* to ensure mutual exclusion in a way appropriate for the current
* architecture.
*
* FIXME: If we have the compare-and-swap instruction (Sparc v9 and above)
* we could use this to speed up the Interlocked operations ...
*/
#include <synch.h>
static
lwp_mutex_t
interlocked_mutex
=
DEFAULTMUTEX
;
static
PVOID
interlocked_cmpxchg
(
PVOID
*
dest
,
PVOID
xchg
,
PVOID
compare
)
{
_lwp_mutex_lock
(
&
interlocked_mutex
);
if
(
*
dest
==
compare
)
*
dest
=
xchg
;
else
compare
=
*
dest
;
_lwp_mutex_unlock
(
&
interlocked_mutex
);
return
compare
;
}
static
LONG
interlocked_inc
(
PLONG
dest
)
{
LONG
retv
;
_lwp_mutex_lock
(
&
interlocked_mutex
);
retv
=
++*
dest
;
_lwp_mutex_unlock
(
&
interlocked_mutex
);
return
retv
;
}
static
LONG
interlocked_dec
(
PLONG
dest
)
{
LONG
retv
;
_lwp_mutex_lock
(
&
interlocked_mutex
);
retv
=
--*
dest
;
_lwp_mutex_unlock
(
&
interlocked_mutex
);
return
retv
;
}
#else
# error You must implement the interlocked* functions for your CPU
#endif
/***********************************************************************
* get_semaphore
*/
static
inline
HANDLE
get_semaphore
(
RTL_CRITICAL_SECTION
*
crit
)
{
HANDLE
ret
=
crit
->
LockSemaphore
;
if
(
!
ret
)
{
HANDLE
sem
;
if
(
NtCreateSemaphore
(
&
sem
,
SEMAPHORE_ALL_ACCESS
,
NULL
,
0
,
1
))
return
0
;
if
(
!
(
ret
=
(
HANDLE
)
InterlockedCompareExchange
(
(
PVOID
*
)
&
crit
->
LockSemaphore
,
(
PVOID
)
sem
,
0
)))
ret
=
sem
;
else
NtClose
(
sem
);
/* somebody beat us to it */
}
return
ret
;
}
/***********************************************************************
* RtlInitializeCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlInitializeCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
crit
->
LockCount
=
-
1
;
crit
->
RecursionCount
=
0
;
crit
->
OwningThread
=
0
;
crit
->
LockSemaphore
=
0
;
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RtlDeleteCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlDeleteCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
crit
->
LockCount
=
-
1
;
crit
->
RecursionCount
=
0
;
crit
->
OwningThread
=
0
;
if
(
crit
->
LockSemaphore
)
NtClose
(
crit
->
LockSemaphore
);
crit
->
LockSemaphore
=
0
;
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RtlpWaitForCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlpWaitForCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
for
(;;)
{
EXCEPTION_RECORD
rec
;
HANDLE
sem
=
get_semaphore
(
crit
);
DWORD
res
=
WaitForSingleObject
(
sem
,
5000L
);
if
(
res
==
WAIT_TIMEOUT
)
{
ERR
(
"Critical section %p wait timed out, retrying (60 sec)
\n
"
,
crit
);
res
=
WaitForSingleObject
(
sem
,
60000L
);
if
(
res
==
WAIT_TIMEOUT
&&
TRACE_ON
(
relay
)
)
{
ERR
(
"Critical section %p wait timed out, retrying (5 min)
\n
"
,
crit
);
res
=
WaitForSingleObject
(
sem
,
300000L
);
}
}
if
(
res
==
STATUS_WAIT_0
)
return
STATUS_SUCCESS
;
rec
.
ExceptionCode
=
EXCEPTION_CRITICAL_SECTION_WAIT
;
rec
.
ExceptionFlags
=
0
;
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionAddress
=
RtlRaiseException
;
/* sic */
rec
.
NumberParameters
=
1
;
rec
.
ExceptionInformation
[
0
]
=
(
DWORD
)
crit
;
RtlRaiseException
(
&
rec
);
}
}
/***********************************************************************
* RtlpUnWaitCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlpUnWaitCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
HANDLE
sem
=
get_semaphore
(
crit
);
NTSTATUS
res
=
NtReleaseSemaphore
(
sem
,
1
,
NULL
);
if
(
res
)
RtlRaiseStatus
(
res
);
return
res
;
}
/***********************************************************************
* RtlEnterCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlEnterCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
if
(
interlocked_inc
(
&
crit
->
LockCount
))
{
if
(
crit
->
OwningThread
==
GetCurrentThreadId
())
{
crit
->
RecursionCount
++
;
return
STATUS_SUCCESS
;
}
/* Now wait for it */
RtlpWaitForCriticalSection
(
crit
);
}
crit
->
OwningThread
=
GetCurrentThreadId
();
crit
->
RecursionCount
=
1
;
return
STATUS_SUCCESS
;
}
/***********************************************************************
* RtlTryEnterCriticalSection (NTDLL.@)
*/
BOOL
WINAPI
RtlTryEnterCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
BOOL
ret
=
FALSE
;
if
(
interlocked_cmpxchg
(
(
PVOID
*
)
&
crit
->
LockCount
,
(
PVOID
)
0L
,
(
PVOID
)
-
1L
)
==
(
PVOID
)
-
1L
)
{
crit
->
OwningThread
=
GetCurrentThreadId
();
crit
->
RecursionCount
=
1
;
ret
=
TRUE
;
}
else
if
(
crit
->
OwningThread
==
GetCurrentThreadId
())
{
interlocked_inc
(
&
crit
->
LockCount
);
crit
->
RecursionCount
++
;
ret
=
TRUE
;
}
return
ret
;
}
/***********************************************************************
* RtlLeaveCriticalSection (NTDLL.@)
*/
NTSTATUS
WINAPI
RtlLeaveCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
)
{
if
(
--
crit
->
RecursionCount
)
interlocked_dec
(
&
crit
->
LockCount
);
else
{
crit
->
OwningThread
=
0
;
if
(
interlocked_dec
(
&
crit
->
LockCount
)
>=
0
)
{
/* someone is waiting */
RtlpUnWaitCriticalSection
(
crit
);
}
}
return
STATUS_SUCCESS
;
}
dlls/ntdll/ntdll.spec
View file @
baa15566
...
...
@@ -331,7 +331,7 @@ type win32
@ stub RtlDecompressFragment
@ stub RtlDelete
@ stub RtlDeleteAce
@ stdcall RtlDeleteCriticalSection(ptr) DeleteCriticalSection
@ stdcall RtlDeleteCriticalSection(ptr)
Rtl
DeleteCriticalSection
@ stub RtlDeleteElementGenericTable
@ stub RtlDeleteRegistryValue
@ stdcall RtlDeleteResource(ptr) RtlDeleteResource
...
...
@@ -348,7 +348,7 @@ type win32
@ stub RtlEnlargedIntegerMultiply
@ stub RtlEnlargedUnsignedDivide
@ stub RtlEnlargedUnsignedMultiply
@ stdcall RtlEnterCriticalSection(ptr) EnterCriticalSection
@ stdcall RtlEnterCriticalSection(ptr)
Rtl
EnterCriticalSection
@ stub RtlEnumProcessHeaps
@ stub RtlEnumerateGenericTable
@ stub RtlEnumerateGenericTableWithoutSplaying
...
...
@@ -410,7 +410,7 @@ type win32
@ stdcall RtlInitUnicodeString(ptr wstr) RtlInitUnicodeString
@ stdcall RtlInitializeBitMap(long long long) RtlInitializeBitMap
@ stub RtlInitializeContext
@ stdcall RtlInitializeCriticalSection(ptr) InitializeCriticalSection
@ stdcall RtlInitializeCriticalSection(ptr)
Rtl
InitializeCriticalSection
@ stdcall RtlInitializeGenericTable() RtlInitializeGenericTable
@ stub RtlInitializeRXact
@ stdcall RtlInitializeResource(ptr) RtlInitializeResource
...
...
@@ -430,7 +430,7 @@ type win32
@ stub RtlLargeIntegerShiftRight
@ stub RtlLargeIntegerSubtract
@ stub RtlLargeIntegerToChar
@ stdcall RtlLeaveCriticalSection(ptr) LeaveCriticalSection
@ stdcall RtlLeaveCriticalSection(ptr)
Rtl
LeaveCriticalSection
@ stdcall RtlLengthRequiredSid(long) RtlLengthRequiredSid
@ stdcall RtlLengthSecurityDescriptor(ptr) RtlLengthSecurityDescriptor
@ stdcall RtlLengthSid(ptr) RtlLengthSid
...
...
@@ -973,7 +973,7 @@ type win32
@ stub RtlIsValidHandle
@ stub RtlLookupAtomInAtomTable
@ stub RtlQueryAtomInAtomTable
@ stdcall RtlTryEnterCriticalSection(ptr) TryEnterCriticalSection
@ stdcall RtlTryEnterCriticalSection(ptr)
Rtl
TryEnterCriticalSection
@ stub RtlEnumerateProperties
@ stub RtlSetPropertyClassId
@ stub RtlSetPropertyNames
...
...
include/ntddk.h
View file @
baa15566
...
...
@@ -918,6 +918,13 @@ NTSTATUS WINAPI NtReleaseSemaphore( IN HANDLE SemaphoreHandle,
IN
ULONG
ReleaseCount
,
IN
PULONG
PreviousCount
);
NTSTATUS
WINAPI
RtlInitializeCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
NTSTATUS
WINAPI
RtlDeleteCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
NTSTATUS
WINAPI
RtlpWaitForCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
NTSTATUS
WINAPI
RtlpUnWaitCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
NTSTATUS
WINAPI
RtlEnterCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
BOOL
WINAPI
RtlTryEnterCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
NTSTATUS
WINAPI
RtlLeaveCriticalSection
(
RTL_CRITICAL_SECTION
*
crit
);
/* string functions */
extern
LPSTR
_strlwr
(
LPSTR
str
);
...
...
include/winbase.h
View file @
baa15566
...
...
@@ -1206,13 +1206,25 @@ BOOL WINAPI GetVersionExW(OSVERSIONINFOW*);
/*int WinMain(HINSTANCE, HINSTANCE prev, char *cmd, int show);*/
LONG
WINAPI
RtlEnterCriticalSection
(
CRITICAL_SECTION
*
crit
);
LONG
WINAPI
RtlLeaveCriticalSection
(
CRITICAL_SECTION
*
crit
);
LONG
WINAPI
RtlDeleteCriticalSection
(
CRITICAL_SECTION
*
crit
);
BOOL
WINAPI
RtlTryEnterCriticalSection
(
CRITICAL_SECTION
*
crit
);
/* FIXME: need to use defines because we don't have proper imports yet */
#define EnterCriticalSection(crit) RtlEnterCriticalSection(crit)
#define LeaveCriticalSection(crit) RtlLeaveCriticalSection(crit)
#define DeleteCriticalSection(crit) RtlDeleteCriticalSection(crit)
#define TryEnterCriticalSection(crit) RtlTryEnterCriticalSection(crit)
#if 0
void WINAPI DeleteCriticalSection(CRITICAL_SECTION *lpCrit);
void WINAPI EnterCriticalSection(CRITICAL_SECTION *lpCrit);
BOOL WINAPI TryEnterCriticalSection(CRITICAL_SECTION *lpCrit);
void
WINAPI
InitializeCriticalSection
(
CRITICAL_SECTION
*
lpCrit
);
void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit);
#endif
void
WINAPI
InitializeCriticalSection
(
CRITICAL_SECTION
*
lpCrit
);
void
WINAPI
MakeCriticalSectionGlobal
(
CRITICAL_SECTION
*
lpCrit
);
BOOL
WINAPI
GetProcessWorkingSetSize
(
HANDLE
,
LPDWORD
,
LPDWORD
);
BOOL
WINAPI
GetProcessWorkingSetSize
(
HANDLE
,
LPDWORD
,
LPDWORD
);
DWORD
WINAPI
QueueUserAPC
(
PAPCFUNC
,
HANDLE
,
ULONG_PTR
);
void
WINAPI
RaiseException
(
DWORD
,
DWORD
,
DWORD
,
const
LPDWORD
);
BOOL
WINAPI
SetProcessWorkingSetSize
(
HANDLE
,
DWORD
,
DWORD
);
...
...
scheduler/critsection.c
View file @
baa15566
...
...
@@ -19,166 +19,23 @@ DEFAULT_DEBUG_CHANNEL(win32);
DECLARE_DEBUG_CHANNEL
(
relay
);
/***********************************************************************
* get_semaphore
*/
static
inline
HANDLE
get_semaphore
(
CRITICAL_SECTION
*
crit
)
{
HANDLE
ret
=
crit
->
LockSemaphore
;
if
(
!
ret
)
{
HANDLE
sem
=
CreateSemaphoreA
(
NULL
,
0
,
1
,
NULL
);
if
(
!
(
ret
=
(
HANDLE
)
InterlockedCompareExchange
(
(
PVOID
*
)
&
crit
->
LockSemaphore
,
(
PVOID
)
sem
,
0
)))
ret
=
sem
;
else
CloseHandle
(
sem
);
/* somebody beat us to it */
}
return
ret
;
}
/***********************************************************************
* InitializeCriticalSection (KERNEL32.472) (NTDLL.406)
* InitializeCriticalSection (KERNEL32.472)
*/
void
WINAPI
InitializeCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
crit
->
LockCount
=
-
1
;
crit
->
RecursionCount
=
0
;
crit
->
OwningThread
=
0
;
crit
->
LockSemaphore
=
0
;
}
/***********************************************************************
* DeleteCriticalSection (KERNEL32.185) (NTDLL.327)
*/
void
WINAPI
DeleteCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
if
(
crit
->
RecursionCount
&&
crit
->
OwningThread
!=
GetCurrentThreadId
())
ERR
(
"Deleting owned critical section (%p)
\n
"
,
crit
);
crit
->
LockCount
=
-
1
;
crit
->
RecursionCount
=
0
;
crit
->
OwningThread
=
0
;
if
(
crit
->
LockSemaphore
)
CloseHandle
(
crit
->
LockSemaphore
);
crit
->
LockSemaphore
=
0
;
}
/***********************************************************************
* RtlpWaitForCriticalSection (NTDLL.@)
*/
void
WINAPI
RtlpWaitForCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
for
(;;)
{
EXCEPTION_RECORD
rec
;
HANDLE
sem
=
get_semaphore
(
crit
);
DWORD
res
=
WaitForSingleObject
(
sem
,
5000L
);
if
(
res
==
WAIT_TIMEOUT
)
{
ERR
(
"Critical section %p wait timed out, retrying (60 sec)
\n
"
,
crit
);
res
=
WaitForSingleObject
(
sem
,
60000L
);
if
(
res
==
WAIT_TIMEOUT
&&
TRACE_ON
(
relay
)
)
{
ERR
(
"Critical section %p wait timed out, retrying (5 min)
\n
"
,
crit
);
res
=
WaitForSingleObject
(
sem
,
300000L
);
}
}
if
(
res
==
STATUS_WAIT_0
)
break
;
rec
.
ExceptionCode
=
EXCEPTION_CRITICAL_SECTION_WAIT
;
rec
.
ExceptionFlags
=
0
;
rec
.
ExceptionRecord
=
NULL
;
rec
.
ExceptionAddress
=
RtlRaiseException
;
/* sic */
rec
.
NumberParameters
=
1
;
rec
.
ExceptionInformation
[
0
]
=
(
DWORD
)
crit
;
RtlRaiseException
(
&
rec
);
}
}
/***********************************************************************
* RtlpUnWaitCriticalSection (NTDLL.@)
*/
void
WINAPI
RtlpUnWaitCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
HANDLE
sem
=
get_semaphore
(
crit
);
ReleaseSemaphore
(
sem
,
1
,
NULL
);
NTSTATUS
ret
=
RtlInitializeCriticalSection
(
crit
);
if
(
ret
)
RtlRaiseStatus
(
ret
);
}
/***********************************************************************
* EnterCriticalSection (KERNEL32.195) (NTDLL.344)
*/
void
WINAPI
EnterCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
if
(
InterlockedIncrement
(
&
crit
->
LockCount
))
{
if
(
crit
->
OwningThread
==
GetCurrentThreadId
())
{
crit
->
RecursionCount
++
;
return
;
}
/* Now wait for it */
RtlpWaitForCriticalSection
(
crit
);
}
crit
->
OwningThread
=
GetCurrentThreadId
();
crit
->
RecursionCount
=
1
;
}
/***********************************************************************
* TryEnterCriticalSection (KERNEL32.898) (NTDLL.969)
*/
BOOL
WINAPI
TryEnterCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
BOOL
ret
=
FALSE
;
if
(
InterlockedCompareExchange
(
(
PVOID
*
)
&
crit
->
LockCount
,
(
PVOID
)
0L
,
(
PVOID
)
-
1L
)
==
(
PVOID
)
-
1L
)
{
crit
->
OwningThread
=
GetCurrentThreadId
();
crit
->
RecursionCount
=
1
;
ret
=
TRUE
;
}
else
if
(
crit
->
OwningThread
==
GetCurrentThreadId
())
{
InterlockedIncrement
(
&
crit
->
LockCount
);
crit
->
RecursionCount
++
;
ret
=
TRUE
;
}
return
ret
;
}
/***********************************************************************
* LeaveCriticalSection (KERNEL32.494) (NTDLL.426)
*/
void
WINAPI
LeaveCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
if
(
crit
->
OwningThread
!=
GetCurrentThreadId
())
return
;
if
(
--
crit
->
RecursionCount
)
{
InterlockedDecrement
(
&
crit
->
LockCount
);
return
;
}
crit
->
OwningThread
=
0
;
if
(
InterlockedDecrement
(
&
crit
->
LockCount
)
>=
0
)
{
/* Someone is waiting */
RtlpUnWaitCriticalSection
(
crit
);
}
}
/***********************************************************************
* MakeCriticalSectionGlobal (KERNEL32.515)
*/
void
WINAPI
MakeCriticalSectionGlobal
(
CRITICAL_SECTION
*
crit
)
{
crit
->
LockSemaphore
=
ConvertToGlobalHandle
(
get_semaphore
(
crit
)
);
/* let's assume that only one thread at a time will try to do this */
HANDLE
sem
=
crit
->
LockSemaphore
;
if
(
!
sem
)
sem
=
CreateSemaphoreA
(
NULL
,
0
,
1
,
NULL
);
crit
->
LockSemaphore
=
ConvertToGlobalHandle
(
sem
);
}
...
...
@@ -188,7 +45,7 @@ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
void
WINAPI
ReinitializeCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
if
(
!
crit
->
LockSemaphore
)
InitializeCriticalSection
(
crit
);
Rtl
InitializeCriticalSection
(
crit
);
}
...
...
@@ -197,7 +54,7 @@ void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
*/
void
WINAPI
UninitializeCriticalSection
(
CRITICAL_SECTION
*
crit
)
{
DeleteCriticalSection
(
crit
);
Rtl
DeleteCriticalSection
(
crit
);
}
#ifdef __i386__
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment