2 * Win32 critical sections
4 * Copyright 1998 Alexandre Julliard
10 #include <sys/types.h>
21 /* On some systems this is supposed to be defined in the program */
22 #ifndef HAVE_UNION_SEMUN
31 /***********************************************************************
32 * InitializeCriticalSection (KERNEL32.472) (NTDLL.406)
34 void WINAPI InitializeCriticalSection( CRITICAL_SECTION *crit )
37 crit->RecursionCount = 0;
38 crit->OwningThread = 0;
39 crit->LockSemaphore = 0;
42 crit->LockSemaphore = CreateSemaphore32A( NULL, 0, 1, NULL );
43 crit->Reserved = (DWORD)-1;
48 crit->Reserved = (DWORD)semget( IPC_PRIVATE, 1, IPC_CREAT | 0777 );
49 if (crit->Reserved == (DWORD)-1)
55 semctl( (int)crit->Reserved, 0, SETVAL, val );
60 /***********************************************************************
61 * DeleteCriticalSection (KERNEL32.185) (NTDLL.327)
63 void WINAPI DeleteCriticalSection( CRITICAL_SECTION *crit )
65 if (crit->LockSemaphore)
67 if (crit->RecursionCount) /* Should not happen */
68 MSG("Deleting owned critical section (%p)\n", crit );
70 crit->RecursionCount = 0;
71 crit->OwningThread = 0;
72 CloseHandle( crit->LockSemaphore );
73 crit->LockSemaphore = 0;
75 else if (crit->Reserved != (DWORD)-1)
77 semctl( (int)crit->Reserved, 0, IPC_RMID, (union semun)0 );
82 /***********************************************************************
83 * EnterCriticalSection (KERNEL32.195) (NTDLL.344)
85 void WINAPI EnterCriticalSection( CRITICAL_SECTION *crit )
87 if ( (crit->Reserved==-1) && !(crit->LockSemaphore) &&
88 (crit!=HEAP_SystemLock)
90 FIXME(win32,"entering uninitialized section(%p)?\n",crit);
91 InitializeCriticalSection(crit);
93 if (InterlockedIncrement( &crit->LockCount ))
95 if (crit->OwningThread == GetCurrentThreadId())
97 crit->RecursionCount++;
100 /* Now wait for it */
101 if (crit->LockSemaphore)
103 /* FIXME: should set a timeout and raise an exception */
104 WaitForSingleObject( crit->LockSemaphore, INFINITE32 );
106 else if (crit->Reserved != (DWORD)-1)
112 sop.sem_flg = 0/*SEM_UNDO*/;
115 ret = semop( (int)crit->Reserved, &sop, 1 );
116 } while ((ret == -1) && (errno == EINTR));
120 MSG( "Uninitialized critical section (%p)\n", crit );
124 crit->OwningThread = GetCurrentThreadId();
125 crit->RecursionCount = 1;
129 /***********************************************************************
130 * TryEnterCriticalSection (KERNEL32.898) (NTDLL.969)
132 BOOL32 WINAPI TryEnterCriticalSection( CRITICAL_SECTION *crit )
134 if (InterlockedIncrement( &crit->LockCount ))
136 if (crit->OwningThread == GetCurrentThreadId())
138 crit->RecursionCount++;
141 /* FIXME: this doesn't work */
142 InterlockedDecrement( &crit->LockCount );
145 crit->OwningThread = GetCurrentThreadId();
146 crit->RecursionCount = 1;
151 /***********************************************************************
152 * LeaveCriticalSection (KERNEL32.494) (NTDLL.426)
154 void WINAPI LeaveCriticalSection( CRITICAL_SECTION *crit )
156 if (crit->OwningThread != GetCurrentThreadId()) return;
158 if (--crit->RecursionCount)
160 InterlockedDecrement( &crit->LockCount );
163 crit->OwningThread = 0;
164 if (InterlockedDecrement( &crit->LockCount ) >= 0)
166 /* Someone is waiting */
167 if (crit->LockSemaphore)
169 ReleaseSemaphore( crit->LockSemaphore, 1, NULL );
171 else if (crit->Reserved != (DWORD)-1)
176 sop.sem_flg = 0/*SEM_UNDO*/;
177 semop( (int)crit->Reserved, &sop, 1 );
183 /***********************************************************************
184 * MakeCriticalSectionGlobal (KERNEL32.515)
186 void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
188 crit->LockSemaphore = ConvertToGlobalHandle( crit->LockSemaphore );
192 /***********************************************************************
193 * ReinitializeCriticalSection (KERNEL32.581)
195 void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
197 DeleteCriticalSection( crit );
198 InitializeCriticalSection( crit );