10
10
* - this required changing sem_info from containig an array of sem_t to an array of sem_t*
11
11
*
12
12
* IDENTIFICATION
13
- * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.3 2001/03/22 03:59:42 momjian Exp $
13
+ * $Header: /cvsroot/pgsql/src/backend/port/darwin/Attic/sem.c,v 1.4 2001/09/07 00:27:29 tgl Exp $
14
14
*
15
15
*-------------------------------------------------------------------------
16
16
*/
17
+ #include "postgres.h"
17
18
18
19
#include <errno.h>
19
20
#include <semaphore.h>
22
23
#include <unistd.h>
23
24
#include <fcntl.h>
24
25
#include <sys/mman.h>
25
- #include "postgres.h"
26
+
27
+ #include "miscadmin.h"
26
28
#include "storage/ipc.h"
27
29
#include "storage/proc.h"
28
30
#include "port/darwin/sem.h"
29
31
30
32
#define SEMMAX IPC_NMAXSEM
31
- #define SETMAX ((MAXBACKENDS + SEMMAX - 1) / SEMMAX)
32
33
#define OPMAX 8
33
34
34
35
#define MODE 0700
@@ -41,19 +42,23 @@ struct pending_ops
41
42
int idx ; /* index of first free array member */
42
43
};
43
44
45
+ struct sem_set_info
46
+ {
47
+ key_t key ;
48
+ int nsems ;
49
+ sem_t * sem [SEMMAX ]; /* array of POSIX semaphores */
50
+ struct sem semV [SEMMAX ]; /* array of System V semaphore
51
+ * structures */
52
+ struct pending_ops pendingOps [SEMMAX ]; /* array of pending
53
+ * operations */
54
+ };
55
+
44
56
struct sem_info
45
57
{
46
58
sem_t * sem ;
47
- struct
48
- {
49
- key_t key ;
50
- int nsems ;
51
- sem_t * sem [SEMMAX ];/* array of POSIX semaphores */
52
- struct sem semV [SEMMAX ]; /* array of System V semaphore
53
- * structures */
54
- struct pending_ops pendingOps [SEMMAX ]; /* array of pending
55
- * operations */
56
- } set [SETMAX ];
59
+ int nsets ;
60
+ /* there are actually nsets of these: */
61
+ struct sem_set_info set [1 ]; /* VARIABLE LENGTH ARRAY */
57
62
};
58
63
59
64
static struct sem_info * SemInfo = (struct sem_info * ) - 1 ;
@@ -66,7 +71,7 @@ semctl(int semid, int semnum, int cmd, /* ... */ union semun arg)
66
71
67
72
sem_wait (SemInfo -> sem );
68
73
69
- if (semid < 0 || semid >= SETMAX ||
74
+ if (semid < 0 || semid >= SemInfo -> nsets ||
70
75
semnum < 0 || semnum >= SemInfo -> set [semid ].nsems )
71
76
{
72
77
sem_post (SemInfo -> sem );
@@ -132,8 +137,10 @@ semget(key_t key, int nsems, int semflg)
132
137
{
133
138
int fd ,
134
139
semid ,
135
- semnum /* , semnum1 */ ;
140
+ semnum ,
141
+ nsets ;
136
142
int exist = 0 ;
143
+ Size sem_info_size ;
137
144
char semname [64 ];
138
145
139
146
if (nsems < 0 || nsems > SEMMAX )
@@ -163,44 +170,46 @@ semget(key_t key, int nsems, int semflg)
163
170
return fd ;
164
171
shm_unlink (SHM_INFO_NAME );
165
172
/* The size may only be set once. Ignore errors. */
166
- ftruncate (fd , sizeof (struct sem_info ));
167
- SemInfo = mmap (NULL , sizeof (struct sem_info ),
173
+ nsets = PROC_SEM_MAP_ENTRIES (MaxBackends );
174
+ sem_info_size = sizeof (struct sem_info ) + (nsets - 1 ) * sizeof (struct sem_set_info );
175
+ ftruncate (fd , sem_info_size );
176
+ SemInfo = mmap (NULL , sem_info_size ,
168
177
PROT_READ | PROT_WRITE , MAP_SHARED , fd , 0 );
169
178
if (SemInfo == MAP_FAILED )
170
179
return -1 ;
171
180
if (!exist )
172
181
{
182
+ /* initialize shared memory */
183
+ memset (SemInfo , 0 , sem_info_size );
184
+ SemInfo -> nsets = nsets ;
185
+ for (semid = 0 ; semid < nsets ; semid ++ )
186
+ SemInfo -> set [semid ].key = -1 ;
173
187
/* create semaphore for locking */
174
188
sprintf (semname , "%s-map" , SEM_NAME );
175
189
#ifdef DEBUG_IPC
176
190
fprintf (stderr , "darwin creating sem %s to cover shared mem.\n" , semname );
177
191
#endif
178
192
SemInfo -> sem = sem_open (semname , O_CREAT , semflg & 0777 , 1 );
179
193
sem_unlink (semname );
180
- sem_wait (SemInfo -> sem );
181
- /* initilize shared memory */
182
- memset (SemInfo -> set , 0 , sizeof (SemInfo -> set ));
183
- for (semid = 0 ; semid < SETMAX ; semid ++ )
184
- SemInfo -> set [semid ].key = -1 ;
185
- sem_post (SemInfo -> sem );
186
194
}
187
195
}
188
196
189
197
sem_wait (SemInfo -> sem );
198
+ nsets = SemInfo -> nsets ;
190
199
191
200
if (key != IPC_PRIVATE )
192
201
{
193
202
/* search existing element */
194
203
semid = 0 ;
195
- while (semid < SETMAX && SemInfo -> set [semid ].key != key )
204
+ while (semid < nsets && SemInfo -> set [semid ].key != key )
196
205
semid ++ ;
197
- if (!(semflg & IPC_CREAT ) && semid >= SETMAX )
206
+ if (!(semflg & IPC_CREAT ) && semid >= nsets )
198
207
{
199
208
sem_post (SemInfo -> sem );
200
209
errno = ENOENT ;
201
210
return -1 ;
202
211
}
203
- else if (semid < SETMAX )
212
+ else if (semid < nsets )
204
213
{
205
214
if (semflg & IPC_CREAT && semflg & IPC_EXCL )
206
215
{
@@ -228,12 +237,12 @@ semget(key_t key, int nsems, int semflg)
228
237
229
238
/* search first free element */
230
239
semid = 0 ;
231
- while (semid < SETMAX && SemInfo -> set [semid ].key != -1 )
240
+ while (semid < nsets && SemInfo -> set [semid ].key != -1 )
232
241
semid ++ ;
233
- if (semid >= SETMAX )
242
+ if (semid >= nsets )
234
243
{
235
244
#ifdef DEBUG_IPC
236
- fprintf (stderr , "darwin semget failed because all keys were -1 up to SETMAX \n" );
245
+ fprintf (stderr , "darwin semget failed because all keys were -1\n" );
237
246
#endif
238
247
sem_post (SemInfo -> sem );
239
248
errno = ENOSPC ;
@@ -249,15 +258,18 @@ semget(key_t key, int nsems, int semflg)
249
258
SemInfo -> set [semid ].sem [semnum ] = sem_open (semname , O_CREAT , semflg & 0777 , 0 );
250
259
sem_unlink (semname );
251
260
252
- /* Currently sem_init always returns -1.
253
- if( sem_init( &SemInfo->set[semid].sem[semnum], 1, 0 ) == -1 ) {
254
- for( semnum1 = 0; semnum1 < semnum; semnum1++ ) {
255
- sem_close( SemInfo->set[semid].sem[semnum1] );
256
- }
257
- sem_post( SemInfo->sem );
258
- return -1;
259
- }
260
- */
261
+ /* Currently sem_init always returns -1. */
262
+ #ifdef NOT_USED
263
+ if ( sem_init ( & SemInfo -> set [semid ].sem [semnum ], 1 , 0 ) == -1 ) {
264
+ int semnum1 ;
265
+
266
+ for ( semnum1 = 0 ; semnum1 < semnum ; semnum1 ++ ) {
267
+ sem_close ( SemInfo -> set [semid ].sem [semnum1 ] );
268
+ }
269
+ sem_post ( SemInfo -> sem );
270
+ return -1 ;
271
+ }
272
+ #endif
261
273
}
262
274
263
275
SemInfo -> set [semid ].key = key ;
@@ -279,7 +291,7 @@ semop(int semid, struct sembuf * sops, size_t nsops)
279
291
280
292
sem_wait (SemInfo -> sem );
281
293
282
- if (semid < 0 || semid >= SETMAX )
294
+ if (semid < 0 || semid >= SemInfo -> nsets )
283
295
{
284
296
sem_post (SemInfo -> sem );
285
297
errno = EINVAL ;
0 commit comments