summaryrefslogtreecommitdiff
path: root/legacy/evas/src/bin/dummy_slave.c
diff options
context:
space:
mode:
authorIván Briano <sachieru@gmail.com>2012-05-03 21:01:31 +0000
committerIván Briano <sachieru@gmail.com>2012-05-03 21:01:31 +0000
commit15328efb85bcf413025d787d1d58d812a407f25a (patch)
tree37c09205c159d8b9758ffdada5dff2248e632613 /legacy/evas/src/bin/dummy_slave.c
parentb8ade6a7cfa99ca19c054bd6b0bf488e63accbf4 (diff)
evas/cserve2: fix typo that kept cserve2 disabled
now seriously... Introducing Cache Serve 2. This cache server will initially load images for clients connected to it. It starts slave processes to load these images, and share the loaded images through shm with the clients. All the connection done between clients and the server goes through sockets. The cserve2 build option is turned on by default, while the old cserve was disabled, but in order to make clients use it, the environment variable EVAS_CSERVE2 must be set, and a server must be running. Clients will try to find the socket on a specified location using the environment variable EVAS_CSERVE2_SOCKET. If it's not defined, then the XDG_RUNTIME_DIR path should be used, and finally HOME, TMPDIR and /tmp. SVN revision: 70699
Diffstat (limited to 'legacy/evas/src/bin/dummy_slave.c')
-rw-r--r--legacy/evas/src/bin/dummy_slave.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/legacy/evas/src/bin/dummy_slave.c b/legacy/evas/src/bin/dummy_slave.c
new file mode 100644
index 0000000000..a150d67e1f
--- /dev/null
+++ b/legacy/evas/src/bin/dummy_slave.c
@@ -0,0 +1,205 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <errno.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <time.h>
9#include <sys/mman.h>
10#include <fcntl.h>
11#include <unistd.h>
12
13#include "evas_cserve2.h"
14
15static Eina_Bool
16command_read(int fd, Slave_Command *cmd, void **params)
17{
18 ssize_t ret;
19 int ints[2], size, got = 0;
20 char *buf;
21
22 ret = read(fd, ints, sizeof(int) * 2);
23 if (ret < (int)sizeof(int) * 2)
24 return EINA_FALSE;
25
26 size = ints[0];
27 buf = malloc(size);
28 if (!buf) return EINA_FALSE;
29
30 do {
31 ret = read(fd, buf + got, size - got);
32 if (ret < 0)
33 {
34 /* EINTR means we were interrupted by a signal before anything
35 * was sent, and if we are back here it means that signal was
36 * not meant for us to die. Any other error here is fatal and
37 * should result in the slave terminating.
38 */
39 if (errno == EINTR)
40 continue;
41 free(buf);
42 return EINA_FALSE;
43 }
44 got += ret;
45 } while (got < size);
46
47 *cmd = ints[1];
48 *params = buf;
49
50 return EINA_TRUE;
51}
52
53static Eina_Bool
54response_send(int fd, Slave_Command cmd, void *resp, int size)
55{
56 int sent = 0, ints[2];
57 const char *data = resp;
58 ssize_t ret;
59
60 ints[0] = size;
61 ints[1] = cmd;
62 ret = write(fd, ints, sizeof(int) * 2);
63 if (ret < 0)
64 return EINA_FALSE;
65 if (!size)
66 return EINA_TRUE;
67 do {
68 ret = write(fd, data + sent, size - sent);
69 if (ret < 0)
70 {
71 /* EINTR means we were interrupted by a signal before anything
72 * was sent, and if we are back here it means that signal was
73 * not meant for us to die. Any other error here is fatal and
74 * should result in the slave terminating.
75 */
76 if (errno == EINTR)
77 continue;
78 return EINA_FALSE;
79 }
80 sent += ret;
81 } while (sent < size);
82
83 return EINA_TRUE;
84}
85
86static Eina_Bool
87error_send(int fd, Error_Type err)
88{
89 return response_send(fd, ERROR, &err, sizeof(Error_Type));
90}
91
92void *
93cserve2_shm_map(const char *name, size_t length, off_t offset)
94{
95 void *map;
96 int fd;
97
98 fd = shm_open(name, O_RDWR, 0);
99 if (fd == -1)
100 return MAP_FAILED;
101
102 map = mmap(NULL, length, PROT_WRITE, MAP_SHARED, fd, offset);
103
104 close(fd);
105
106 return map;
107}
108
109void
110cserve2_shm_unmap(void *map, size_t length)
111{
112 munmap(map, length);
113}
114
115static Error_Type
116image_open(const char *file __UNUSED__, const char *key __UNUSED__, Slave_Msg_Image_Opened *result)
117{
118 memset(result, 0, sizeof(*result));
119 result->w = 32;
120 result->h = 32;
121 result->frame_count = 1;
122 result->loop_count = 0;
123 result->loop_hint = 0;
124 result->alpha = EINA_TRUE;
125 return CSERVE2_NONE;
126}
127
128static Error_Type
129image_load(const char *shmfile, Slave_Msg_Image_Load *params)
130{
131 char *map = cserve2_shm_map(shmfile, params->shm.mmap_size,
132 params->shm.mmap_offset);
133 if (map == MAP_FAILED)
134 return CSERVE2_RESOURCE_ALLOCATION_FAILED;
135
136 memset(map + params->shm.image_offset, 'A', params->shm.image_size);
137
138 return CSERVE2_NONE;
139}
140
141int main(int c, char **v)
142{
143 int wfd, rfd;
144 Slave_Command cmd;
145 void *params = NULL;;
146 Eina_Bool quit = EINA_FALSE;
147
148 if (c < 3)
149 return 1;
150
151 wfd = atoi(v[1]);
152 rfd = atoi(v[2]);
153
154 while (!quit)
155 {
156 if (!command_read(rfd, &cmd, &params))
157 {
158 error_send(wfd, CSERVE2_INVALID_COMMAND);
159 continue;
160 }
161
162 switch (cmd)
163 {
164 case IMAGE_OPEN:
165 {
166 Slave_Msg_Image_Opened result;
167 Slave_Msg_Image_Open *p;
168 Error_Type err;
169 const char *file, *key;
170 p = params;
171 file = (const char *)(p + sizeof(*p));
172 key = file + strlen(file) + 1;
173 if ((err = image_open(file, key, &result)) != CSERVE2_NONE)
174 error_send(wfd, err);
175 else
176 response_send(wfd, IMAGE_OPEN, &result,
177 sizeof(Slave_Msg_Image_Opened));
178 break;
179 }
180 case IMAGE_LOAD:
181 {
182 Slave_Msg_Image_Load *load_args = params;
183 Error_Type err;
184 const char *shmfile = ((const char *)params) +
185 sizeof(Slave_Msg_Image_Load);
186 if ((err = image_load(shmfile, load_args)) != CSERVE2_NONE)
187 error_send(wfd, err);
188 else
189 response_send(wfd, IMAGE_LOAD, NULL, 0);
190 break;
191 }
192 case SLAVE_QUIT:
193 {
194 quit = EINA_TRUE;
195 break;
196 }
197
198 default:
199 error_send(wfd, CSERVE2_INVALID_COMMAND);
200 }
201 free(params);
202 }
203
204 return 0;
205}