aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/libraries
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/libraries/Runnr.h6
-rw-r--r--src/libraries/SledjHamr.c513
-rw-r--r--src/libraries/SledjHamr.h21
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
8struct _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
17struct _message 8struct _message
18{ 9{
19 Eina_Clist node; 10 Eina_Clist node;
@@ -21,48 +12,6 @@ struct _message
21}; 12};
22 13
23 14
24static 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
36static 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
44static 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
66void *addMessage(Eina_Clist *list, size_t size, const char *message, ...) 15void *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
85void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...) 34static 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
91void 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);
109if (conn) send2(conn, SID, buf); else printf("sendBack() can't find Connection!\n");
101} 110}
102 111
103void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...) 112void 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);
130if (conn) send2(conn, SID, buf); else printf("sendForth() can't find Connection!\n");
119} 131}
120 132
133void 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
139length = 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);
145strcpy(buf, message);
146length = 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
124static Eina_Bool parseStream(void *data, int type, void *evData, int evSize, void *ev) 176static 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
174Eina_Bool parseClientStream(void *data, int type, Ecore_Con_Event_Client_Data *ev) 228static 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
180Eina_Bool parseServerStream(void *data, int type, Ecore_Con_Event_Server_Data *ev) 237static 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
186Eina_Bool clientAdd(void *data, int type, Ecore_Con_Event_Client_Add *ev) 247static 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
208Eina_Bool clientDel(void *data, int type, Ecore_Con_Event_Client_Del *ev) 280static 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
235Connection *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) 318Connection *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
276Eina_Bool serverAdd(void *data, int type, Ecore_Con_Event_Server_Add *ev) 361static 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
301Eina_Bool serverDel(void *data, int type, Ecore_Con_Event_Server_Del *ev) 385static 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
401static 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 414static Eina_Bool _reachOutTimer(void *data)
349#if 1
350Ecore_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
379Connection *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) 485Connection *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
28struct _ConnClient 35struct _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
34struct _Connection 44struct _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
56Ecore_Con_Server *reachOut(char *address, int port, void *data, Ecore_Event_Handler_Cb _add, Ecore_Event_Handler_Cb _data, Ecore_Event_Handler_Cb _del);
57void *addMessage(Eina_Clist *list, size_t size, const char *message, ...); 68void *addMessage(Eina_Clist *list, size_t size, const char *message, ...);
58void sendBack(Ecore_Con_Client *client, const char *SID, const char *message, ...); 69void sendBack(Connection *conn, const char *SID, const char *message, ...);
59void sendForth(Ecore_Con_Server *server, const char *SID, const char *message, ...); 70void sendForth(Connection *conn, const char *SID, const char *message, ...);
60 71
72void send2(Connection *conn, const char *SID, const char *message, ...);
61Connection *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); 73Connection *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);
74Connection *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