2 * Win32 critical sections
4 * Copyright 1998 Alexandre Julliard
10 #include <sys/types.h>
18 DEFAULT_DEBUG_CHANNEL(win32
)
21 /***********************************************************************
22 * InitializeCriticalSection (KERNEL32.472) (NTDLL.406)
24 void WINAPI
InitializeCriticalSection( CRITICAL_SECTION
*crit
)
27 crit
->RecursionCount
= 0;
28 crit
->OwningThread
= 0;
29 crit
->LockSemaphore
= 0;
30 crit
->LockSemaphore
= CreateSemaphoreA( NULL
, 0, 1, NULL
);
31 crit
->Reserved
= (DWORD
)-1;
35 /***********************************************************************
36 * DeleteCriticalSection (KERNEL32.185) (NTDLL.327)
38 void WINAPI
DeleteCriticalSection( CRITICAL_SECTION
*crit
)
40 if (crit
->LockSemaphore
)
42 if (crit
->RecursionCount
) /* Should not happen */
43 MSG("Deleting owned critical section (%p)\n", crit
);
45 crit
->RecursionCount
= 0;
46 crit
->OwningThread
= 0;
47 CloseHandle( crit
->LockSemaphore
);
48 crit
->LockSemaphore
= 0;
53 /***********************************************************************
54 * EnterCriticalSection (KERNEL32.195) (NTDLL.344)
56 void WINAPI
EnterCriticalSection( CRITICAL_SECTION
*crit
)
60 if (!crit
->LockSemaphore
)
62 FIXME(win32
,"entering uninitialized section(%p)?\n",crit
);
63 InitializeCriticalSection(crit
);
65 if (InterlockedIncrement( &crit
->LockCount
))
67 if (crit
->OwningThread
== GetCurrentThreadId())
69 crit
->RecursionCount
++;
74 res
= WaitForSingleObject( crit
->LockSemaphore
, 2000 );
75 if (res
== STATUS_TIMEOUT
) res
= WaitForSingleObject( crit
->LockSemaphore
, 2000 );
76 if (res
!= STATUS_WAIT_0
)
78 ERR(win32
, "Critical section %p wait failed err=%lx\n", crit
, res
);
79 /* FIXME: should raise an exception */
82 crit
->OwningThread
= GetCurrentThreadId();
83 crit
->RecursionCount
= 1;
87 /***********************************************************************
88 * TryEnterCriticalSection (KERNEL32.898) (NTDLL.969)
90 BOOL WINAPI
TryEnterCriticalSection( CRITICAL_SECTION
*crit
)
92 if (InterlockedIncrement( &crit
->LockCount
))
94 if (crit
->OwningThread
== GetCurrentThreadId())
96 crit
->RecursionCount
++;
99 /* FIXME: this doesn't work */
100 InterlockedDecrement( &crit
->LockCount
);
103 crit
->OwningThread
= GetCurrentThreadId();
104 crit
->RecursionCount
= 1;
109 /***********************************************************************
110 * LeaveCriticalSection (KERNEL32.494) (NTDLL.426)
112 void WINAPI
LeaveCriticalSection( CRITICAL_SECTION
*crit
)
114 if (crit
->OwningThread
!= GetCurrentThreadId()) return;
116 if (--crit
->RecursionCount
)
118 InterlockedDecrement( &crit
->LockCount
);
121 crit
->OwningThread
= 0;
122 if (InterlockedDecrement( &crit
->LockCount
) >= 0)
124 /* Someone is waiting */
125 ReleaseSemaphore( crit
->LockSemaphore
, 1, NULL
);
130 /***********************************************************************
131 * MakeCriticalSectionGlobal (KERNEL32.515)
133 void WINAPI
MakeCriticalSectionGlobal( CRITICAL_SECTION
*crit
)
135 crit
->LockSemaphore
= ConvertToGlobalHandle( crit
->LockSemaphore
);
139 /***********************************************************************
140 * ReinitializeCriticalSection (KERNEL32.581)
142 void WINAPI
ReinitializeCriticalSection( CRITICAL_SECTION
*crit
)
144 DeleteCriticalSection( crit
);
145 InitializeCriticalSection( crit
);
149 /***********************************************************************
150 * UninitializeCriticalSection (KERNEL32.703)
152 void WINAPI
UninitializeCriticalSection( CRITICAL_SECTION
*crit
)
154 FIXME(win32
, "(%p) half a stub\n", crit
);
155 DeleteCriticalSection( crit
);