summaryrefslogtreecommitdiff
path: root/src/bin/evas/evas_cserve2_shm.c
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-07-18 19:21:58 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-10-28 15:47:12 +0900
commitdeb8776de5b46e280371fc0db894db96287cf681 (patch)
treee2be62905988d20087a6e5a247aa173f4e359c5c /src/bin/evas/evas_cserve2_shm.c
parent781c2e26e545586378c07339154c50a500b14b99 (diff)
evas/cserve2: Add functions to resize shm files
- cserve2_shm_segment_request() Creates a new shm segment (Shm_Handle) from an existing file, without changing the current mmap. - cserve2_shm_resize() Grows the file and remaps in memory (new virtual address). - cserve2_shm_id_get() Returns the shm creation ID.
Diffstat (limited to 'src/bin/evas/evas_cserve2_shm.c')
-rw-r--r--src/bin/evas/evas_cserve2_shm.c104
1 files changed, 103 insertions, 1 deletions
diff --git a/src/bin/evas/evas_cserve2_shm.c b/src/bin/evas/evas_cserve2_shm.c
index 7dcf05dbb6..2df0bb5e60 100644
--- a/src/bin/evas/evas_cserve2_shm.c
+++ b/src/bin/evas/evas_cserve2_shm.c
@@ -28,6 +28,7 @@ struct _Shm_Handle
28 size_t map_size; 28 size_t map_size;
29 size_t image_size; 29 size_t image_size;
30 int refcount; 30 int refcount;
31 int shmid;
31 void *data; 32 void *data;
32}; 33};
33 34
@@ -77,7 +78,7 @@ cserve2_shm_request(const char *infix, size_t size)
77 78
78 do { 79 do {
79 snprintf(shmname, sizeof(shmname), "/evas-shm-%x-%s-%08x", 80 snprintf(shmname, sizeof(shmname), "/evas-shm-%x-%s-%08x",
80 (int) getuid(), infix, id++); 81 (int) getuid(), infix, ++id);
81 fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); 82 fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
82 if (fd == -1 && errno != EEXIST) 83 if (fd == -1 && errno != EEXIST)
83 { 84 {
@@ -110,6 +111,100 @@ cserve2_shm_request(const char *infix, size_t size)
110 111
111 shm->image_size = size; 112 shm->image_size = size;
112 shm->map_size = map_size; 113 shm->map_size = map_size;
114 shm->shmid = id;
115
116 return shm;
117}
118
119Shm_Handle *
120cserve2_shm_segment_request(Shm_Handle *shm, size_t size)
121{
122 Shm_Handle *segment;
123 size_t map_size;
124 Shm_Mapping *map = shm->mapping;
125 int fd;
126
127 segment = calloc(1, sizeof (Shm_Handle));
128 if (!segment) return NULL;
129
130 fd = shm_open(map->name, O_RDWR, S_IRUSR | S_IWUSR);
131 if (!fd)
132 {
133 ERR("Could not reopen shm handle: %m");
134 free(segment);
135 return NULL;
136 }
137
138 map_size = cserve2_shm_size_normalize(size);
139 map_size += map->length;
140
141 if (ftruncate(fd, map_size) == -1)
142 {
143 ERR("Could not set the size of the shm: %m");
144 close(fd);
145 free(segment);
146 return NULL;
147 }
148 close(fd);
149
150 segment->mapping = map;
151 segment->map_offset = map->length;
152 segment->map_size = map_size - map->length;
153 segment->image_size = size;
154 segment->image_offset = segment->map_offset;
155 map->length = map_size;
156 map->segments = eina_inlist_append(map->segments, EINA_INLIST_GET(segment));
157
158 return segment;
159}
160
161Shm_Handle *
162cserve2_shm_resize(Shm_Handle *shm, size_t newsize)
163{
164 size_t map_size;
165 int fd;
166
167 if (!shm)
168 return NULL;
169
170 if (shm->map_offset || shm->image_offset)
171 {
172 CRIT("Can not resize shm with non-zero offset");
173 return NULL;
174 }
175
176 if (eina_inlist_count(shm->mapping->segments) > 1)
177 {
178 CRIT("Can not resize shm with more than one segment");
179 return NULL;
180 }
181
182 fd = shm_open(shm->mapping->name, O_RDWR, S_IRUSR | S_IWUSR);
183 if (!fd)
184 {
185 ERR("Could not reopen shm handle: %m");
186 return NULL;
187 }
188
189 map_size = cserve2_shm_size_normalize(newsize);
190 if (ftruncate(fd, map_size))
191 {
192 ERR("Could not set the size of the shm: %m");
193 close(fd);
194 return NULL;
195 }
196
197 if (shm->data)
198 {
199 munmap(shm->data, shm->image_size);
200 shm->data = mmap(NULL, shm->image_size, PROT_WRITE, MAP_SHARED,
201 fd, shm->image_offset);
202 }
203 close(fd);
204
205 shm->map_size = map_size;
206 shm->image_size = newsize;
207 shm->mapping->length = map_size;
113 208
114 return shm; 209 return shm;
115} 210}
@@ -139,6 +234,12 @@ cserve2_shm_name_get(const Shm_Handle *shm)
139 return shm->mapping->name; 234 return shm->mapping->name;
140} 235}
141 236
237int
238cserve2_shm_id_get(const Shm_Handle *shm)
239{
240 return shm->shmid;
241}
242
142off_t 243off_t
143cserve2_shm_map_offset_get(const Shm_Handle *shm) 244cserve2_shm_map_offset_get(const Shm_Handle *shm)
144{ 245{
@@ -220,6 +321,7 @@ _cserve2_shm_cleanup()
220 else 321 else
221 DBG("cserve2 cleanup: ignoring %s", f_info->path); 322 DBG("cserve2 cleanup: ignoring %s", f_info->path);
222 } 323 }
324 eina_iterator_free(iter);
223} 325}
224 326
225void 327void