]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/bshm.c
Apply win32 fixes + add tapetest.c
[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, 2001, 2002 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 #include "bacula.h"
43
44 #if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
45
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
50
51 #else /* threaded model */
52 /* Multiple thread protection */
53 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
54 #endif
55
56
57 /* Create shared memory segment defined by BSHM */
58 void shm_create(BSHM *shm)
59 {
60 #ifdef NEED_SHARED_MEMORY
61    int shmid, i;
62    int not_found = TRUE;
63
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);
68          shmkey++;
69          continue;
70       }
71       not_found = FALSE;
72       break;
73    }
74    if (not_found) 
75       Emsg2(M_ABORT, 0, "Could not get %d bytes of shared memory: %s\n", shm->size, strerror(errno));
76    shm->shmkey = shmkey;
77    shm->shmid = shmid;
78    Dmsg2(110, "shm_create return key=%x id=%d\n", shmkey, shmid);
79    shmkey++;                          /* leave set for next time */
80 #else 
81    shm->shmbuf = NULL;
82    shm->shmkey = 0;                   /* reference count */
83 #endif
84 }
85
86 /* Attach to shared memory segement defined in BSHM */
87 void *shm_open(BSHM *shm)
88 {
89 #ifdef NEED_SHARED_MEMORY
90    int shmid;
91    char *shmbuf;
92
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;
102    shm->shmid = shmid;
103    return shmbuf;
104 #else
105    P(mutex);
106    if (!shm->shmbuf) {
107       shm->shmbuf = bmalloc(shm->size);
108    }
109    shm->shmkey++;                     /* reference count */
110    V(mutex);
111    return shm->shmbuf;
112 #endif
113 }
114
115 /* Detach from shared memory segement */
116 void shm_close(BSHM *shm)
117 {
118 #ifdef NEED_SHARED_MEMORY
119    if (shm->size) {
120       if (shmdt(shm->shmbuf) < 0) {
121          Emsg1(M_ERROR, 0, "Error detaching shared memory: %s\n", strerror(errno));
122       }
123    }
124 #else
125    P(mutex);
126    shm->shmkey--;                     /* reference count */
127    V(mutex);
128 #endif
129 }
130
131 /* Destroy the shared memory segment */
132 void shm_destroy(BSHM *shm)
133 {
134 #ifdef NEED_SHARED_MEMORY
135    if (shm->size) {
136       if (shmctl(shm->shmid, IPC_RMID, NULL) < 0) {
137          Emsg1(M_ERROR, 0, "Could not destroy shared memory: %s\n", strerror(errno));
138       }
139    }
140 #else
141    /* We really should check that the ref count is zero */
142    P(mutex);
143    if (shm->shmbuf) {
144       free(shm->shmbuf);
145       shm->shmbuf = NULL;
146    }
147    V(mutex);
148 #endif
149 }
150
151 #endif /* ! HAVE_CYGWIN */