summaryrefslogtreecommitdiff
path: root/src/bin/evas/evas_cserve2_shm.c
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-11-04 11:51:42 +0000
commitc15e9c6575c3b5f39ded167dda5259de3de96151 (patch)
tree5115d7ae3620af24c2bc094cd062575af7adeda9 /src/bin/evas/evas_cserve2_shm.c
parenta5ac6a987caec5a7f7596a25d0a065b9cc94c50c (diff)
merge: and now Evas
I've tested make -j 3 install and it works nicely I've tested expedite with software and opengl xlib, and it works. Not tested other engines, so please report any problems (engines or other) on the ML. TODO: examples and tests, I'll add them later ISSUE: Eina_Unicode size check. It indirectly depends on eina_config.h, which is created at the end of the configure script. So its size is always 0. I don't know how that size is used, so I can't do a lot, for now. SVN revision: 78895
Diffstat (limited to 'src/bin/evas/evas_cserve2_shm.c')
-rw-r--r--src/bin/evas/evas_cserve2_shm.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/bin/evas/evas_cserve2_shm.c b/src/bin/evas/evas_cserve2_shm.c
new file mode 100644
index 0000000000..5e60138b42
--- /dev/null
+++ b/src/bin/evas/evas_cserve2_shm.c
@@ -0,0 +1,195 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include "evas_cserve2.h"
6
7#include <errno.h>
8#include <sys/mman.h>
9#include <sys/stat.h>
10#include <fcntl.h>
11#include <unistd.h>
12
13struct _Shm_Mapping
14{
15 const char *name;
16 size_t length;
17 Eina_Inlist *segments;
18};
19
20typedef struct _Shm_Mapping Shm_Mapping;
21
22struct _Shm_Handle
23{
24 EINA_INLIST;
25 Shm_Mapping *mapping;
26 off_t map_offset;
27 off_t image_offset;
28 size_t map_size;
29 size_t image_size;
30 int refcount;
31 void *data;
32};
33
34static int id = 0;
35
36size_t
37cserve2_shm_size_normalize(size_t size)
38{
39 long pagesize;
40 size_t normalized;
41
42 pagesize = sysconf(_SC_PAGESIZE);
43 if (pagesize < 1)
44 {
45 ERR("sysconf() reported weird value for PAGESIZE, assuming 4096.");
46 pagesize = 4096;
47 }
48
49 normalized = ((size + pagesize - 1) / pagesize) * pagesize;
50
51 return normalized;
52}
53
54Shm_Handle *
55cserve2_shm_request(size_t size)
56{
57 Shm_Mapping *map;
58 Shm_Handle *shm;
59 char shmname[NAME_MAX];
60 size_t map_size;
61 int fd;
62
63 map = calloc(1, sizeof(Shm_Mapping));
64 if (!map)
65 {
66 ERR("Failed to allocate mapping handler.");
67 return NULL;
68 }
69
70 do {
71 snprintf(shmname, sizeof(shmname), "/evas-shm-img-%d", id++);
72 fd = shm_open(shmname, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
73 if (fd == -1 && errno != EEXIST)
74 {
75 ERR("Failed to create shared memory object '%s': %m", shmname);
76 free(map);
77 return NULL;
78 }
79 } while (fd == -1);
80
81 map_size = cserve2_shm_size_normalize(size);
82
83 if (ftruncate(fd, map_size) == -1)
84 {
85 ERR("Failed to set size of shared file: %m");
86 close(fd);
87 free(map);
88 return NULL;
89 }
90 close(fd);
91
92 map->name = eina_stringshare_add(shmname);
93 map->length = map_size;
94
95 shm = calloc(1, sizeof(Shm_Handle));
96 if (!shm)
97 {
98 ERR("Failed to allocate shared memory handler.");
99 eina_stringshare_del(map->name);
100 free(map);
101 return NULL;
102 }
103
104 map->segments = eina_inlist_append(map->segments, EINA_INLIST_GET(shm));
105 shm->mapping = map;
106 shm->map_offset = 0;
107 shm->image_offset = 0;
108
109 shm->image_size = size;
110 shm->map_size = map_size;
111
112 return shm;
113}
114
115void
116cserve2_shm_unref(Shm_Handle *shm)
117{
118 Shm_Mapping *map = shm->mapping;
119
120 map->segments = eina_inlist_remove(map->segments, EINA_INLIST_GET(shm));
121
122 if (shm->data)
123 munmap(shm->data, shm->image_size);
124 free(shm);
125
126 if (map->segments)
127 return;
128
129 shm_unlink(map->name);
130 eina_stringshare_del(map->name);
131 free(map);
132}
133
134const char *
135cserve2_shm_name_get(const Shm_Handle *shm)
136{
137 return shm->mapping->name;
138}
139
140off_t
141cserve2_shm_map_offset_get(const Shm_Handle *shm)
142{
143 return shm->map_offset;
144}
145
146off_t
147cserve2_shm_offset_get(const Shm_Handle *shm)
148{
149 return shm->image_offset;
150}
151
152size_t
153cserve2_shm_map_size_get(const Shm_Handle *shm)
154{
155 return shm->map_size;
156}
157
158size_t
159cserve2_shm_size_get(const Shm_Handle *shm)
160{
161 return shm->image_size;
162}
163
164void *
165cserve2_shm_map(Shm_Handle *shm)
166{
167 int fd;
168 const char *name;
169
170 if (shm->refcount++)
171 return shm->data;
172
173 name = cserve2_shm_name_get(shm);
174
175 fd = shm_open(name, O_RDWR, S_IWUSR);
176 if (fd == -1)
177 return MAP_FAILED;
178
179 shm->data = mmap(NULL, shm->image_size, PROT_WRITE, MAP_SHARED,
180 fd, shm->image_offset);
181
182 close(fd);
183
184 return shm->data;
185}
186
187void
188cserve2_shm_unmap(Shm_Handle *shm)
189{
190 if (--shm->refcount)
191 return;
192
193 munmap(shm->data, shm->image_size);
194 shm->data = NULL;
195}