source: trunk/src/odincrt/critsect.cpp@ 8266

Last change on this file since 8266 was 8218, checked in by sandervl, 23 years ago

only shared for named critical section

File size: 4.7 KB
Line 
1/* $Id: critsect.cpp,v 1.2 2002-04-08 11:25:22 sandervl Exp $ */
2/*
3 * Critical sections
4 *
5 * Copyright 2002 Sander van Leeuwen (sandervl@xs4all.nl)
6 * OS/2 port
7 *
8 * Based on Wine code
9 *
10 * Copyright 1998 Alexandre Julliard (991031 Port)
11 *
12 *
13 */
14#define INCL_DOSPROCESS
15#define INCL_DOSERRORS
16#define INCL_DOSSEMAPHORES
17#include <os2wrap.h>
18#include <win32type.h>
19#include <win32api.h>
20
21#include <assert.h>
22#include <stdio.h>
23
24#include <odincrt.h>
25
26#ifdef DEBUG
27#define DebugInt3() _interrupt(3)
28#else
29#define DebugInt3()
30#endif
31
32#define MAKE_THREADID(processid, threadid) ((processid << 16) | threadid)
33
34//******************************************************************************
35//******************************************************************************
36inline ULONG GetCurrentThreadId()
37{
38 PTIB ptib;
39 PPIB ppib;
40 APIRET rc;
41
42 rc = DosGetInfoBlocks(&ptib, &ppib);
43 if(rc == NO_ERROR) {
44 return MAKE_THREADID(ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
45 }
46 DebugInt3();
47 return 0;
48}
49//******************************************************************************
50//******************************************************************************
51inline ULONG GetCurrentProcessId()
52{
53 PTIB ptib;
54 PPIB ppib;
55 APIRET rc;
56
57 rc = DosGetInfoBlocks(&ptib, &ppib);
58 if(rc == NO_ERROR) {
59 return ppib->pib_ulpid;
60 }
61 DebugInt3();
62 return 0;
63}
64
65/***********************************************************************
66 * DosInitializeCriticalSection
67 */
68VOID WIN32API DosInitializeCriticalSection(CRITICAL_SECTION_OS2 *crit, PSZ pszSemName)
69{
70 APIRET rc;
71
72 crit->LockCount = -1;
73 crit->RecursionCount = 0;
74 crit->OwningThread = 0;
75
76 rc = DosCreateMutexSem(pszSemName, &crit->hmtxLock, (pszSemName) ? DC_SEM_SHARED : 0, FALSE);
77 if(rc != NO_ERROR) {
78 DebugInt3();
79 crit->hmtxLock = 0;
80 }
81 crit->Reserved = GetCurrentProcessId();
82}
83
84
85/***********************************************************************
86 * DosAccessCriticalSection
87 */
88VOID WIN32API DosAccessCriticalSection(CRITICAL_SECTION_OS2 *, PSZ pszSemName)
89{
90 HMTX hmtxLock = 0;
91 APIRET rc;
92
93 if(pszSemName == NULL) {
94 DebugInt3();
95 return;
96 }
97
98 rc = DosOpenMutexSem(pszSemName, &hmtxLock);
99 if(rc != NO_ERROR) {
100 DebugInt3();
101 }
102}
103/***********************************************************************
104 * DosDeleteCriticalSection
105 */
106void WIN32API DosDeleteCriticalSection( CRITICAL_SECTION_OS2 *crit )
107{
108 if (crit->hmtxLock)
109 {
110 if (crit->RecursionCount) /* Should not happen */
111 {
112 DebugInt3();
113 }
114 crit->LockCount = -1;
115 crit->RecursionCount = 0;
116 crit->OwningThread = 0;
117 DosCloseMutexSem(crit->hmtxLock);
118 crit->hmtxLock = 0;
119 crit->Reserved = (DWORD)-1;
120 }
121}
122
123
124/***********************************************************************
125 * DosEnterCriticalSection
126 */
127void WIN32API DosEnterCriticalSection( CRITICAL_SECTION_OS2 *crit )
128{
129 DWORD res;
130
131 if (!crit->hmtxLock)
132 {
133 DosInitializeCriticalSection(crit, NULL);
134 }
135 if (DosInterlockedIncrement( &crit->LockCount ))
136 {
137 if (crit->OwningThread == GetCurrentThreadId())
138 {
139 crit->RecursionCount++;
140 return;
141 }
142
143 /* Now wait for it */
144 APIRET rc = DosRequestMutexSem(crit->hmtxLock, SEM_INDEFINITE_WAIT);
145 }
146 crit->OwningThread = GetCurrentThreadId();
147 crit->RecursionCount = 1;
148}
149
150
151/***********************************************************************
152 * DosTryEnterCriticalSection
153 */
154BOOL WIN32API DosTryEnterCriticalSection( CRITICAL_SECTION_OS2 *crit )
155{
156 if (DosInterlockedIncrement( &crit->LockCount ))
157 {
158 if (crit->OwningThread == GetCurrentThreadId())
159 {
160 crit->RecursionCount++;
161 return TRUE;
162 }
163 /* FIXME: this doesn't work */
164 DosInterlockedDecrement( &crit->LockCount );
165 return FALSE;
166 }
167 crit->OwningThread = GetCurrentThreadId();
168 crit->RecursionCount = 1;
169 return TRUE;
170}
171
172
173/***********************************************************************
174 * DosLeaveCriticalSection
175 */
176void WIN32API DosLeaveCriticalSection( CRITICAL_SECTION_OS2 *crit )
177{
178 if (crit->OwningThread != GetCurrentThreadId()) return;
179
180 if (--crit->RecursionCount)
181 {
182 DosInterlockedDecrement( &crit->LockCount );
183 return;
184 }
185 crit->OwningThread = 0;
186 if (DosInterlockedDecrement( &crit->LockCount ) >= 0)
187 {
188 /* Someone is waiting */
189 DosReleaseMutexSem(crit->hmtxLock);
190 }
191}
192
Note: See TracBrowser for help on using the repository browser.