]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bshm.c
- Correct compiler complaints in wx-console and tray-monitor.
[bacula/bacula] / bacula / src / lib / bshm.c
1 /*
2  *   Bacula shared memory routines
3  *
4  * To avoid problems with several return arguments, we
5  * pass a packet.
6  *
7  *  BSHM definition is in bshm.h
8  *
9  *  By Kern Sibbald, May MM
10  *
11  *   Version $Id$
12  *
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.
19  *
20  */
21
22 /*
23    Copyright (C) 2000-2004 Kern Sibbald and John Walker
24
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.
29
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.
34
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,
38    MA 02111-1307, USA.
39
40  */
41
42 #ifdef implemented
43
44 #include "bacula.h"
45
46 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
47
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
52
53 #else /* threaded model */
54 /* Multiple thread protection */
55 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
56 #endif
57
58
59 /* Create shared memory segment defined by BSHM */
60 void shm_create(BSHM *shm)
61 {
62 #ifdef NEED_SHARED_MEMORY
63    int shmid, i;
64    int not_found = TRUE;
65
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);
70          shmkey++;
71          continue;
72       }
73       not_found = FALSE;
74       break;
75    }
76    if (not_found)
77       Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
78    shm->shmkey = shmkey;
79    shm->shmid = shmid;
80    Dmsg2(110, "shm_create return key=%x id=%d\n", shmkey, shmid);
81    shmkey++;                          /* leave set for next time */
82 #else
83    shm->shmbuf = NULL;
84    shm->shmkey = 0;                   /* reference count */
85 #endif
86 }
87
88 /* Attach to shared memory segement defined in BSHM */
89 void *shm_open(BSHM *shm)
90 {
91 #ifdef NEED_SHARED_MEMORY
92    int shmid;
93    char *shmbuf;
94
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;
104    shm->shmid = shmid;
105    return shmbuf;
106 #else
107    P(mutex);
108    if (!shm->shmbuf) {
109       shm->shmbuf = bmalloc(shm->size);
110    }
111    shm->shmkey++;                     /* reference count */
112    V(mutex);
113    return shm->shmbuf;
114 #endif
115 }
116
117 /* Detach from shared memory segement */
118 void shm_close(BSHM *shm)
119 {
120 #ifdef NEED_SHARED_MEMORY
121    if (shm->size) {
122       if (shmdt(shm->shmbuf) < 0) {
123          Emsg1(M_ERROR, 0, "Error detaching shared memory: %s\n", strerror(errno));
124       }
125    }
126 #else
127    P(mutex);
128    shm->shmkey--;                     /* reference count */
129    V(mutex);
130 #endif
131 }
132
133 /* Destroy the shared memory segment */
134 void shm_destroy(BSHM *shm)
135 {
136 #ifdef NEED_SHARED_MEMORY
137    if (shm->size) {
138       if (shmctl(shm->shmid, IPC_RMID, NULL) < 0) {
139          Emsg1(M_ERROR, 0, "Could not destroy shared memory: %s\n", strerror(errno));
140       }
141    }
142 #else
143    /* We really should check that the ref count is zero */
144    P(mutex);
145    if (shm->shmbuf) {
146       free(shm->shmbuf);
147       shm->shmbuf = NULL;
148    }
149    V(mutex);
150 #endif
151 }
152
153 #endif /* ! HAVE_CYGWIN */
154
155 #endif