summaryrefslogtreecommitdiff
path: root/src/bin/evas/evas_cserve2_messages.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_messages.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_messages.c')
-rw-r--r--src/bin/evas/evas_cserve2_messages.c193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/bin/evas/evas_cserve2_messages.c b/src/bin/evas/evas_cserve2_messages.c
new file mode 100644
index 0000000000..e5cb1b7ee8
--- /dev/null
+++ b/src/bin/evas/evas_cserve2_messages.c
@@ -0,0 +1,193 @@
1#ifdef HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <errno.h>
6#include <string.h>
7
8#include "evas_cserve2.h"
9
10// #define DEBUG_MSG 1
11
12static void
13debug_msg(const char *typestr, const void *buf, int size)
14{
15#ifdef DEBUG_MSG
16 const char *str = buf;
17 int i;
18
19 printf("message %s: ", typestr);
20 for (i = 0; i < size; i++)
21 printf("%x ", str[i]);
22
23 printf("\n");
24#else
25 (void)typestr;
26 (void)buf;
27 (void)size;
28#endif
29}
30
31static void
32_client_msg_allocate_buf(Client *client, int msgsize)
33{
34 client->msg.reading = EINA_TRUE;
35 client->msg.buf = malloc(msgsize + 1);
36 client->msg.size = msgsize;
37 client->msg.done = 0;
38}
39
40static void
41_client_msg_free(Client *client)
42{
43 client->msg.reading = EINA_FALSE;
44 free(client->msg.buf);
45}
46
47static void
48_client_msg_parse(Client *client)
49{
50 Msg_Base *msg = (Msg_Base *)client->msg.buf;
51 DBG("Message received. Size: %d; type = %d",
52 client->msg.size, msg->type);
53
54 cserve2_command_run(client, msg->type);
55}
56
57static void
58_client_msg_read(Client *client, int done)
59{
60 client->msg.done += done;
61 if (client->msg.done == client->msg.size)
62 {
63 debug_msg("received", client->msg.buf, client->msg.size);
64 _client_msg_parse(client);
65 _client_msg_free(client);
66 }
67}
68
69void
70cserve2_message_handler(int fd EINA_UNUSED, Fd_Flags flags, void *data)
71{
72 Client *client = data;
73 int len;
74 int msgsize;
75
76 if (flags & FD_ERROR)
77 {
78 ERR("Error on socket for client: %d", client->id);
79 goto client_close;
80 }
81
82 if (flags & FD_WRITE)
83 cserve2_client_deliver(client);
84
85 if (!(flags & FD_READ))
86 return;
87
88 if (!client->msg.reading)
89 len = cserve2_client_read(client, &msgsize, sizeof(msgsize));
90 else
91 len = cserve2_client_read(client, &client->msg.buf[client->msg.done],
92 client->msg.size - client->msg.done);
93
94 if (!len)
95 {
96 INF("Client %d connection closed.", client->id);
97 goto client_close;
98 }
99
100 if (len < 0)
101 {
102 if (errno == EAGAIN || errno == EWOULDBLOCK)
103 {
104 WRN("No data to read but the message handler was called.");
105 return;
106 }
107 WRN("Error when reading message from client: \"%s\"",
108 strerror(errno));
109 // FIXME: Should we close the connection, or just send an ERROR
110 // message?
111 goto client_close;
112 }
113
114 if (!client->msg.reading)
115 _client_msg_allocate_buf(client, msgsize);
116 else
117 _client_msg_read(client, len);
118
119 return;
120
121client_close:
122 if (client->msg.reading)
123 _client_msg_free(client);
124 cserve2_client_del(client);
125}
126
127void
128cserve2_client_deliver(Client *client)
129{
130 size_t sent, size;
131 const char *str;
132
133 if (!client->msg.pending)
134 {
135 Fd_Flags cur_flags;
136 cserve2_fd_watch_flags_get(client->socket, &cur_flags);
137 cur_flags ^= FD_WRITE;
138 cserve2_fd_watch_flags_set(client->socket, cur_flags);
139 return;
140 }
141
142 size = eina_binbuf_length_get(client->msg.pending);
143 str = (const char *)eina_binbuf_string_get(client->msg.pending);
144 sent = cserve2_client_write(client, str, size);
145 if (sent == size)
146 {
147 eina_binbuf_free(client->msg.pending);
148 client->msg.pending = NULL;
149 return;
150 }
151
152 eina_binbuf_remove(client->msg.pending, 0, sent);
153}
154
155ssize_t
156cserve2_client_send(Client *client, const void *data, size_t size)
157{
158 ssize_t sent;
159
160 debug_msg("sent", data, size);
161 if (client->msg.pending)
162 {
163 eina_binbuf_append_length
164 (client->msg.pending, (unsigned char *)data, size);
165 return size;
166 }
167
168 sent = cserve2_client_write(client, data, size);
169 if ((sent < 0) && ((errno != EAGAIN) && (errno != EWOULDBLOCK)))
170 {
171 // FIXME: Big error when writing on the socket to the client,
172 // so we must close the connection to the client and remove
173 // its references inside our cache.
174 WRN("Error on socket with client %d: %s", client->id, strerror(errno));
175 if (client->msg.reading)
176 _client_msg_free(client);
177 cserve2_client_del(client);
178 return sent;
179 }
180 if (sent < 0)
181 sent = 0;
182 if (sent < (int)size)
183 {
184 Fd_Flags cur_flags;
185 client->msg.pending = eina_binbuf_new();
186 eina_binbuf_append_length
187 (client->msg.pending, (unsigned char *)data + sent, size - sent);
188 cserve2_fd_watch_flags_get(client->socket, &cur_flags);
189 cur_flags |= FD_WRITE;
190 cserve2_fd_watch_flags_set(client->socket, cur_flags);
191 }
192 return size;
193}