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
);