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 */
qshm_get
void * qshm_get(int shmid)
Get a pointer of shared memory.
Definition qshm.c:149
qshm_init
int qshm_init(const char *keyfile, int keyid, size_t size, bool recreate)
Initialize shared-memory.
Definition qshm.c:91
qshm_getid
int qshm_getid(const char *keyfile, int keyid)
Get shared memory identifier by keyfile and keyid for existing shared memory.
Definition qshm.c:127
qshm_free
bool qshm_free(int shmid)
De-allocate shared memory.
Definition qshm.c:167