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