|
10 | 10 | * Portions Copyright (c) 1994, Regents of the University of California
|
11 | 11 | *
|
12 | 12 | * IDENTIFICATION
|
13 |
| - * $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.9 2003/05/0814:49:03 momjian Exp $ |
| 13 | + * $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.10 2003/05/0819:17:07 momjian Exp $ |
14 | 14 | *
|
15 | 15 | *-------------------------------------------------------------------------
|
16 | 16 | */
|
@@ -47,6 +47,8 @@ static void IpcMemoryDetach(int status, Datum shmaddr);
|
47 | 47 | staticvoidIpcMemoryDelete(intstatus,DatumshmId);
|
48 | 48 | staticvoid*PrivateMemoryCreate(uint32size);
|
49 | 49 | staticvoidPrivateMemoryDelete(intstatus,Datummemaddr);
|
| 50 | +staticPGShmemHeader*PGSharedMemoryAttach(IpcMemoryKeykey, |
| 51 | +IpcMemoryId*shmid,void*addr); |
50 | 52 |
|
51 | 53 |
|
52 | 54 | /*
|
@@ -297,72 +299,48 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
|
297 | 299 | IpcMemoryKeyNextShmemSegID;
|
298 | 300 | void*memAddress;
|
299 | 301 | PGShmemHeader*hdr;
|
| 302 | +IpcMemoryIdshmid; |
300 | 303 |
|
301 | 304 | /* Room for a header? */
|
302 | 305 | Assert(size>MAXALIGN(sizeof(PGShmemHeader)));
|
303 | 306 |
|
304 |
| -if (ExecBackend&&UsedShmemSegID!=0) |
305 |
| -NextShmemSegID=UsedShmemSegID; |
306 |
| -else |
307 |
| -NextShmemSegID=port*1000+1; |
308 |
| - |
309 |
| -for (;;NextShmemSegID++) |
| 307 | +/* Just attach and return the pointer */ |
| 308 | +if (ExecBackend&&UsedShmemSegAddr!=NULL&& !makePrivate) |
310 | 309 | {
|
311 |
| -IpcMemoryIdshmid; |
312 |
| - |
313 |
| -/* Special case if creating a private segment --- just malloc() it */ |
314 |
| -if (makePrivate) |
315 |
| -{ |
316 |
| -memAddress=PrivateMemoryCreate(size); |
317 |
| -break; |
318 |
| -} |
319 |
| - |
320 |
| -/* If attach to fixed address, only try once */ |
321 |
| -if (ExecBackend&&UsedShmemSegAddr!=NULL&&NextShmemSegID!=UsedShmemSegID) |
| 310 | +if ((hdr= (PGShmemHeader*)memAddress=PGSharedMemoryAttach( |
| 311 | +UsedShmemSegID,&shmid,UsedShmemSegAddr))==NULL) |
322 | 312 | {
|
323 |
| -fprintf(stderr,"Unable to attach to memory at fixed address: shmget(key=%d, addr=%p) failed: %s\n", |
| 313 | +fprintf(stderr,"Unable to attach topropermemory at fixed address: shmget(key=%d, addr=%p) failed: %s\n", |
324 | 314 | (int)UsedShmemSegID,UsedShmemSegAddr,strerror(errno));
|
325 | 315 | proc_exit(1);
|
326 | 316 | }
|
| 317 | +returnhdr; |
| 318 | +} |
327 | 319 |
|
328 |
| -if (!ExecBackend||UsedShmemSegAddr==NULL) |
329 |
| -{ |
330 |
| -/* Try to create new segment */ |
331 |
| -memAddress=InternalIpcMemoryCreate(NextShmemSegID,size); |
332 |
| -if (memAddress) |
333 |
| -break;/* successful create and attach */ |
334 |
| -} |
335 |
| - |
336 |
| -/* See if it looks to be leftover from a dead Postgres process */ |
337 |
| -shmid=shmget(NextShmemSegID,sizeof(PGShmemHeader),0); |
338 |
| -if (shmid<0) |
339 |
| -continue;/* failed: must be some other app's */ |
340 |
| - |
341 |
| -/* use intimate shared memory on SPARC Solaris */ |
342 |
| -memAddress=shmat(shmid,UsedShmemSegAddr, |
343 |
| -#if defined(solaris)&&defined(__sparc__) |
344 |
| -SHM_SHARE_MMU |
345 |
| -#else |
346 |
| -0 |
347 |
| -#endif |
348 |
| -); |
349 |
| - |
350 |
| -if (memAddress== (void*)-1) |
351 |
| -continue;/* failed: must be some other app's */ |
| 320 | +/* Create shared memory */ |
| 321 | + |
| 322 | +NextShmemSegID=port*1000+1; |
352 | 323 |
|
353 |
| -hdr= (PGShmemHeader*)memAddress; |
354 |
| -if (hdr->magic!=PGShmemMagic) |
| 324 | +for (;;NextShmemSegID++) |
| 325 | +{ |
| 326 | +/* Special case if creating a private segment --- just malloc() it */ |
| 327 | +if (makePrivate) |
355 | 328 | {
|
356 |
| -shmdt(memAddress); |
357 |
| -continue;/* segment belongs to a non-Postgres app */ |
| 329 | +memAddress=PrivateMemoryCreate(size); |
| 330 | +break; |
358 | 331 | }
|
359 | 332 |
|
360 |
| -/* Successfully attached to shared memory, which is all we wanted */ |
361 |
| -if (ExecBackend&&UsedShmemSegAddr!=NULL) |
362 |
| -break; |
| 333 | +/* Try to create new segment */ |
| 334 | +memAddress=InternalIpcMemoryCreate(NextShmemSegID,size); |
| 335 | +if (memAddress) |
| 336 | +break;/* successful create and attach */ |
363 | 337 |
|
364 | 338 | /* Check shared memory and possibly remove and recreate */
|
365 | 339 |
|
| 340 | +if ((hdr= (PGShmemHeader*)memAddress=PGSharedMemoryAttach( |
| 341 | +NextShmemSegID,&shmid,UsedShmemSegAddr))==NULL) |
| 342 | +continue;/* can't attach, not one of mine */ |
| 343 | + |
366 | 344 | /*
|
367 | 345 | * If I am not the creator and it belongs to an extant process,
|
368 | 346 | * continue.
|
@@ -401,31 +379,60 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
|
401 | 379 | */
|
402 | 380 | }
|
403 | 381 |
|
| 382 | +/* |
| 383 | + * OK, we created a new segment. Mark it as created by this process. |
| 384 | + * The order of assignments here is critical so that another Postgres |
| 385 | + * process can't see the header as valid but belonging to an invalid |
| 386 | + * PID! |
| 387 | + */ |
404 | 388 | hdr= (PGShmemHeader*)memAddress;
|
| 389 | +hdr->creatorPID=getpid(); |
| 390 | +hdr->magic=PGShmemMagic; |
405 | 391 |
|
406 |
| -if (!ExecBackend||makePrivate||UsedShmemSegAddr==NULL) |
407 |
| -{ |
408 |
| -/* |
409 |
| - * OK, we created a new segment. Mark it as created by this process. |
410 |
| - * The order of assignments here is critical so that another Postgres |
411 |
| - * process can't see the header as valid but belonging to an invalid |
412 |
| - * PID! |
413 |
| - */ |
414 |
| -hdr->creatorPID=getpid(); |
415 |
| -hdr->magic=PGShmemMagic; |
416 |
| - |
417 |
| -/* |
418 |
| - * Initialize space allocation status for segment. |
419 |
| - */ |
420 |
| -hdr->totalsize=size; |
421 |
| -hdr->freeoffset=MAXALIGN(sizeof(PGShmemHeader)); |
422 |
| -} |
| 392 | +/* |
| 393 | + * Initialize space allocation status for segment. |
| 394 | + */ |
| 395 | +hdr->totalsize=size; |
| 396 | +hdr->freeoffset=MAXALIGN(sizeof(PGShmemHeader)); |
423 | 397 |
|
424 |
| -if (ExecBackend&& !makePrivate&&UsedShmemSegAddr==NULL) |
| 398 | + |
| 399 | +if (ExecBackend&&UsedShmemSegAddr==NULL&& !makePrivate) |
425 | 400 | {
|
426 | 401 | UsedShmemSegAddr=memAddress;
|
427 | 402 | UsedShmemSegID=NextShmemSegID;
|
428 | 403 | }
|
| 404 | + |
| 405 | +returnhdr; |
| 406 | +} |
| 407 | + |
| 408 | + |
| 409 | +/* |
| 410 | + *Attach to shared memory and make sure it has a Postgres header |
| 411 | + */ |
| 412 | +staticPGShmemHeader* |
| 413 | +PGSharedMemoryAttach(IpcMemoryKeykey,IpcMemoryId*shmid,void*addr) |
| 414 | +{ |
| 415 | +PGShmemHeader*hdr; |
| 416 | + |
| 417 | +if ((*shmid=shmget(key,sizeof(PGShmemHeader),0))<0) |
| 418 | +returnNULL; |
429 | 419 |
|
| 420 | +hdr= (PGShmemHeader*)shmat(*shmid,UsedShmemSegAddr, |
| 421 | +#if defined(solaris)&&defined(__sparc__) |
| 422 | +/* use intimate shared memory on SPARC Solaris */ |
| 423 | +SHM_SHARE_MMU |
| 424 | +#else |
| 425 | +0 |
| 426 | +#endif |
| 427 | +); |
| 428 | + |
| 429 | +if (hdr== (PGShmemHeader*)-1) |
| 430 | +returnNULL;/* failed: must be some other app's */ |
| 431 | + |
| 432 | +if (hdr->magic!=PGShmemMagic) |
| 433 | +{ |
| 434 | +shmdt(hdr); |
| 435 | +returnNULL;/* segment belongs to a non-Postgres app */ |
| 436 | +} |
430 | 437 | returnhdr;
|
431 | 438 | }
|