diff options
author | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-11-23 19:45:33 -0200 |
---|---|---|
committer | Gustavo Sverzut Barbieri <barbieri@profusion.mobi> | 2016-11-23 19:45:33 -0200 |
commit | 6f3220ffc6140594792c596ebb452149e19be00f (patch) | |
tree | e4856af31d89b89739852ae3d06bac7917d36ebf /src/lib | |
parent | d0b6aa6596884fc4db5287bd8e3c2cee9db1f031 (diff) |
ecore_ipc: convert ecore_ipc_server_add() to Efl_Net_Server.
Each client (Ecore_Ipc_Client) is very similar to the handle
configured by ecore_ipc_server_connect() (the dialer), except we do
not have events such as "connected" and "error", as well as we don't
delete the socket as it's owned by the server, instead we close it.
The UNIX socket is configured similarly to ecore_con, setting the same
masks and mode for directories.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/ecore_ipc/ecore_ipc.c | 446 | ||||
-rw-r--r-- | src/lib/ecore_ipc/ecore_ipc_private.h | 10 |
2 files changed, 450 insertions, 6 deletions
diff --git a/src/lib/ecore_ipc/ecore_ipc.c b/src/lib/ecore_ipc/ecore_ipc.c index 8a38815da3..82d58194f0 100644 --- a/src/lib/ecore_ipc/ecore_ipc.c +++ b/src/lib/ecore_ipc/ecore_ipc.c | |||
@@ -295,6 +295,8 @@ ecore_ipc_client_add(Ecore_Ipc_Server *svr) | |||
295 | cl = calloc(1, sizeof(Ecore_Ipc_Client)); | 295 | cl = calloc(1, sizeof(Ecore_Ipc_Client)); |
296 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL); | 296 | EINA_SAFETY_ON_NULL_RETURN_VAL(cl, NULL); |
297 | cl->svr = svr; | 297 | cl->svr = svr; |
298 | cl->max_buf_size = 32 * 1024; | ||
299 | |||
298 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT); | 300 | ECORE_MAGIC_SET(cl, ECORE_MAGIC_IPC_CLIENT); |
299 | svr->clients = eina_list_append(svr->clients, cl); | 301 | svr->clients = eina_list_append(svr->clients, cl); |
300 | 302 | ||
@@ -362,9 +364,27 @@ ecore_ipc_shutdown(void) | |||
362 | return _ecore_ipc_init_count; | 364 | return _ecore_ipc_init_count; |
363 | } | 365 | } |
364 | 366 | ||
365 | /* FIXME: need to add protocol type parameter */ | 367 | static void |
366 | EAPI Ecore_Ipc_Server * | 368 | _ecore_ipc_server_del(Ecore_Ipc_Server *svr) |
367 | ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, const void *data) | 369 | { |
370 | DBG("server %p del", svr); | ||
371 | |||
372 | if (svr->server) | ||
373 | { | ||
374 | efl_del(svr->server); | ||
375 | svr->server = NULL; | ||
376 | } | ||
377 | } | ||
378 | |||
379 | static void _ecore_ipc_server_client_add(void *data, const Efl_Event *event); | ||
380 | |||
381 | EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_server_cbs, | ||
382 | { EFL_NET_SERVER_EVENT_CLIENT_ADD, _ecore_ipc_server_client_add }); | ||
383 | |||
384 | |||
385 | #ifndef EFL_NET_SERVER_UNIX_CLASS | ||
386 | static Ecore_Ipc_Server * | ||
387 | ecore_ipc_server_add_legacy(Ecore_Ipc_Type compl_type, char *name, int port, const void *data) | ||
368 | { | 388 | { |
369 | Ecore_Ipc_Server *svr; | 389 | Ecore_Ipc_Server *svr; |
370 | Ecore_Ipc_Type type; | 390 | Ecore_Ipc_Type type; |
@@ -403,6 +423,190 @@ ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, cons | |||
403 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); | 423 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); |
404 | return svr; | 424 | return svr; |
405 | } | 425 | } |
426 | #else | ||
427 | static Eina_Bool | ||
428 | _ecore_ipc_local_mkpath(const char *path, mode_t mode) | ||
429 | { | ||
430 | Eina_Bool ret = EINA_FALSE; | ||
431 | char *s, *d, *itr; | ||
432 | |||
433 | if (!path) return EINA_FALSE; | ||
434 | EINA_SAFETY_ON_TRUE_RETURN_VAL(path[0] != '/', EINA_FALSE); | ||
435 | |||
436 | s = strdup(path); | ||
437 | EINA_SAFETY_ON_NULL_RETURN_VAL(s, EINA_FALSE); | ||
438 | d = dirname(s); | ||
439 | EINA_SAFETY_ON_NULL_RETURN_VAL(d, EINA_FALSE); | ||
440 | |||
441 | for (itr = d + 1; *itr != '\0'; itr++) | ||
442 | { | ||
443 | if (*itr == '/') | ||
444 | { | ||
445 | *itr = '\0'; | ||
446 | if (mkdir(d, mode) != 0) | ||
447 | { | ||
448 | if (errno != EEXIST) | ||
449 | { | ||
450 | ERR("could not create parent directory '%s' of path '%s': %s", d, path, strerror(errno)); | ||
451 | goto end; | ||
452 | } | ||
453 | } | ||
454 | *itr = '/'; | ||
455 | } | ||
456 | } | ||
457 | |||
458 | if (mkdir(d, mode) != 0) | ||
459 | { | ||
460 | if (errno != EEXIST) | ||
461 | ERR("could not create parent directory '%s' of path '%s': %s", d, path, strerror(errno)); | ||
462 | else | ||
463 | { | ||
464 | struct stat st; | ||
465 | if ((stat(d, &st) != 0) || (!S_ISDIR(st.st_mode))) | ||
466 | ERR("could not create parent directory '%s' of path '%s': exists but is not a directory", d, path); | ||
467 | else ret = EINA_TRUE; | ||
468 | } | ||
469 | } | ||
470 | else ret = EINA_TRUE; | ||
471 | |||
472 | end: | ||
473 | free(s); | ||
474 | return ret; | ||
475 | } | ||
476 | #endif | ||
477 | |||
478 | /* FIXME: need to add protocol type parameter */ | ||
479 | EAPI Ecore_Ipc_Server * | ||
480 | ecore_ipc_server_add(Ecore_Ipc_Type type, const char *name, int port, const void *data) | ||
481 | { | ||
482 | Ecore_Ipc_Server *svr; | ||
483 | Eo *loop = ecore_main_loop_get(); | ||
484 | char *address = NULL; | ||
485 | Eina_Error err; | ||
486 | #ifdef EFL_NET_SERVER_UNIX_CLASS | ||
487 | mode_t old_mask, new_mask = 0; | ||
488 | #endif | ||
489 | |||
490 | EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL); | ||
491 | |||
492 | #ifndef EFL_NET_SERVER_UNIX_CLASS | ||
493 | if (((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER) || | ||
494 | ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)) | ||
495 | { | ||
496 | DBG("no 'local' Efl.Net.Server for your system yet, use legacy Ecore_Con"); | ||
497 | return ecore_ipc_server_add_legacy(type, name, port, data); | ||
498 | } | ||
499 | #endif | ||
500 | |||
501 | svr = calloc(1, sizeof(Ecore_Ipc_Server)); | ||
502 | EINA_SAFETY_ON_NULL_RETURN_VAL(svr, NULL); | ||
503 | |||
504 | if (0) { } | ||
505 | #ifdef EFL_NET_SERVER_UNIX_CLASS | ||
506 | if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER) | ||
507 | { | ||
508 | address = ecore_con_local_path_new(EINA_FALSE, name, port); | ||
509 | EINA_SAFETY_ON_NULL_GOTO(address, error_server); | ||
510 | |||
511 | if (!_ecore_ipc_local_mkpath(address, S_IRUSR | S_IWUSR | S_IXUSR)) | ||
512 | { | ||
513 | free(address); | ||
514 | goto error_server; | ||
515 | } | ||
516 | |||
517 | new_mask = S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH; | ||
518 | |||
519 | svr->server = efl_add(EFL_NET_SERVER_UNIX_CLASS, ecore_main_loop_get()); | ||
520 | EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server); | ||
521 | } | ||
522 | else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM) | ||
523 | { | ||
524 | address = ecore_con_local_path_new(EINA_TRUE, name, port); | ||
525 | EINA_SAFETY_ON_NULL_GOTO(address, error_server); | ||
526 | |||
527 | /* ecore_con didn't create leading directories for LOCAL_SYSTEM */ | ||
528 | |||
529 | new_mask = 0; | ||
530 | |||
531 | svr->server = efl_add(EFL_NET_SERVER_UNIX_CLASS, ecore_main_loop_get()); | ||
532 | EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server); | ||
533 | } | ||
534 | #endif /* EFL_NET_SERVER_UNIX_CLASS */ | ||
535 | else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_REMOTE_SYSTEM) | ||
536 | { | ||
537 | char buf[4096]; | ||
538 | |||
539 | if (port <= 0) | ||
540 | { | ||
541 | ERR("remote system requires port>=0, got %d", port); | ||
542 | goto error_server; | ||
543 | } | ||
544 | |||
545 | snprintf(buf, sizeof(buf), "%s:%d", name, port); | ||
546 | address = strdup(buf); | ||
547 | EINA_SAFETY_ON_NULL_GOTO(address, error_server); | ||
548 | |||
549 | if ((type & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL) | ||
550 | { | ||
551 | svr->server = efl_add(EFL_NET_SERVER_SSL_CLASS, loop); | ||
552 | EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server); | ||
553 | } | ||
554 | else | ||
555 | { | ||
556 | svr->server = efl_add(EFL_NET_SERVER_TCP_CLASS, loop); | ||
557 | EINA_SAFETY_ON_NULL_GOTO(svr->server, error_server); | ||
558 | } | ||
559 | } | ||
560 | else | ||
561 | { | ||
562 | ERR("IPC Type must be one of: local_user, local_system or remote_system"); | ||
563 | goto error_server; | ||
564 | } | ||
565 | |||
566 | efl_event_callback_array_add(svr->server, _ecore_ipc_server_cbs(), svr); | ||
567 | |||
568 | #ifdef EFL_NET_SERVER_UNIX_CLASS | ||
569 | if (efl_isa(svr->server, EFL_NET_SERVER_UNIX_CLASS)) | ||
570 | old_mask = umask(new_mask); | ||
571 | #endif | ||
572 | |||
573 | err = efl_net_server_serve(svr->server, address); | ||
574 | |||
575 | #ifdef EFL_NET_SERVER_UNIX_CLASS | ||
576 | if (efl_isa(svr->server, EFL_NET_SERVER_UNIX_CLASS)) | ||
577 | umask(old_mask); | ||
578 | #endif | ||
579 | |||
580 | if (err) | ||
581 | { | ||
582 | WRN("Could not serve %s %s: %s", | ||
583 | efl_class_name_get(efl_class_get(svr->server)), | ||
584 | address, eina_error_msg_get(err)); | ||
585 | goto error; | ||
586 | } | ||
587 | DBG("will serve %p %s address='%s'", | ||
588 | svr->server, | ||
589 | efl_class_name_get(efl_class_get(svr->server)), | ||
590 | address); | ||
591 | |||
592 | svr->max_buf_size = 32 * 1024; | ||
593 | svr->data = (void *)data; | ||
594 | servers = eina_list_append(servers, svr); | ||
595 | ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); | ||
596 | free(address); | ||
597 | return svr; | ||
598 | |||
599 | error: | ||
600 | free(address); | ||
601 | _ecore_ipc_server_del(svr); | ||
602 | free(svr); | ||
603 | return NULL; /* server will trigger all cleanup on its own callbacks */ | ||
604 | |||
605 | error_server: | ||
606 | free(address); | ||
607 | free(svr); | ||
608 | return NULL; | ||
609 | } | ||
406 | 610 | ||
407 | static void | 611 | static void |
408 | _ecore_ipc_dialer_del(Ecore_Ipc_Server *svr) | 612 | _ecore_ipc_dialer_del(Ecore_Ipc_Server *svr) |
@@ -713,6 +917,7 @@ ecore_ipc_server_del(Ecore_Ipc_Server *svr) | |||
713 | } | 917 | } |
714 | 918 | ||
715 | if (svr->dialer.dialer) _ecore_ipc_dialer_del(svr); | 919 | if (svr->dialer.dialer) _ecore_ipc_dialer_del(svr); |
920 | if (svr->server) _ecore_ipc_server_del(svr); | ||
716 | if (svr->legacy_server) ecore_con_server_del(svr->legacy_server); | 921 | if (svr->legacy_server) ecore_con_server_del(svr->legacy_server); |
717 | servers = eina_list_remove(servers, svr); | 922 | servers = eina_list_remove(servers, svr); |
718 | 923 | ||
@@ -749,6 +954,7 @@ ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr) | |||
749 | 954 | ||
750 | if (svr->dialer.dialer) | 955 | if (svr->dialer.dialer) |
751 | return efl_net_dialer_connected_get(svr->dialer.dialer); | 956 | return efl_net_dialer_connected_get(svr->dialer.dialer); |
957 | else if (svr->server) return EINA_TRUE; | ||
752 | else if (!svr->legacy_server) return EINA_FALSE; | 958 | else if (!svr->legacy_server) return EINA_FALSE; |
753 | 959 | ||
754 | return ecore_con_server_connected_get(svr->legacy_server); | 960 | return ecore_con_server_connected_get(svr->legacy_server); |
@@ -876,6 +1082,11 @@ ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int | |||
876 | 1082 | ||
877 | return s + size; | 1083 | return s + size; |
878 | } | 1084 | } |
1085 | else if (svr->server) | ||
1086 | { | ||
1087 | ERR("Send data to clients, not the server handle"); | ||
1088 | return 0; | ||
1089 | } | ||
879 | else if (!svr->legacy_server) return 0; | 1090 | else if (!svr->legacy_server) return 0; |
880 | 1091 | ||
881 | ret = ecore_con_server_send(svr->legacy_server, dat, s); | 1092 | ret = ecore_con_server_send(svr->legacy_server, dat, s); |
@@ -892,6 +1103,12 @@ ecore_ipc_server_client_limit_set(Ecore_Ipc_Server *svr, int client_limit, char | |||
892 | "ecore_ipc_server_client_limit_set"); | 1103 | "ecore_ipc_server_client_limit_set"); |
893 | return; | 1104 | return; |
894 | } | 1105 | } |
1106 | if (svr->server) | ||
1107 | { | ||
1108 | efl_net_server_clients_limit_set(svr->server, client_limit, reject_excess_clients); | ||
1109 | return; | ||
1110 | } | ||
1111 | else if (!svr->legacy_server) return; | ||
895 | ecore_con_server_client_limit_set(svr->legacy_server, client_limit, reject_excess_clients); | 1112 | ecore_con_server_client_limit_set(svr->legacy_server, client_limit, reject_excess_clients); |
896 | } | 1113 | } |
897 | 1114 | ||
@@ -937,6 +1154,14 @@ ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr) | |||
937 | /* original IPC just returned IP for remote connections */ | 1154 | /* original IPC just returned IP for remote connections */ |
938 | return NULL; | 1155 | return NULL; |
939 | } | 1156 | } |
1157 | else if (svr->server) | ||
1158 | { | ||
1159 | if (efl_isa(svr->server, EFL_NET_SERVER_TCP_CLASS) || | ||
1160 | efl_isa(svr->server, EFL_NET_SERVER_SSL_CLASS)) | ||
1161 | return efl_net_server_address_get(svr->server); | ||
1162 | /* original IPC just returned IP for remote connections */ | ||
1163 | return NULL; | ||
1164 | } | ||
940 | else if (!svr->legacy_server) return NULL; | 1165 | else if (!svr->legacy_server) return NULL; |
941 | 1166 | ||
942 | return ecore_con_server_ip_get(svr->legacy_server); | 1167 | return ecore_con_server_ip_get(svr->legacy_server); |
@@ -957,6 +1182,11 @@ ecore_ipc_server_flush(Ecore_Ipc_Server *svr) | |||
957 | efl_io_copier_flush(svr->dialer.send_copier); | 1182 | efl_io_copier_flush(svr->dialer.send_copier); |
958 | return; | 1183 | return; |
959 | } | 1184 | } |
1185 | else if (svr->server) | ||
1186 | { | ||
1187 | ERR("Flush clients, not the server handle"); | ||
1188 | return; | ||
1189 | } | ||
960 | else if (!svr->legacy_server) return; | 1190 | else if (!svr->legacy_server) return; |
961 | 1191 | ||
962 | ecore_con_server_flush(svr->legacy_server); | 1192 | ecore_con_server_flush(svr->legacy_server); |
@@ -1009,8 +1239,16 @@ ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int r | |||
1009 | "ecore_ipc_client_send"); | 1239 | "ecore_ipc_client_send"); |
1010 | return 0; | 1240 | return 0; |
1011 | } | 1241 | } |
1012 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!cl->client, 0); | 1242 | if (cl->socket.socket) |
1013 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!ecore_con_client_connected_get(cl->client), 0); | 1243 | EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(cl->socket.socket), 0); |
1244 | else if (cl->client) | ||
1245 | EINA_SAFETY_ON_TRUE_RETURN_VAL(!ecore_con_client_connected_get(cl->client), 0); | ||
1246 | else | ||
1247 | { | ||
1248 | ERR("client %p is not connected", cl); | ||
1249 | return 0; | ||
1250 | } | ||
1251 | |||
1014 | if (size < 0) size = 0; | 1252 | if (size < 0) size = 0; |
1015 | msg.major = major; | 1253 | msg.major = major; |
1016 | msg.minor = minor; | 1254 | msg.minor = minor; |
@@ -1034,6 +1272,48 @@ ecore_ipc_client_send(Ecore_Ipc_Client *cl, int major, int minor, int ref, int r | |||
1034 | *head |= md << (4 * 5); | 1272 | *head |= md << (4 * 5); |
1035 | *head = htonl(*head); | 1273 | *head = htonl(*head); |
1036 | cl->prev.o = msg; | 1274 | cl->prev.o = msg; |
1275 | |||
1276 | if (cl->socket.input) | ||
1277 | { | ||
1278 | Eina_Slice slice; | ||
1279 | Eina_Error err; | ||
1280 | |||
1281 | slice.mem = dat; | ||
1282 | slice.len = s; | ||
1283 | err = efl_io_writer_write(cl->socket.input, &slice, NULL); | ||
1284 | if (err) | ||
1285 | { | ||
1286 | ERR("could not write queue=%p %zd bytes: %s", | ||
1287 | cl->socket.input, slice.len, eina_error_msg_get(err)); | ||
1288 | return 0; | ||
1289 | } | ||
1290 | if (slice.len < (size_t)s) | ||
1291 | { | ||
1292 | ERR("only wrote %zd of %d bytes to queue %p", | ||
1293 | slice.len, s, cl->socket.input); | ||
1294 | return 0; | ||
1295 | } | ||
1296 | |||
1297 | slice.mem = data; | ||
1298 | slice.len = size; | ||
1299 | err = efl_io_writer_write(cl->socket.input, &slice, NULL); | ||
1300 | if (err) | ||
1301 | { | ||
1302 | ERR("could not write queue=%p %zd bytes: %s", | ||
1303 | cl->socket.input, slice.len, eina_error_msg_get(err)); | ||
1304 | return 0; | ||
1305 | } | ||
1306 | if (slice.len < (size_t)size) | ||
1307 | { | ||
1308 | ERR("only wrote %zd of %d bytes to queue %p", | ||
1309 | slice.len, size, cl->socket.input); | ||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | return s + size; | ||
1314 | } | ||
1315 | else if (!cl->client) return 0; | ||
1316 | |||
1037 | ret = ecore_con_client_send(cl->client, dat, s); | 1317 | ret = ecore_con_client_send(cl->client, dat, s); |
1038 | if (size > 0) ret += ecore_con_client_send(cl->client, data, size); | 1318 | if (size > 0) ret += ecore_con_client_send(cl->client, data, size); |
1039 | return ret; | 1319 | return ret; |
@@ -1051,6 +1331,140 @@ ecore_ipc_client_server_get(Ecore_Ipc_Client *cl) | |||
1051 | return cl->svr; | 1331 | return cl->svr; |
1052 | } | 1332 | } |
1053 | 1333 | ||
1334 | static Efl_Callback_Array_Item *_ecore_ipc_socket_cbs(void); | ||
1335 | |||
1336 | static void | ||
1337 | _ecore_ipc_client_socket_del(Ecore_Ipc_Client *cl) | ||
1338 | { | ||
1339 | DBG("client %p socket del", cl); | ||
1340 | |||
1341 | if (cl->socket.recv_copier) | ||
1342 | { | ||
1343 | efl_del(cl->socket.recv_copier); | ||
1344 | cl->socket.recv_copier = NULL; | ||
1345 | } | ||
1346 | |||
1347 | if (cl->socket.send_copier) | ||
1348 | { | ||
1349 | efl_del(cl->socket.send_copier); | ||
1350 | cl->socket.send_copier = NULL; | ||
1351 | } | ||
1352 | |||
1353 | if (cl->socket.input) | ||
1354 | { | ||
1355 | efl_del(cl->socket.input); | ||
1356 | cl->socket.input = NULL; | ||
1357 | } | ||
1358 | |||
1359 | if (cl->socket.socket) | ||
1360 | { | ||
1361 | efl_event_callback_array_del(cl->socket.socket, _ecore_ipc_socket_cbs(), cl); | ||
1362 | /* do not del() as it's owned by srv->server */ | ||
1363 | if (!efl_io_closer_closed_get(cl->socket.socket)) | ||
1364 | efl_io_closer_close(cl->socket.socket); | ||
1365 | efl_unref(cl->socket.socket); | ||
1366 | cl->socket.socket = NULL; | ||
1367 | } | ||
1368 | } | ||
1369 | |||
1370 | static void | ||
1371 | _ecore_ipc_client_socket_eos(void *data, const Efl_Event *event EINA_UNUSED) | ||
1372 | { | ||
1373 | Ecore_Ipc_Client *cl = data; | ||
1374 | |||
1375 | DBG("client %p socket %p eos", cl, cl->socket.socket); | ||
1376 | |||
1377 | _ecore_ipc_client_socket_del(cl); | ||
1378 | |||
1379 | ecore_ipc_post_event_client_del(cl); | ||
1380 | } | ||
1381 | |||
1382 | EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_socket_cbs, | ||
1383 | { EFL_IO_READER_EVENT_EOS, _ecore_ipc_client_socket_eos }); | ||
1384 | |||
1385 | static Eina_Bool ecore_ipc_client_data_process(Ecore_Ipc_Client *cl, void *data, int size, Eina_Bool *stolen); | ||
1386 | |||
1387 | static void | ||
1388 | _ecore_ipc_client_socket_copier_data(void *data, const Efl_Event *event EINA_UNUSED) | ||
1389 | { | ||
1390 | Ecore_Ipc_Client *cl = data; | ||
1391 | Eina_Binbuf *binbuf; | ||
1392 | uint8_t *mem; | ||
1393 | int size; | ||
1394 | Eina_Bool stolen; | ||
1395 | |||
1396 | DBG("client %p recv_copier %p data", cl, cl->socket.recv_copier); | ||
1397 | |||
1398 | binbuf = efl_io_copier_binbuf_steal(cl->socket.recv_copier); | ||
1399 | EINA_SAFETY_ON_NULL_RETURN(binbuf); | ||
1400 | size = eina_binbuf_length_get(binbuf); | ||
1401 | mem = eina_binbuf_string_steal(binbuf); | ||
1402 | eina_binbuf_free(binbuf); | ||
1403 | |||
1404 | ecore_ipc_client_data_process(cl, mem, size, &stolen); | ||
1405 | if (!stolen) free(mem); | ||
1406 | } | ||
1407 | |||
1408 | static void | ||
1409 | _ecore_ipc_client_socket_copier_error(void *data, const Efl_Event *event) | ||
1410 | { | ||
1411 | Ecore_Ipc_Client *cl = data; | ||
1412 | Eina_Error *perr = event->info; | ||
1413 | |||
1414 | WRN("client %p socket %p copier %p error %s", cl, cl->socket.socket, event->object, eina_error_msg_get(*perr)); | ||
1415 | |||
1416 | if (!efl_io_closer_closed_get(cl->socket.socket)) | ||
1417 | efl_io_closer_close(cl->socket.socket); | ||
1418 | } | ||
1419 | |||
1420 | EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_client_socket_copier_cbs, | ||
1421 | { EFL_IO_COPIER_EVENT_ERROR, _ecore_ipc_client_socket_copier_error }); | ||
1422 | |||
1423 | static void | ||
1424 | _ecore_ipc_server_client_add(void *data, const Efl_Event *event) | ||
1425 | { | ||
1426 | Ecore_Ipc_Server *svr = data; | ||
1427 | Eo *socket = event->info; | ||
1428 | Ecore_Ipc_Client *cl; | ||
1429 | Eo *loop; | ||
1430 | |||
1431 | DBG("server %p %p got new client %p (%s)", | ||
1432 | svr, svr->server, | ||
1433 | event->object, efl_net_socket_address_remote_get(socket)); | ||
1434 | |||
1435 | cl = ecore_ipc_client_add(svr); | ||
1436 | EINA_SAFETY_ON_NULL_RETURN(cl); | ||
1437 | |||
1438 | cl->socket.socket = efl_ref(socket); | ||
1439 | efl_event_callback_array_add(cl->socket.socket, _ecore_ipc_socket_cbs(), cl); | ||
1440 | |||
1441 | loop = efl_loop_get(socket); | ||
1442 | |||
1443 | cl->socket.input = efl_add(EFL_IO_QUEUE_CLASS, loop); | ||
1444 | EINA_SAFETY_ON_NULL_GOTO(cl->socket.input, error); | ||
1445 | |||
1446 | cl->socket.send_copier = efl_add(EFL_IO_COPIER_CLASS, loop, | ||
1447 | efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE), | ||
1448 | efl_io_copier_source_set(efl_added, cl->socket.input), | ||
1449 | efl_io_copier_destination_set(efl_added, cl->socket.socket), | ||
1450 | efl_event_callback_array_add(efl_added, _ecore_ipc_client_socket_copier_cbs(), cl)); | ||
1451 | EINA_SAFETY_ON_NULL_GOTO(cl->socket.send_copier, error); | ||
1452 | |||
1453 | cl->socket.recv_copier = efl_add(EFL_IO_COPIER_CLASS, loop, | ||
1454 | efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE), | ||
1455 | efl_io_copier_source_set(efl_added, cl->socket.socket), | ||
1456 | efl_event_callback_array_add(efl_added, _ecore_ipc_client_socket_copier_cbs(), cl), | ||
1457 | efl_event_callback_add(efl_added, EFL_IO_COPIER_EVENT_DATA, _ecore_ipc_client_socket_copier_data, cl)); | ||
1458 | EINA_SAFETY_ON_NULL_GOTO(cl->socket.recv_copier, error); | ||
1459 | |||
1460 | ecore_ipc_post_event_client_add(cl); | ||
1461 | return; | ||
1462 | |||
1463 | error: | ||
1464 | _ecore_ipc_client_socket_del(cl); | ||
1465 | free(cl); | ||
1466 | } | ||
1467 | |||
1054 | EAPI void * | 1468 | EAPI void * |
1055 | ecore_ipc_client_del(Ecore_Ipc_Client *cl) | 1469 | ecore_ipc_client_del(Ecore_Ipc_Client *cl) |
1056 | { | 1470 | { |
@@ -1070,6 +1484,7 @@ ecore_ipc_client_del(Ecore_Ipc_Client *cl) | |||
1070 | if (cl->event_count == 0) | 1484 | if (cl->event_count == 0) |
1071 | { | 1485 | { |
1072 | svr = cl->svr; | 1486 | svr = cl->svr; |
1487 | if (cl->socket.socket) _ecore_ipc_client_socket_del(cl); | ||
1073 | if (cl->client) ecore_con_client_del(cl->client); | 1488 | if (cl->client) ecore_con_client_del(cl->client); |
1074 | if (ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) | 1489 | if (ECORE_MAGIC_CHECK(svr, ECORE_MAGIC_IPC_SERVER)) |
1075 | svr->clients = eina_list_remove(svr->clients, cl); | 1490 | svr->clients = eina_list_remove(svr->clients, cl); |
@@ -1137,6 +1552,18 @@ ecore_ipc_client_ip_get(Ecore_Ipc_Client *cl) | |||
1137 | "ecore_ipc_client_ip_get"); | 1552 | "ecore_ipc_client_ip_get"); |
1138 | return NULL; | 1553 | return NULL; |
1139 | } | 1554 | } |
1555 | if (cl->socket.socket) | ||
1556 | { | ||
1557 | if (efl_isa(cl->socket.socket, EFL_NET_SOCKET_TCP_CLASS) || | ||
1558 | efl_isa(cl->socket.socket, EFL_NET_SOCKET_SSL_CLASS)) | ||
1559 | return efl_net_socket_address_remote_get(cl->socket.socket); | ||
1560 | /* original IPC just returned IP for remote connections, | ||
1561 | * for unix socket it returned 0.0.0.0 | ||
1562 | */ | ||
1563 | return "0.0.0.0"; | ||
1564 | } | ||
1565 | else if (!cl->client) return NULL; | ||
1566 | |||
1140 | return ecore_con_client_ip_get(cl->client); | 1567 | return ecore_con_client_ip_get(cl->client); |
1141 | } | 1568 | } |
1142 | 1569 | ||
@@ -1149,6 +1576,14 @@ ecore_ipc_client_flush(Ecore_Ipc_Client *cl) | |||
1149 | "ecore_ipc_client_flush"); | 1576 | "ecore_ipc_client_flush"); |
1150 | return; | 1577 | return; |
1151 | } | 1578 | } |
1579 | if (cl->socket.input) | ||
1580 | { | ||
1581 | while (efl_io_queue_usage_get(cl->socket.input) > 0) | ||
1582 | efl_io_copier_flush(cl->socket.send_copier); | ||
1583 | return; | ||
1584 | } | ||
1585 | else if (!cl->client) return; | ||
1586 | |||
1152 | ecore_con_client_flush(cl->client); | 1587 | ecore_con_client_flush(cl->client); |
1153 | } | 1588 | } |
1154 | 1589 | ||
@@ -1174,7 +1609,6 @@ _ecore_ipc_event_client_add(void *data EINA_UNUSED, int ev_type EINA_UNUSED, voi | |||
1174 | 1609 | ||
1175 | if (!cl) return ECORE_CALLBACK_CANCEL; | 1610 | if (!cl) return ECORE_CALLBACK_CANCEL; |
1176 | cl->client = e->client; | 1611 | cl->client = e->client; |
1177 | cl->max_buf_size = 32 * 1024; | ||
1178 | ecore_con_client_data_set(cl->client, (void *)cl); | 1612 | ecore_con_client_data_set(cl->client, (void *)cl); |
1179 | 1613 | ||
1180 | ecore_ipc_post_event_client_add(cl); | 1614 | ecore_ipc_post_event_client_add(cl); |
diff --git a/src/lib/ecore_ipc/ecore_ipc_private.h b/src/lib/ecore_ipc/ecore_ipc_private.h index 9f0def1f44..baf71fd788 100644 --- a/src/lib/ecore_ipc/ecore_ipc_private.h +++ b/src/lib/ecore_ipc/ecore_ipc_private.h | |||
@@ -66,6 +66,14 @@ struct _Ecore_Ipc_Msg_Head | |||
66 | struct _Ecore_Ipc_Client | 66 | struct _Ecore_Ipc_Client |
67 | { | 67 | { |
68 | ECORE_MAGIC; | 68 | ECORE_MAGIC; |
69 | |||
70 | struct { | ||
71 | Eo *input; | ||
72 | Eo *socket; | ||
73 | Eo *recv_copier; | ||
74 | Eo *send_copier; | ||
75 | } socket; | ||
76 | |||
69 | Ecore_Con_Client *client; | 77 | Ecore_Con_Client *client; |
70 | Ecore_Ipc_Server *svr; | 78 | Ecore_Ipc_Server *svr; |
71 | void *data; | 79 | void *data; |
@@ -93,6 +101,8 @@ struct _Ecore_Ipc_Server | |||
93 | Eo *send_copier; | 101 | Eo *send_copier; |
94 | } dialer; | 102 | } dialer; |
95 | 103 | ||
104 | Eo *server; | ||
105 | |||
96 | Ecore_Con_Server *legacy_server; | 106 | Ecore_Con_Server *legacy_server; |
97 | Eina_List *clients; | 107 | Eina_List *clients; |
98 | void *data; | 108 | void *data; |