source: branches/2.20_branch/hlpmgr/sharedmemory.c

Last change on this file was 360, checked in by RBRi, 16 years ago

warning fixes

  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
1#include <stdio.h>
2#include <string.h>
3
4#define INCL_DOSERRORS
5#define INCL_DOSSEMAPHORES
6#define INCL_DOSPROCESS
7#include <os2.h>
8
9#include "SharedMemory.h"
10#include "Log.h"
11
12APIRET GetSharedMemory( char* Name,
13 ULONG Size,
14 TSharedMemory* pSharedMemory )
15{
16 APIRET rc;
17 char FullName[ 260 ];
18
19 pSharedMemory -> FFirst = TRUE;
20
21 strcpy( FullName, "\\SHAREMEM\\" );
22 strcat( FullName, Name );
23
24 LogEvent( "Full shared mem name: %s", FullName );
25 rc = DosAllocSharedMem( & pSharedMemory -> FPointer,
26 FullName,
27 Size,
28 PAG_READ | PAG_WRITE | PAG_COMMIT );
29
30 if ( rc != 0 )
31 {
32 LogEvent( " Unable to create shared mem: %d", rc );
33 if ( rc == ERROR_ALREADY_EXISTS )
34 {
35 LogEvent( " - Already exists, open" );
36 // memory already exists, just get it
37 pSharedMemory -> FFirst = FALSE;
38 rc = DosGetNamedSharedMem( & pSharedMemory -> FPointer,
39 FullName,
40 PAG_READ | PAG_WRITE );
41 LogEvent( " rc = %d", rc );
42 }
43 }
44
45 return rc;
46}
47
48APIRET OpenOrCreateMutex( PSZ pszName,
49 PHMTX phmtx )
50{
51 int Tries;
52 APIRET rc;
53
54 Tries = 0;
55 while( TRUE )
56 {
57 rc = DosOpenMutexSem( pszName,
58 phmtx );
59
60 if ( rc != ERROR_SEM_NOT_FOUND )
61 // ok, or some error
62 break;
63
64 rc = DosCreateMutexSem( pszName,
65 phmtx,
66 0,
67 FALSE );
68 if ( rc != ERROR_DUPLICATE_NAME )
69 // ok, or some error
70 break;
71
72 Tries ++;
73 if ( Tries > 100 )
74 // prevent an infinite loop in the extreme case
75 break;
76
77 // try again
78 DosSleep( 1 );
79 }
80
81 return rc;
82}
83
84void ReleaseSharedMemory( TSharedMemory* pSharedMemory )
85{
86 DosFreeMem( pSharedMemory -> FPointer ); // will free the shared mem once nobody has a ref.
87 pSharedMemory -> FPointer = NULL;
88}
89
90APIRET GetSubAllocatedSharedMemory( char* Name,
91 ULONG Size,
92 ULONG ReserveSize, // size to reserve at start of memory
93 TSubAllocatedSharedMemory* pSharedMemory )
94{
95 APIRET rc;
96 ULONG ActualSize;
97 ULONG ActualReserveSize;
98 ULONG Flags;
99 HMTX StartupSemaphore;
100 char SemaphoreName[ 260 ];
101
102 LogEvent( "GetSubAllocatedSharedMemory" );
103
104 ActualSize = Size;
105 if ( ActualSize < 256 )
106 ActualSize = 256; // make sure the suballoc info will fit.
107
108 // Ensure that only one process inits the suballocation
109
110 strcpy( SemaphoreName, "\\SEM32\\" );
111 strcat( SemaphoreName, Name );
112
113 LogEvent( " semaphore name: %s", SemaphoreName );
114
115 rc = OpenOrCreateMutex( SemaphoreName,
116 & StartupSemaphore );
117 if ( rc != 0 )
118 {
119 DosReleaseMutexSem( StartupSemaphore ); // why release here??
120 DosCloseMutexSem( StartupSemaphore );
121 LogEvent( " Semaphore failure: %d", rc );
122 return rc;
123 }
124
125 LogEvent( " Semaphore opened OK" );
126
127 DosRequestMutexSem( StartupSemaphore, SEM_INDEFINITE_WAIT );
128
129 rc = GetSharedMemory( Name,
130 ActualSize,
131 & ( pSharedMemory -> FMem ) );
132
133 if ( rc != 0 )
134 {
135 LogEvent( " GetSharedMemory failed: %d", rc );
136 DosReleaseMutexSem( StartupSemaphore );
137 DosCloseMutexSem( StartupSemaphore );
138 return rc;
139 }
140 LogEvent( " GetSharedMemory success" );
141
142 // round reserve size up to nearest 8 bytes
143 ActualReserveSize = ( ( ReserveSize + 7 ) / 8 ) * 8;
144
145 if ( ActualReserveSize >= ActualSize )
146 {
147 LogEvent( "Assertion failure: reserve size larger than total shared mem size!" );
148 DosReleaseMutexSem( StartupSemaphore );
149 DosCloseMutexSem( StartupSemaphore );
150 return ERROR_INVALID_PARAMETER;
151 }
152
153 pSharedMemory -> FAllocationArea =
154 (PBYTE) pSharedMemory -> FMem.FPointer
155 + ActualReserveSize;
156
157 Flags = DOSSUB_SERIALIZE;
158 if ( pSharedMemory -> FMem.FFirst )
159 {
160 // Initialise reserved area to zero
161 memset( pSharedMemory -> FMem.FPointer, 0, ActualReserveSize );
162 Flags = Flags | DOSSUB_INIT;
163 // otherwise just attach
164 }
165
166 // set up suballocation, with serialisation for multi-process access
167 rc = DosSubSetMem( pSharedMemory -> FAllocationArea,
168 Flags,
169 ActualSize - ActualReserveSize );
170
171 if ( rc == 0 )
172 LogEvent( " Suballocation initialised OK" );
173 else
174 LogEvent( " Error initialising Suballocation: ", rc );
175
176 DosReleaseMutexSem( StartupSemaphore );
177 DosCloseMutexSem( StartupSemaphore );
178
179 return rc;
180}
181
182// suballocate space of the given size
183APIRET SubAllocate( TSubAllocatedSharedMemory* pSharedMemory,
184 ULONG Size,
185 void** p )
186{
187 APIRET rc;
188 PULONG pSize;
189
190 rc = DosSubAllocMem( pSharedMemory -> FAllocationArea,
191 p,
192 Size + sizeof( ULONG ) );
193 if ( rc != 0 )
194 return rc;
195
196 // Store size at start of block
197 pSize = (PULONG) *p;
198 *pSize = Size;
199
200 *p = (PBYTE) (*p) + sizeof( ULONG );
201
202 return rc;
203}
204
205// free the given space.
206void SubDeallocate( TSubAllocatedSharedMemory* pSharedMemory,
207 void** p )
208{
209 APIRET rc;
210 PULONG pSize;
211 ULONG Size;
212
213 // retrieve size from start of block
214 *p = (PBYTE) (*p) - sizeof( ULONG );
215 pSize = (PULONG) *p;
216 Size = *pSize;
217
218 rc = DosSubFreeMem( pSharedMemory -> FAllocationArea,
219 p,
220 Size );
221
222 *p = NULL;
223}
224
225void ReleaseSubAllocatedSharedMemory( TSubAllocatedSharedMemory* pSharedMemory )
226{
227 // DosSubUnsetMem( pSharedMemory -> FAllocationArea );
228 // to do this requires manual reference counting
229 // it's easy just to not worry and the suballoc stuff
230 // will be freed when the shared memory is freed
231 pSharedMemory -> FAllocationArea = NULL;
232 ReleaseSharedMemory( & pSharedMemory -> FMem );
233}
234
Note: See TracBrowser for help on using the repository browser.