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-2004 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 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
48 #ifdef NEED_SHARED_MEMORY
49 #define SHM_KEY 0x0BACB01 /* key for shared memory */
50 static key_t shmkey = SHM_KEY;
51 #define MAX_TRIES 1000
53 #else /* threaded model */
54 /* Multiple thread protection */
55 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
59 /* Create shared memory segment defined by BSHM */
60 void shm_create(BSHM *shm)
62 #ifdef NEED_SHARED_MEMORY
66 Dmsg1(110, "shm_create size=%d\n", shm->size);
67 for (i=0; i<MAX_TRIES; i++) {
68 if ((shmid = shmget(shmkey, shm->size, shm->perms | IPC_CREAT)) < 0) {
69 Emsg1(M_WARN, 0, "shmget failure key = %x\n", shmkey);
77 Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
80 Dmsg2(110, "shm_create return key=%x id=%d\n", shmkey, shmid);
81 shmkey++; /* leave set for next time */
84 shm->shmkey = 0; /* reference count */
88 /* Attach to shared memory segement defined in BSHM */
89 void *shm_open(BSHM *shm)
91 #ifdef NEED_SHARED_MEMORY
95 Dmsg2(110, "shm_open key=%x size=%d\n", shm->shmkey, shm->size);
96 if ((shmid = shmget(shm->shmkey, shm->size, 0)) < 0)
97 Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
98 Dmsg1(110, "shm_open shmat with id=%d\n", shmid);
99 shmbuf = shmat(shmid, NULL, 0);
100 Dmsg1(110, "shm_open buf=%x\n", shmbuf);
101 if (shmbuf == (char *) -1)
102 Emsg1(M_ABORT, 0, "Could not attach shared memory: %s\n", strerror(errno));
103 shm->shmbuf = shmbuf;
109 shm->shmbuf = bmalloc(shm->size);
111 shm->shmkey++; /* reference count */
117 /* Detach from shared memory segement */
118 void shm_close(BSHM *shm)
120 #ifdef NEED_SHARED_MEMORY
122 if (shmdt(shm->shmbuf) < 0) {
123 Emsg1(M_ERROR, 0, "Error detaching shared memory: %s\n", strerror(errno));
128 shm->shmkey--; /* reference count */
133 /* Destroy the shared memory segment */
134 void shm_destroy(BSHM *shm)
136 #ifdef NEED_SHARED_MEMORY
138 if (shmctl(shm->shmid, IPC_RMID, NULL) < 0) {
139 Emsg1(M_ERROR, 0, "Could not destroy shared memory: %s\n", strerror(errno));
143 /* We really should check that the ref count is zero */
153 #endif /* ! HAVE_CYGWIN */