2 * Bacula shared memory routines
4 * To avoid problems with several return arguments, we
7 * BSHM definition is in bshm.h
9 * By Kern Sibbald, May MM
13 * Note, this routine was originally written so that the DEVICE structures
14 * could be shared between the child processes. Now that the Storage
15 * daemon is threaded, these routines are no longer needed. Rather than
16 * rewrite all the code, I simply #ifdef it on NEED_SHARED_MEMORY, and
17 * when not defined, I simply malloc() a buffer, which is, of course,
18 * available to all the threads.
23 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
25 This program is free software; you can redistribute it and/or
26 modify it under the terms of the GNU General Public License as
27 published by the Free Software Foundation; either version 2 of
28 the License, or (at your option) any later version.
30 This program is distributed in the hope that it will be useful,
31 but WITHOUT ANY WARRANTY; without even the implied warranty of
32 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
33 General Public License for more details.
35 You should have received a copy of the GNU General Public
36 License along with this program; if not, write to the Free
37 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
46 #ifdef NEED_SHARED_MEMORY
47 #define SHM_KEY 0x0BACB01 /* key for shared memory */
48 static key_t shmkey = SHM_KEY;
49 #define MAX_TRIES 1000
51 #else /* threaded model */
52 /* Multiple thread protection */
53 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
57 /* Create shared memory segment defined by BSHM */
58 void shm_create(BSHM *shm)
60 #ifdef NEED_SHARED_MEMORY
64 Dmsg1(110, "shm_create size=%d\n", shm->size);
65 for (i=0; i<MAX_TRIES; i++) {
66 if ((shmid = shmget(shmkey, shm->size, shm->perms | IPC_CREAT)) < 0) {
67 Emsg1(M_WARN, 0, "shmget failure key = %x\n", shmkey);
75 Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
78 Dmsg2(110, "shm_create return key=%x id=%d\n", shmkey, shmid);
79 shmkey++; /* leave set for next time */
82 shm->shmkey = 0; /* reference count */
86 /* Attach to shared memory segement defined in BSHM */
87 void *shm_open(BSHM *shm)
89 #ifdef NEED_SHARED_MEMORY
93 Dmsg2(110, "shm_open key=%x size=%d\n", shm->shmkey, shm->size);
94 if ((shmid = shmget(shm->shmkey, shm->size, 0)) < 0)
95 Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
96 Dmsg1(110, "shm_open shmat with id=%d\n", shmid);
97 shmbuf = shmat(shmid, NULL, 0);
98 Dmsg1(110, "shm_open buf=%x\n", shmbuf);
99 if (shmbuf == (char *) -1)
100 Emsg1(M_ABORT, 0, "Could not attach shared memory: %s\n", strerror(errno));
101 shm->shmbuf = shmbuf;
107 shm->shmbuf = bmalloc(shm->size);
109 shm->shmkey++; /* reference count */
115 /* Detach from shared memory segement */
116 void shm_close(BSHM *shm)
118 #ifdef NEED_SHARED_MEMORY
120 if (shmdt(shm->shmbuf) < 0) {
121 Emsg1(M_ERROR, 0, "Error detaching shared memory: %s\n", strerror(errno));
126 shm->shmkey--; /* reference count */
131 /* Destroy the shared memory segment */
132 void shm_destroy(BSHM *shm)
134 #ifdef NEED_SHARED_MEMORY
136 if (shmctl(shm->shmid, IPC_RMID, NULL) < 0) {
137 Emsg1(M_ERROR, 0, "Could not destroy shared memory: %s\n", strerror(errno));
141 /* We really should check that the ref count is zero */
151 #endif /* ! HAVE_CYGWIN */