qLibc
qshm.c
Go to the documentation of this file.
1 /******************************************************************************
2  * qLibc
3  *
4  * Copyright (c) 2010-2015 Seungyoung Kim.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  *****************************************************************************/
28 
29 /**
30  * @file qshm.c Shared-memory APIs.
31  *
32  * @note
33  * @code
34  * [your header file]
35  * struct SharedData {
36  * (... structrue definitions ...)
37  * }
38  *
39  * [shared memory creater]
40  * // create shared memory
41  * int shmid = qshm_init("/some/file/for/generating/unique/key", 's', sizeof(struct SharedData), true);
42  * if(shmid < 0) {
43  * printf("ERROR: Can't initialize shared memory.\n");
44  * return -1;
45  * }
46  *
47  * // get shared memory pointer
48  * struct SharedData *sdata = (SharedData *)qshm_get(shmid);
49  * if(sdata == NULL) {
50  * printf("ERROR: Can't get shared memory.\n");
51  * return -1;
52  * }
53  *
54  * [shared memory user]
55  * // get shared memory id
56  * int shmid = qshm_getid("/some/file/for/generating/unique/key", 's');
57  * if(shmid < 0) {
58  * printf("ERROR: Can't get shared memory id.\n");
59  * return -1;
60  * }
61  *
62  * // get shared memory pointer
63  * struct SharedData *sdata = (SharedData *)qshm_get(shmid);
64  * if(sdata == NULL) {
65  * printf("ERROR: Can't get shared memory.\n");
66  * return -1;
67  * }
68  * @endcode
69  */
70 
71 #ifndef DISABLE_IPC
72 
73 #include <stdio.h>
74 #include <stdlib.h>
75 #include <stdbool.h>
76 #include <string.h>
77 #include <sys/shm.h>
78 #include "qinternal.h"
79 #include "ipc/qshm.h"
80 
81 /**
82  * Initialize shared-memory
83  *
84  * @param keyfile seed for generating unique IPC key
85  * @param keyid seed for generating unique IPC key
86  * @param size size of shared memory
87  * @param recreate set to true to re-create shared-memory if already exists
88  *
89  * @return non-negative shared memory identifier if successful, otherwise returns -1
90  */
91 int qshm_init(const char *keyfile, int keyid, size_t size, bool recreate) {
92  key_t semkey;
93  int shmid;
94 
95  /* generate unique key using ftok() */
96  if (keyfile != NULL) {
97  semkey = ftok(keyfile, keyid);
98  if (semkey == -1)
99  return -1;
100  } else {
101  semkey = IPC_PRIVATE;
102  }
103 
104  /* create shared memory */
105  if ((shmid = shmget(semkey, size, IPC_CREAT | IPC_EXCL | 0666)) == -1) {
106  if (recreate == false)
107  return -1;
108 
109  /* destroy & re-create */
110  if ((shmid = qshm_getid(keyfile, keyid)) >= 0)
111  qshm_free(shmid);
112  if ((shmid = shmget(semkey, size, IPC_CREAT | IPC_EXCL | 0666)) == -1)
113  return -1;
114  }
115 
116  return shmid;
117 }
118 
119 /**
120  * Get shared memory identifier by keyfile and keyid for existing shared memory
121  *
122  * @param keyfile seed for generating unique IPC key
123  * @param keyid seed for generating unique IPC key
124  *
125  * @return non-negative shared memory identifier if successful, otherwise returns -1
126  */
127 int qshm_getid(const char *keyfile, int keyid) {
128  int shmid;
129 
130  /* generate unique key using ftok() */
131  key_t semkey = ftok(keyfile, keyid);
132  if (semkey == -1)
133  return -1;
134 
135  /* get current shared memory id */
136  if ((shmid = shmget(semkey, 0, 0)) == -1)
137  return -1;
138 
139  return shmid;
140 }
141 
142 /**
143  * Get a pointer of shared memory
144  *
145  * @param shmid shared memory identifier
146  *
147  * @return a pointer of shared memory
148  */
149 void *qshm_get(int shmid) {
150  void *pShm;
151 
152  if (shmid < 0)
153  return NULL;
154  pShm = shmat(shmid, 0, 0);
155  if (pShm == (void *) -1)
156  return NULL;
157  return pShm;
158 }
159 
160 /**
161  * De-allocate shared memory
162  *
163  * @param shmid shared memory identifier
164  *
165  * @return true if successful, otherwise returns false
166  */
167 bool qshm_free(int shmid) {
168  if (shmid < 0)
169  return false;
170  if (shmctl(shmid, IPC_RMID, 0) != 0)
171  return false;
172  return true;
173 }
174 
175 #endif /* DISABLE_IPC */
int qshm_init(const char *keyfile, int keyid, size_t size, bool recreate)
Initialize shared-memory.
Definition: qshm.c:91
bool qshm_free(int shmid)
De-allocate shared memory.
Definition: qshm.c:167
int qshm_getid(const char *keyfile, int keyid)
Get shared memory identifier by keyfile and keyid for existing shared memory.
Definition: qshm.c:127
void * qshm_get(int shmid)
Get a pointer of shared memory.
Definition: qshm.c:149