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.
22 Copyright (C) 2000-2006 Kern Sibbald
24 This program is free software; you can redistribute it and/or
25 modify it under the terms of the GNU General Public License
26 version 2 as amended with additional clauses defined in the
27 file LICENSE in the main source directory.
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 the file LICENSE for additional details.
41 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
43 #ifdef NEED_SHARED_MEMORY
44 #define SHM_KEY 0x0BACB01 /* key for shared memory */
45 static key_t shmkey = SHM_KEY;
46 #define MAX_TRIES 1000
48 #else /* threaded model */
49 /* Multiple thread protection */
50 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
54 /* Create shared memory segment defined by BSHM */
55 void shm_create(BSHM *shm)
57 #ifdef NEED_SHARED_MEMORY
61 Dmsg1(110, "shm_create size=%d\n", shm->size);
62 for (i=0; i<MAX_TRIES; i++) {
63 if ((shmid = shmget(shmkey, shm->size, shm->perms | IPC_CREAT)) < 0) {
64 Emsg1(M_WARN, 0, _("shmget failure key = %x\n"), shmkey);
72 Emsg2(M_ABORT, 0, _("Could not get %d bytes of shared memory: %s\n"), shm->size, strerror(errno));
75 Dmsg2(110, "shm_create return key=%x id=%d\n", shmkey, shmid);
76 shmkey++; /* leave set for next time */
79 shm->shmkey = 0; /* reference count */
83 /* Attach to shared memory segement defined in BSHM */
84 void *shm_open(BSHM *shm)
86 #ifdef NEED_SHARED_MEMORY
90 Dmsg2(110, "shm_open key=%x size=%d\n", shm->shmkey, shm->size);
91 if ((shmid = shmget(shm->shmkey, shm->size, 0)) < 0)
92 Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
93 Dmsg1(110, "shm_open shmat with id=%d\n", shmid);
94 shmbuf = shmat(shmid, NULL, 0);
95 Dmsg1(110, "shm_open buf=%x\n", shmbuf);
96 if (shmbuf == (char *) -1)
97 Emsg1(M_ABORT, 0, _("Could not attach shared memory: %s\n"), strerror(errno));
104 shm->shmbuf = bmalloc(shm->size);
106 shm->shmkey++; /* reference count */
112 /* Detach from shared memory segement */
113 void shm_close(BSHM *shm)
115 #ifdef NEED_SHARED_MEMORY
117 if (shmdt(shm->shmbuf) < 0) {
118 Emsg1(M_ERROR, 0, _("Error detaching shared memory: %s\n"), strerror(errno));
123 shm->shmkey--; /* reference count */
128 /* Destroy the shared memory segment */
129 void shm_destroy(BSHM *shm)
131 #ifdef NEED_SHARED_MEMORY
133 if (shmctl(shm->shmid, IPC_RMID, NULL) < 0) {
134 Emsg1(M_ERROR, 0, _("Could not destroy shared memory: %s\n"), strerror(errno));
138 /* We really should check that the ref count is zero */
148 #endif /* ! HAVE_CYGWIN */