|
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 | } |