diff options
Diffstat (limited to '')
-rw-r--r-- | src/libraries/Runnr.h | 6 | ||||
-rw-r--r-- | src/libraries/SledjHamr.c | 513 | ||||
-rw-r--r-- | src/libraries/SledjHamr.h | 21 |
3 files changed, 326 insertions, 214 deletions
diff --git a/src/libraries/Runnr.h b/src/libraries/Runnr.h index a2098d9..b44dca4 100644 --- a/src/libraries/Runnr.h +++ b/src/libraries/Runnr.h | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <lualib.h> | 12 | #include <lualib.h> |
13 | #include <lauxlib.h> | 13 | #include <lauxlib.h> |
14 | 14 | ||
15 | #include "SledjHamr.h" | ||
16 | |||
15 | // Stick with Plan C for now. | 17 | // Stick with Plan C for now. |
16 | // TODO - Should make this choosable at run time after more testing of Ecore_Thead. | 18 | // TODO - Should make this choosable at run time after more testing of Ecore_Thead. |
17 | #define THREADIT 0 | 19 | #define THREADIT 0 |
@@ -41,7 +43,7 @@ typedef struct _LuaCompile | |||
41 | { | 43 | { |
42 | char *file, *SID, *luaName; | 44 | char *file, *SID, *luaName; |
43 | int bugCount; | 45 | int bugCount; |
44 | Ecore_Con_Client *client; | 46 | Connection *client; |
45 | compileCb parser; | 47 | compileCb parser; |
46 | compileCb cb; | 48 | compileCb cb; |
47 | boolean doConstants; | 49 | boolean doConstants; |
@@ -69,7 +71,7 @@ typedef struct _script | |||
69 | runnrStatus status; | 71 | runnrStatus status; |
70 | RunnrServerCb send2server; | 72 | RunnrServerCb send2server; |
71 | Eina_Clist messages; | 73 | Eina_Clist messages; |
72 | Ecore_Con_Client *client; | 74 | Connection *client; |
73 | Ecore_Timer *timer; | 75 | Ecore_Timer *timer; |
74 | } script; | 76 | } script; |
75 | 77 | ||
diff --git a/src/libraries/SledjHamr.c b/src/libraries/SledjHamr.c index 3445e52..10eeca5 100644 --- a/src/libraries/SledjHamr.c +++ b/src/libraries/SledjHamr.c | |||
@@ -5,15 +5,6 @@ | |||
5 | #include "SledjHamr.h" | 5 | #include "SledjHamr.h" |
6 | 6 | ||
7 | 7 | ||
8 | struct _conct | ||
9 | { | ||
10 | char *address; | ||
11 | int port; | ||
12 | void *pointer; | ||
13 | Ecore_Event_Handler_Cb addCb, dataCb, delCb; | ||
14 | Ecore_Event_Handler *add, *data, *del; | ||
15 | }; | ||
16 | |||
17 | struct _message | 8 | struct _message |
18 | { | 9 | { |
19 | Eina_Clist node; | 10 | Eina_Clist node; |
@@ -21,48 +12,6 @@ struct _message | |||
21 | }; | 12 | }; |
22 | 13 | ||
23 | 14 | ||
24 | static Eina_Bool _add(void *data, int type, Ecore_Con_Event_Server_Del *ev) | ||
25 | { | ||
26 | struct _conct *this = data; | ||
27 | |||
28 | if (this->addCb) | ||
29 | this->addCb(this->pointer, type, ev); | ||
30 | if (this->dataCb) | ||
31 | ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, this->dataCb, this->pointer); | ||
32 | |||
33 | return ECORE_CALLBACK_RENEW; | ||
34 | } | ||
35 | |||
36 | static Eina_Bool _delTimer(void *data) | ||
37 | { | ||
38 | struct _conct *this = data; | ||
39 | |||
40 | reachOut(this->address, this->port, this->pointer, this->addCb, this->dataCb, this->delCb); | ||
41 | return ECORE_CALLBACK_CANCEL; | ||
42 | } | ||
43 | |||
44 | static Eina_Bool _del(void *data, int type, Ecore_Con_Event_Server_Del *ev) | ||
45 | { | ||
46 | struct _conct *this = data; | ||
47 | |||
48 | printf("FAILED connection to server %s:%d, trying again in a second!\n", this->address, this->port); | ||
49 | ecore_event_handler_del(this->add); | ||
50 | ecore_event_handler_del(this->del); | ||
51 | |||
52 | if (this->delCb) | ||
53 | { | ||
54 | if (ECORE_CALLBACK_RENEW == this->delCb(this->pointer, type, ev)) | ||
55 | ecore_timer_add(1.0, _delTimer, this); | ||
56 | } | ||
57 | |||
58 | if (ev->server) ecore_con_server_del(ev->server); | ||
59 | // TODO - Hmm, I think this is where this should be freed, but it causes a seggie in reachOut's while loop. | ||
60 | // Which is odd, so leave it commented for now and investigate later. | ||
61 | // free(this); | ||
62 | |||
63 | return ECORE_CALLBACK_CANCEL; | ||
64 | } | ||
65 | |||
66 | void *addMessage(Eina_Clist *list, size_t size, const char *message, ...) | 15 | void *addMessage(Eina_Clist *list, size_t size, const char *message, ...) |
67 | { | 16 | { |
68 | va_list args; | 17 | va_list args; |
@@ -82,10 +31,68 @@ void *addMessage(Eina_Clist *list, size_t size, const char *message, ...) | |||
82 | return result; | 31 | return result; |
83 | } | 32 | } |
84 | 33 | ||
85 | void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...) | 34 | static boolean checkConnection(Connection *conn, char *func, connType wanted, boolean isLocal) |
35 | { | ||
36 | boolean result = TRUE; | ||
37 | |||
38 | if ((conn->type != CT_CLIENT) && (conn->type != CT_SERVER)) | ||
39 | { | ||
40 | result = FALSE; | ||
41 | printf("CONNECTION OBJECT in %s() is of unknown type %d\n", func, (int) conn->type); | ||
42 | } | ||
43 | else if (conn->type != wanted) | ||
44 | { | ||
45 | result = FALSE; | ||
46 | switch (wanted) | ||
47 | { | ||
48 | case CT_CLIENT : | ||
49 | if (conn->type == CT_SERVER) | ||
50 | printf("INVALID CONNECTION OBJECT in %s(), it might be a server object!\n", func); | ||
51 | else | ||
52 | printf("INVALID CONNECTION OBJECT in %s(), type is %d!\n", func, (int) conn->type); | ||
53 | if (conn->conn.client.myServer == NULL) | ||
54 | printf("CONNECTION OBJECT in %s() is a local client, but should be a remote client mirror!\n", func); | ||
55 | break; | ||
56 | |||
57 | case CT_SERVER : | ||
58 | if (conn->type == CT_CLIENT) | ||
59 | printf("INVALID CONNECTION OBJECT in %s(), it might be a client object!\n", func); | ||
60 | else | ||
61 | printf("INVALID CONNECTION OBJECT in %s(), type is %d!\n", func, (int) conn->type); | ||
62 | if (isLocal) | ||
63 | { | ||
64 | if (conn->conn.server.clients == NULL) | ||
65 | printf("CONNECTION OBJECT in %s() is a remote server mirror, but should be a local server!\n", func); | ||
66 | } | ||
67 | else | ||
68 | { | ||
69 | if (conn->conn.server.clients != NULL) | ||
70 | printf("CONNECTION OBJECT in %s() is a local server, but should be a remote server mirror!\n", func); | ||
71 | } | ||
72 | break; | ||
73 | |||
74 | default : | ||
75 | printf("CONNECTION OBJECT in %s(), silly coder asked for an unknown type!""\n", func); | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | if (NULL == conn->name) | ||
80 | { | ||
81 | result = FALSE; | ||
82 | printf("CONNECTION OBJECT in %s() has no name!\n", func); | ||
83 | } | ||
84 | } | ||
85 | |||
86 | //if (result) printf("%s(\"%s\")\n", func, conn->name); | ||
87 | |||
88 | return result; | ||
89 | } | ||
90 | |||
91 | void sendBack(Connection *conn, const char *SID, const char *message, ...) | ||
86 | { | 92 | { |
87 | va_list args; | 93 | va_list args; |
88 | char buf[PATH_MAX]; | 94 | // Ecore_Con_Client *client = conn->conn.client.client; |
95 | char buf[PATH_MAX * 2]; | ||
89 | int length = strlen(SID); | 96 | int length = strlen(SID); |
90 | 97 | ||
91 | strncpy(buf, SID, length); | 98 | strncpy(buf, SID, length); |
@@ -95,15 +102,18 @@ void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, .. | |||
95 | va_end(args); | 102 | va_end(args); |
96 | buf[length++] = '\n'; | 103 | buf[length++] = '\n'; |
97 | buf[length] = '\0'; | 104 | buf[length] = '\0'; |
98 | // printf("sendBack(%s)", buf); | 105 | // printf("sendBack(%s", buf); |
99 | ecore_con_client_send(client, buf, length); | 106 | // ecore_con_client_send(client, buf, length); |
100 | ecore_con_client_flush(client); | 107 | // ecore_con_client_flush(client); |
108 | //Connection *conn = ecore_con_client_data_get(client); | ||
109 | if (conn) send2(conn, SID, buf); else printf("sendBack() can't find Connection!\n"); | ||
101 | } | 110 | } |
102 | 111 | ||
103 | void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...) | 112 | void sendForth(Connection *conn, const char *SID, const char *message, ...) |
104 | { | 113 | { |
105 | va_list args; | 114 | va_list args; |
106 | char buf[PATH_MAX]; | 115 | // Ecore_Con_Server *server = conn->conn.server.server; |
116 | char buf[PATH_MAX * 2]; | ||
107 | int length = strlen(SID); | 117 | int length = strlen(SID); |
108 | 118 | ||
109 | strncpy(buf, SID, length); | 119 | strncpy(buf, SID, length); |
@@ -113,123 +123,196 @@ void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, . | |||
113 | va_end(args); | 123 | va_end(args); |
114 | buf[length++] = '\n'; | 124 | buf[length++] = '\n'; |
115 | buf[length] = '\0'; | 125 | buf[length] = '\0'; |
116 | // printf("sendForth(%s)", buf); | 126 | // printf("sendForth(%s", buf); |
117 | ecore_con_server_send(server, buf, length); | 127 | // ecore_con_server_send(server, buf, length); |
118 | ecore_con_server_flush(server); | 128 | // ecore_con_server_flush(server); |
129 | //Connection *conn = ecore_con_server_data_get(server); | ||
130 | if (conn) send2(conn, SID, buf); else printf("sendForth() can't find Connection!\n"); | ||
119 | } | 131 | } |
120 | 132 | ||
133 | void send2(Connection *conn, const char *SID, const char *message, ...) | ||
134 | { | ||
135 | va_list args; | ||
136 | char buf[PATH_MAX * 2]; | ||
137 | int length = strlen(SID); | ||
121 | 138 | ||
139 | length = 0; | ||
140 | // strncpy(buf, SID, length); | ||
141 | // buf[length++] = '.'; | ||
142 | va_start(args, message); | ||
143 | // length += vsprintf(&buf[length], message, args); | ||
144 | va_end(args); | ||
145 | strcpy(buf, message); | ||
146 | length = strlen(buf); | ||
147 | // buf[length++] = '\n'; | ||
148 | buf[length] = '\0'; | ||
122 | 149 | ||
150 | // TODO - Should check if this is always gonna be local? Likely not. | ||
151 | if (checkConnection(conn, "send2", conn->type, FALSE)) | ||
152 | { | ||
153 | switch (conn->type) | ||
154 | { | ||
155 | case CT_CLIENT : | ||
156 | // printf("vvv send2(%*s", length, buf); | ||
157 | ecore_con_client_send(conn->conn.client.client, strndup(buf, length), length); | ||
158 | ecore_con_client_flush(conn->conn.client.client); | ||
159 | break; | ||
160 | |||
161 | case CT_SERVER : | ||
162 | // printf("^^^ send2(%*s", length, buf); | ||
163 | ecore_con_server_send(conn->conn.server.server, strndup(buf, length), length); | ||
164 | ecore_con_server_flush(conn->conn.server.server); | ||
165 | break; | ||
166 | |||
167 | default : | ||
168 | printf("send2() unable to send to partially bogus Connection object!\n"); | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | else | ||
173 | printf("send2() unable to send to bogus Connection object!\n"); | ||
174 | } | ||
123 | 175 | ||
124 | static Eina_Bool parseStream(void *data, int type, void *evData, int evSize, void *ev) | 176 | static Eina_Bool parseStream(void *data, int type, void *evData, int evSize, void *ev) |
125 | { | 177 | { |
126 | Connection *connection = data; | 178 | Connection *conn = data; |
127 | char SID[PATH_MAX]; | 179 | char SID[PATH_MAX]; |
128 | const char *command; | 180 | const char *command; |
129 | char *ext; | 181 | char *ext; |
130 | 182 | ||
131 | if (NULL == connection->stream) | 183 | //printf("parseStream(%s, \"%*s\")\n", conn->name, evSize, (char *) evData); |
132 | connection->stream = eina_strbuf_new(); | 184 | if (NULL == conn->stream) |
185 | conn->stream = eina_strbuf_new(); | ||
133 | 186 | ||
134 | eina_strbuf_append_length(connection->stream, evData, evSize); | 187 | eina_strbuf_append_length(conn->stream, evData, evSize); |
135 | command = eina_strbuf_string_get(connection->stream); | 188 | command = eina_strbuf_string_get(conn->stream); |
136 | while ((ext = index(command, '\n'))) | 189 | while ((ext = index(command, '\n'))) |
137 | { | 190 | { |
138 | int length = ext - command; | 191 | int length = ext - command; |
139 | 192 | ||
140 | strncpy(SID, command, length + 1); | 193 | strncpy(SID, command, length + 1); |
141 | SID[length] = '\0'; | 194 | SID[length] = '\0'; |
142 | eina_strbuf_remove(connection->stream, 0, length + 1); | 195 | eina_strbuf_remove(conn->stream, 0, length + 1); |
143 | ext = index(SID, '.'); | 196 | ext = index(SID, '.'); |
144 | if (ext) | 197 | if (ext) |
145 | { | 198 | { |
146 | ext[0] = '\0'; | 199 | ext[0] = '\0'; |
147 | command = ext + 1; | 200 | command = ext + 1; |
148 | ext = index(SID, '('); | 201 | ext = index(command, '('); |
149 | if (ext) | 202 | if (ext) |
150 | { | 203 | { |
151 | streamParser func = eina_hash_find(connection->commands, command); | 204 | streamParser func = eina_hash_find(conn->commands, command); |
152 | //PW("COMMAND - %s", command); | 205 | //printf("parseStream(%s>> %s\"\n", conn->name, command); |
153 | |||
154 | ext[0] = '\0'; | ||
155 | 206 | ||
207 | // ext[0] = '\0'; | ||
156 | // Need a callback if we can't find the command. | 208 | // Need a callback if we can't find the command. |
157 | if (NULL == func) | 209 | if (NULL == func) |
158 | func = connection->unknownCommand; | 210 | func = conn->unknownCommand; |
159 | if (func) | 211 | if (func) |
160 | func(data, connection, SID, (char *) command, ext + 1); | 212 | func(conn->pointer, conn, SID, (char *) command, ext + 1); |
213 | else | ||
214 | printf("parseStream() No function found for command %s!\n", command); | ||
161 | } | 215 | } |
162 | } | 216 | } |
163 | 217 | ||
164 | // Get the next blob to check it. | 218 | // Get the next blob to check it. |
165 | command = eina_strbuf_string_get(connection->stream); | 219 | command = eina_strbuf_string_get(conn->stream); |
166 | } | 220 | } |
167 | 221 | ||
168 | if (connection->_data) | 222 | if (conn->_data) |
169 | connection->_data(data, type, ev); | 223 | conn->_data(conn->pointer, type, ev); |
170 | 224 | ||
171 | return ECORE_CALLBACK_RENEW; | 225 | return ECORE_CALLBACK_RENEW; |
172 | } | 226 | } |
173 | 227 | ||
174 | Eina_Bool parseClientStream(void *data, int type, Ecore_Con_Event_Client_Data *ev) | 228 | static Eina_Bool parseClientStream(void *data, int type, Ecore_Con_Event_Client_Data *ev) |
175 | { | 229 | { |
176 | // data is the server connection, but we want the client one. | 230 | Connection *conn = /*data*/ ecore_con_client_data_get(ev->client); |
177 | return parseStream(ecore_con_client_data_get(ev->client), type, ev->data, ev->size, ev); | 231 | |
232 | if (checkConnection(conn, "parseClientStream", CT_CLIENT, FALSE)) | ||
233 | return parseStream(conn, type, ev->data, ev->size, ev); | ||
234 | return ECORE_CALLBACK_RENEW; | ||
178 | } | 235 | } |
179 | 236 | ||
180 | Eina_Bool parseServerStream(void *data, int type, Ecore_Con_Event_Server_Data *ev) | 237 | static Eina_Bool parseServerStream(void *data, int type, Ecore_Con_Event_Server_Data *ev) |
181 | { | 238 | { |
182 | return parseStream(data, type, ev->data, ev->size, ev); | 239 | Connection *conn = /*data*/ ecore_con_server_data_get(ev->server); |
183 | } | 240 | |
241 | if (checkConnection(conn, "parseServerStream", CT_SERVER, FALSE)) | ||
242 | return parseStream(conn, type, ev->data, ev->size, ev); | ||
184 | 243 | ||
244 | return ECORE_CALLBACK_RENEW; | ||
245 | } | ||
185 | 246 | ||
186 | Eina_Bool clientAdd(void *data, int type, Ecore_Con_Event_Client_Add *ev) | 247 | static Eina_Bool clientAdd(void *data, int type, Ecore_Con_Event_Client_Add *ev) |
187 | { | 248 | { |
188 | Connection *conn, *connection = data; | 249 | Connection *conn, *connection = data; |
189 | 250 | ||
251 | if (checkConnection(connection, "clientAdd", CT_SERVER, TRUE)) | ||
252 | { | ||
190 | ecore_con_client_timeout_set(ev->client, 0); | 253 | ecore_con_client_timeout_set(ev->client, 0); |
191 | conn = calloc(1, sizeof(Connection)); | 254 | conn = calloc(1, sizeof(Connection)); |
192 | conn->type = CT_CLIENT; | 255 | conn->type = CT_CLIENT; |
193 | conn->conn.client.client = ev->client; | 256 | conn->conn.client.client = ev->client; |
194 | conn->conn.client.myServer = connection; | 257 | conn->conn.client.myServer = connection; |
258 | conn->conn.client.server = malloc(sizeof(Eina_Clist)); | ||
259 | eina_clist_element_init(conn->conn.client.server); | ||
260 | eina_clist_add_tail(connection->conn.server.clients, conn->conn.client.server); | ||
195 | conn->name = strdup(connection->name); | 261 | conn->name = strdup(connection->name); |
196 | conn->address = strdup(connection->address); | 262 | conn->address = strdup(connection->address); |
197 | conn->port = connection->port; | 263 | conn->port = connection->port; |
198 | conn->pointer = connection->pointer; | 264 | conn->pointer = connection->pointer; |
265 | conn->_add = connection->_add; | ||
266 | conn->_data = connection->_data; | ||
267 | conn->_del = connection->_del; | ||
268 | conn->unknownCommand = connection->unknownCommand; | ||
199 | conn->commands = eina_hash_string_superfast_new(NULL); | 269 | conn->commands = eina_hash_string_superfast_new(NULL); |
200 | ecore_con_client_data_set(ev->client, conn); | 270 | ecore_con_client_data_set(ev->client, conn); |
201 | 271 | ||
202 | if (connection->_add) | 272 | if (connection->_add) |
203 | return connection->_add(connection->pointer, type, ev); | 273 | return connection->_add(connection->pointer, type, ev); |
204 | 274 | ||
205 | return ECORE_CALLBACK_RENEW; | 275 | } |
276 | |||
277 | return ECORE_CALLBACK_RENEW; | ||
206 | } | 278 | } |
207 | 279 | ||
208 | Eina_Bool clientDel(void *data, int type, Ecore_Con_Event_Client_Del *ev) | 280 | static Eina_Bool clientDel(void *data, int type, Ecore_Con_Event_Client_Del *ev) |
209 | { | 281 | { |
210 | Connection *connection = data; | 282 | Connection *conn = data; |
211 | 283 | ||
284 | if (checkConnection(conn, "clientDel", CT_SERVER, TRUE)) | ||
285 | { | ||
212 | if (ev->client) | 286 | if (ev->client) |
213 | { | 287 | { |
214 | Eina_List const *clients; | 288 | Eina_List const *clients; |
215 | 289 | ||
290 | if (conn->_del) | ||
291 | conn->_del(conn->pointer, type, ev); | ||
292 | |||
293 | ecore_con_client_del(ev->client); | ||
294 | |||
295 | |||
216 | // This is only really for testing, normally it just runs 24/7, or until told not to. | 296 | // This is only really for testing, normally it just runs 24/7, or until told not to. |
217 | clients = ecore_con_server_clients_get(connection->conn.server.server); | 297 | // The "- 1" is coz this server is still counted. |
298 | clients = ecore_con_server_clients_get(conn->conn.server.server) - 1; | ||
218 | if (0 == eina_list_count(clients)) | 299 | if (0 == eina_list_count(clients)) |
219 | printf("No more clients, exiting."); | 300 | printf("No more clients for %s, exiting.\n", conn->name); |
220 | else | 301 | else |
221 | printf("Some %d more clients, exiting anyway.", eina_list_count(clients)); | 302 | printf("Some (%d) more clients for %s, exiting anyway.\n", eina_list_count(clients), conn->name); |
222 | |||
223 | // TODO - Probably should just keep running, both servers, and go away when all clients are gone for testing. | ||
224 | 303 | ||
225 | if (connection->_del) | 304 | // TODO - the Connection free function should take care of all of this, and we should call it here. ish. |
226 | connection->_del(connection->pointer, type, ev); | 305 | eina_clist_remove(conn->conn.client.server); |
306 | free(conn->conn.client.server); | ||
307 | conn->conn.client.server = NULL; | ||
227 | 308 | ||
228 | ecore_con_client_del(ev->client); | 309 | // TODO - Probably should just keep running, both servers, and go away when all clients are gone for testing. |
229 | ecore_main_loop_quit(); | 310 | ecore_main_loop_quit(); |
230 | } | 311 | } |
312 | } | ||
231 | 313 | ||
232 | return ECORE_CALLBACK_RENEW; | 314 | free(conn); |
315 | return ECORE_CALLBACK_RENEW; | ||
233 | } | 316 | } |
234 | 317 | ||
235 | Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser) | 318 | Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser) |
@@ -238,11 +321,11 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor | |||
238 | Ecore_Con_Server *server; | 321 | Ecore_Con_Server *server; |
239 | 322 | ||
240 | conn->type = CT_SERVER; | 323 | conn->type = CT_SERVER; |
241 | // conn->conn.server.serverCommand = ; | 324 | conn->conn.server.clients = malloc(sizeof(Eina_Clist)); |
325 | eina_clist_init(conn->conn.server.clients); | ||
242 | conn->name = strdup(name); | 326 | conn->name = strdup(name); |
243 | conn->address = strdup(address); | 327 | conn->address = strdup(address); |
244 | conn->port = port; | 328 | conn->port = port; |
245 | |||
246 | conn->pointer = data; | 329 | conn->pointer = data; |
247 | conn->_add = _add; | 330 | conn->_add = _add; |
248 | conn->_data = _data; | 331 | conn->_data = _data; |
@@ -250,21 +333,23 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor | |||
250 | conn->unknownCommand = _parser; | 333 | conn->unknownCommand = _parser; |
251 | conn->commands = eina_hash_string_superfast_new(NULL); | 334 | conn->commands = eina_hash_string_superfast_new(NULL); |
252 | 335 | ||
253 | if ((server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, address, port, data))) | 336 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb) clientAdd, conn); |
337 | conn->data = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb) parseClientStream, conn); | ||
338 | conn->del = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb) clientDel, conn); | ||
339 | // conn->died = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _serverDied, conn); | ||
340 | |||
341 | if ((server = ecore_con_server_add(ECORE_CON_REMOTE_TCP, address, port, conn))) | ||
254 | { | 342 | { |
255 | conn->conn.server.server = server; | 343 | conn->conn.server.server = server; |
256 | 344 | ecore_con_server_timeout_set(server, 0); | |
257 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_ADD, (Ecore_Event_Handler_Cb) clientAdd, conn); | 345 | ecore_con_server_client_limit_set(server, -1, 0); |
258 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DATA, (Ecore_Event_Handler_Cb) parseClientStream, conn); | 346 | // ecore_con_server_timeout_set(server, 10); |
259 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_CLIENT_DEL, (Ecore_Event_Handler_Cb) clientDel, conn); | 347 | // ecore_con_server_client_limit_set(server, 3, 0); |
260 | ecore_con_server_timeout_set(server, 0); | 348 | printf("ACTUALLY created the %s server %s:%d.\n", name, address, port); |
261 | ecore_con_server_client_limit_set(server, -1, 0); | ||
262 | ecore_con_server_data_set(server, conn); | ||
263 | // ecore_con_server_timeout_set(server, 10); | ||
264 | // ecore_con_server_client_limit_set(server, 3, 0); | ||
265 | } | 349 | } |
266 | else | 350 | else |
267 | { | 351 | { |
352 | // TODO - Connection needs a generic free function. Only reason we are getting away with this is during initial testing, the Connections last the entire run anyway. | ||
268 | free(conn->address); | 353 | free(conn->address); |
269 | free(conn); | 354 | free(conn); |
270 | conn = NULL; | 355 | conn = NULL; |
@@ -273,142 +358,154 @@ Connection *openArms(char *name, const char *address, int port, void *data, Ecor | |||
273 | return conn; | 358 | return conn; |
274 | } | 359 | } |
275 | 360 | ||
276 | Eina_Bool serverAdd(void *data, int type, Ecore_Con_Event_Server_Add *ev) | 361 | static Eina_Bool serverAdd(void *data, int type, Ecore_Con_Event_Server_Add *ev) |
277 | { | 362 | { |
278 | Connection *connection = data; | 363 | Connection *conn = data; |
279 | |||
280 | connection->conn.server.hackyCount++; | ||
281 | 364 | ||
282 | // Alledgedly this checks for real conections, but given that the first time it's called, there's no real connection, this is failing somehow. | 365 | if (checkConnection(conn, "serverAdd", CT_SERVER, FALSE)) |
283 | //if (ecore_con_server_connected_get(ev->server)) | ||
284 | if (connection->conn.server.hackyCount <= 1) | ||
285 | printf("Bogus server ignored."); | ||
286 | else | ||
287 | { | 366 | { |
288 | printf("Connected to %s server.", connection->name); | 367 | conn->conn.server.hackyCount++; |
289 | connection->conn.server.server = ev->server; | 368 | conn->stage++; |
290 | // In case the server crashed, clear out any waiting data. | ||
291 | if (connection->stream) | ||
292 | eina_strbuf_reset(connection->stream); | ||
293 | 369 | ||
294 | if (connection->_add) | 370 | if (conn->name) |
295 | connection->_add(data, type, ev); | 371 | printf("serverAdd()^^^^^^^^^^^^^^^^^^^^^^^Connected to %s server.\n", conn->name); |
372 | else | ||
373 | printf("serverAdd()^^^^^^^^^^^^^^^^^^^^^^^Connected to UNKNOWN server.\n"); | ||
374 | |||
375 | // In case the server crashed, clear out any waiting data. | ||
376 | if (conn->stream) | ||
377 | eina_strbuf_reset(conn->stream); | ||
378 | if (conn->_add) | ||
379 | conn->_add(conn->pointer, type, ev); | ||
296 | } | 380 | } |
297 | 381 | ||
298 | return ECORE_CALLBACK_RENEW; | 382 | return ECORE_CALLBACK_RENEW; |
299 | } | 383 | } |
300 | 384 | ||
301 | Eina_Bool serverDel(void *data, int type, Ecore_Con_Event_Server_Del *ev) | 385 | static Eina_Bool serverDel(void *data, int type, Ecore_Con_Event_Server_Del *ev) |
302 | { | 386 | { |
303 | Connection *connection = data; | 387 | Eina_Bool result = ECORE_CALLBACK_RENEW; |
388 | Connection *conn = data; | ||
304 | 389 | ||
305 | connection->conn.server.server = NULL; | 390 | if (checkConnection(conn, "serverDel", CT_SERVER, FALSE)) |
306 | |||
307 | // connection->server.hackyCount--; | ||
308 | // Let it fail a couple of times during startup, then try to start our own script server. | ||
309 | connection->conn.server.count++; | ||
310 | if (1 < connection->conn.server.count) | ||
311 | { | 391 | { |
312 | char buf[PATH_MAX]; | 392 | conn->conn.server.server = NULL; |
313 | 393 | conn->stage = -3; | |
314 | printf("Failed to connect to a %s server, starting our own.", connection->name); | 394 | if (conn->_del) |
315 | // TODO - Should use Ecore_Exe for this sort of thing. | 395 | result = conn->_del(conn->pointer, type, ev); |
316 | sprintf(buf, "%s/%s &", prefix_bin_get(), connection->conn.server.serverCommand); | ||
317 | system(buf); | ||
318 | connection->conn.server.count = 0; | ||
319 | // TODO - There's also the question of what to do if the connection failed. | ||
320 | // Did the server crash, or was it just the connection? | ||
321 | // Probably gonna need some smarts, for now we just restart all the scripts. | ||
322 | // Which I think gets done on server add. | ||
323 | } | 396 | } |
324 | 397 | ||
325 | if (connection->_del) | 398 | return result; |
326 | connection->_del(data, type, ev); | 399 | } |
327 | |||
328 | |||
329 | // TODO - May want to renew even if it's not running the GUI, but then we still need some sort of "shut down" signal, which we don't need during testing. | ||
330 | // if (ourGlobals->ui) | ||
331 | return ECORE_CALLBACK_RENEW; | ||
332 | |||
333 | // ecore_main_loop_quit(); | ||
334 | |||
335 | // return ECORE_CALLBACK_CANCEL; | ||
336 | |||
337 | 400 | ||
401 | static Eina_Bool _serverDied(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) | ||
402 | { | ||
403 | Connection *conn = data; | ||
404 | // Ecore_Exe_Event_Data *dataFromProcess = (Ecore_Exe_Event_Data *)event; | ||
338 | 405 | ||
339 | /* Extantz does this instead of the above returns - | 406 | conn->stage = -3; |
407 | conn->conn.server.serverHandle = NULL; | ||
408 | conn->conn.server.pid = 0; | ||
340 | 409 | ||
341 | if (ourGlobals->running) | 410 | return ECORE_CALLBACK_DONE; |
342 | return ECORE_CALLBACK_RENEW; | ||
343 | return ECORE_CALLBACK_CANCEL; | ||
344 | */ | ||
345 | } | 411 | } |
346 | 412 | ||
347 | 413 | // TODO - instead of a timer, try to make this event driven. Use jobs, or idler, or something. | |
348 | 414 | static Eina_Bool _reachOutTimer(void *data) | |
349 | #if 1 | ||
350 | Ecore_Con_Server *reachOut(char *address, int port, void *data, Ecore_Event_Handler_Cb _addCb, Ecore_Event_Handler_Cb _dataCb, Ecore_Event_Handler_Cb _delCb) | ||
351 | { | 415 | { |
416 | Eina_Bool result = ECORE_CALLBACK_RENEW; | ||
417 | Connection *conn = data; | ||
352 | Ecore_Con_Server *server = NULL; | 418 | Ecore_Con_Server *server = NULL; |
353 | struct _conct *this = malloc(sizeof(struct _conct)); | 419 | |
354 | int count = 0; | 420 | switch (conn->stage) |
355 | |||
356 | this->address = address; | ||
357 | this->port = port; | ||
358 | this->pointer = data; | ||
359 | this->addCb = _addCb; | ||
360 | this->dataCb = _dataCb; | ||
361 | this->delCb = _delCb; | ||
362 | // This loop is overkill I think. | ||
363 | while ((!server) && (10 > count)) | ||
364 | { | 421 | { |
365 | if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, address, port, this->pointer))) | 422 | // TODO - Seems Ecore_con now has trouble with my try first, then start method, so start first, then try. Fix this, or do something else. |
366 | { | 423 | case -3 : |
367 | this->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) _add, this); | 424 | printf("Failed to connect to a %s server, starting our own.\n", conn->name); |
368 | this->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) _del, this); | 425 | conn->conn.server.serverHandle = ecore_exe_pipe_run(conn->conn.server.serverCommand, ECORE_EXE_NONE /*| ECORE_EXE_TERM_WITH_PARENT*/, conn); |
369 | } | 426 | if (conn->conn.server.serverHandle) |
370 | count++; | 427 | { |
371 | } | 428 | conn->conn.server.pid = ecore_exe_pid_get(conn->conn.server.serverHandle); |
429 | if (conn->conn.server.pid == -1) | ||
430 | fprintf(stderr, "Could not retrive the PID!\n"); | ||
431 | else | ||
432 | fprintf(stdout, "The child process has PID:%u\n", (unsigned int)conn->conn.server.pid); | ||
433 | } | ||
434 | else | ||
435 | fprintf(stderr, "Could not create server process %s!\n", conn->conn.server.serverCommand); | ||
436 | |||
437 | // TODO - There's also the question of what to do if the connection failed. | ||
438 | // Did the server crash, or was it just the connection? | ||
439 | // Also, I'm assuming the connection failed here, rather than went away after running for some time. Should differentiate. | ||
440 | // Probably gonna need some smarts, for now we just restart all the scripts. | ||
441 | // Which I think gets done on server add. | ||
442 | break; | ||
443 | |||
444 | // TODO - Alternate strategy : Keep track of if we started a server, then keep pinging it's port until it answers, | ||
445 | // with a timeout until we kill the server and start again. | ||
446 | |||
447 | case -2 : // Give the server some time to start up. | ||
448 | case -1 : // Give the server some time to start up. | ||
449 | // Check if the server is still running here, if not, reset stage to previous -3 (taking into account the increment at the end). | ||
450 | if (conn->conn.server.pid) | ||
451 | printf("Waiting for %s server to start from command \"%s\"\n", conn->name, conn->conn.server.serverCommand); | ||
452 | else | ||
453 | conn->stage = -4; | ||
454 | break; | ||
455 | |||
456 | case 0 : | ||
457 | printf("Attempting to connect to the %s server %s:%d.\n", conn->name, conn->address, conn->port); | ||
458 | // This should only return NULL if something goes wrong with the setup, | ||
459 | // you wont know if the connection worked until you get the add callback, | ||
460 | // or you get the del calback if it failed. | ||
461 | if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, conn->address, conn->port, conn))) | ||
462 | printf("MAYBE connecting to the %s server %s:%d.\n", conn->name, conn->address, conn->port); | ||
463 | else | ||
464 | printf("FAILED to create the connection to the %s server %s:%d!\n", conn->name, conn->address, conn->port); | ||
465 | conn->conn.server.server = server; | ||
466 | break; | ||
372 | 467 | ||
373 | if (!server) | 468 | case 1 : // This stage is the serverAdd callback. |
374 | printf("Failed to connect to server %s:%d!\n", this->address, this->port); | 469 | break; |
375 | 470 | ||
376 | return server; | 471 | case 2 : // Give the server a chance to die. |
472 | break; | ||
473 | |||
474 | default : | ||
475 | if (5 < conn->stage) | ||
476 | conn->stage = 2; // loop back to nothing. | ||
477 | // result = ECORE_CALLBACK_CANCEL; | ||
478 | break; | ||
479 | } | ||
480 | conn->stage++; | ||
481 | |||
482 | return result; | ||
377 | } | 483 | } |
378 | #else | 484 | |
379 | Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del) | 485 | Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser) |
380 | { | 486 | { |
381 | Connection *conn = calloc(1, sizeof(Connection)); | 487 | Connection *conn = calloc(1, sizeof(Connection)); |
382 | Ecore_Con_Server *server = NULL; | ||
383 | int count = 0; | ||
384 | 488 | ||
385 | conn->type = CT_SERVER; | 489 | conn->type = CT_SERVER; |
386 | conn->conn.server.serverCommand = strdup(command); | 490 | conn->conn.server.serverCommand = strdup(command); |
491 | // Sure, this is essentially a NOP, but lets be explicit here, this is a remote server, so no list of clients, not just an empty list. | ||
492 | conn->conn.server.clients = NULL; | ||
387 | conn->name = strdup(name); | 493 | conn->name = strdup(name); |
388 | conn->address = strdup(address); | 494 | conn->address = strdup(address); |
389 | conn->port = port; | 495 | conn->port = port; |
390 | conn->pointer = data; | 496 | conn->pointer = data; |
391 | conn-> = _add; | 497 | conn->_add = _add; |
392 | conn-> = _data; | 498 | conn->_data = _data; |
393 | conn-> = _del; | 499 | conn->_del = _del; |
500 | conn->unknownCommand = _parser; | ||
394 | conn->commands = eina_hash_string_superfast_new(NULL); | 501 | conn->commands = eina_hash_string_superfast_new(NULL); |
395 | 502 | ||
396 | // This loop is overkill I think. | 503 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) serverAdd, conn); |
397 | while ((!server) && (10 > count)) | 504 | conn->data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb) parseServerStream, conn); |
398 | { | 505 | conn->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) serverDel, conn); |
399 | if ((server = ecore_con_server_connect(ECORE_CON_REMOTE_TCP, address, port, data))) | 506 | conn->died = ecore_event_handler_add(ECORE_EXE_EVENT_DEL, _serverDied, conn); |
400 | { | ||
401 | conn->add = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_ADD, (Ecore_Event_Handler_Cb) serverAdd, conn); | ||
402 | conn->data = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DATA, (Ecore_Event_Handler_Cb) parseServerStream, conn); | ||
403 | conn->del = ecore_event_handler_add(ECORE_CON_EVENT_SERVER_DEL, (Ecore_Event_Handler_Cb) serverDel, conn); | ||
404 | ecore_con_server_data_set(server, conn); | ||
405 | } | ||
406 | count++; | ||
407 | } | ||
408 | 507 | ||
409 | if (!server) | 508 | ecore_timer_add(1.0, _reachOutTimer, conn); |
410 | printf("Failed to connect to the %s server %s:%d!\n", name, address, port); | ||
411 | 509 | ||
412 | return conn; | 510 | return conn; |
413 | } | 511 | } |
414 | #endif | ||
diff --git a/src/libraries/SledjHamr.h b/src/libraries/SledjHamr.h index 467fcc6..326e423 100644 --- a/src/libraries/SledjHamr.h +++ b/src/libraries/SledjHamr.h | |||
@@ -23,12 +23,22 @@ struct _ConnServer | |||
23 | Ecore_Con_Server *server; | 23 | Ecore_Con_Server *server; |
24 | char *serverCommand; | 24 | char *serverCommand; |
25 | int count, hackyCount; | 25 | int count, hackyCount; |
26 | // A list of connected remote clients. | ||
27 | // A NULL list means this is a remote server stored in a local clients Connection. | ||
28 | // An empty list means this is a local server, with no clients. | ||
29 | // An actual list means this is a local server, with connected remote clients. | ||
30 | Eina_Clist *clients; // HEAD element. | ||
31 | Ecore_Exe *serverHandle; // For running the server. | ||
32 | pid_t pid; | ||
26 | }; | 33 | }; |
27 | 34 | ||
28 | struct _ConnClient | 35 | struct _ConnClient |
29 | { | 36 | { |
30 | Ecore_Con_Client *client; | 37 | Ecore_Con_Client *client; |
38 | // If this is a local client, then myServer is a server Connection representing the remote server, and the server list entry element can be NULL. | ||
39 | // If this is a remote client, then myServer is NULL, and this Connection is stored in a list in the local server's Connection. | ||
31 | Connection *myServer; | 40 | Connection *myServer; |
41 | Eina_Clist *server; // Entry element. | ||
32 | }; | 42 | }; |
33 | 43 | ||
34 | struct _Connection | 44 | struct _Connection |
@@ -48,16 +58,19 @@ struct _Connection | |||
48 | // Callbacks. | 58 | // Callbacks. |
49 | void *pointer; | 59 | void *pointer; |
50 | Ecore_Event_Handler_Cb _add, _data, _del; | 60 | Ecore_Event_Handler_Cb _add, _data, _del; |
51 | Ecore_Event_Handler *add, *data, *del; | 61 | Ecore_Event_Handler *add, *data, *del, *died; |
52 | streamParser unknownCommand; | 62 | streamParser unknownCommand; |
63 | |||
64 | int stage; // Stage of creation for the Connection. | ||
53 | }; | 65 | }; |
54 | 66 | ||
55 | 67 | ||
56 | Ecore_Con_Server *reachOut(char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del); | ||
57 | void *addMessage(Eina_Clist *list, size_t size, const char *message, ...); | 68 | void *addMessage(Eina_Clist *list, size_t size, const char *message, ...); |
58 | void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...); | 69 | void sendBack(Connection *conn, const char *SID, const char *message, ...); |
59 | void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...); | 70 | void sendForth(Connection *conn, const char *SID, const char *message, ...); |
60 | 71 | ||
72 | void send2(Connection *conn, const char *SID, const char *message, ...); | ||
61 | Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser); | 73 | Connection *openArms(char *name, const char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser); |
74 | Connection *reachOut(char *name, char *command, char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del, streamParser _parser); | ||
62 | 75 | ||
63 | #endif | 76 | #endif |