summaryrefslogtreecommitdiff
path: root/src/lib/ecore_ipc
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-11-23 12:17:14 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2016-11-23 12:57:10 -0200
commite34b07e6e28d8bf40d581e97ce617028b5ecce04 (patch)
tree807cb6b2df32729c2f07792b37f786cdc9ac1f17 /src/lib/ecore_ipc
parent715c882073aace5c6f77916a11a442718fb91a40 (diff)
ecore_ipc: implement ecore_con_server_connect() using Efl.Net.Dialer.
Use the new Efl.Net.Dialer classes to implement ecore_con_server_connect() scenario. Note that since Windows still doesn't provide any equivalent to Efl.Net.Dialer.Unix, we keep the legacy code for it.
Diffstat (limited to 'src/lib/ecore_ipc')
-rw-r--r--src/lib/ecore_ipc/ecore_ipc.c312
-rw-r--r--src/lib/ecore_ipc/ecore_ipc_private.h9
2 files changed, 318 insertions, 3 deletions
diff --git a/src/lib/ecore_ipc/ecore_ipc.c b/src/lib/ecore_ipc/ecore_ipc.c
index 59e7db62ee..c0f9f5f5ac 100644
--- a/src/lib/ecore_ipc/ecore_ipc.c
+++ b/src/lib/ecore_ipc/ecore_ipc.c
@@ -404,9 +404,118 @@ ecore_ipc_server_add(Ecore_Ipc_Type compl_type, const char *name, int port, cons
404 return svr; 404 return svr;
405} 405}
406 406
407/* FIXME: need to add protocol type parameter */ 407static void
408EAPI Ecore_Ipc_Server * 408_ecore_ipc_dialer_del(Ecore_Ipc_Server *svr)
409ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const void *data) 409{
410 DBG("dialer %p del", svr);
411
412 if (svr->dialer.recv_copier)
413 {
414 efl_del(svr->dialer.recv_copier);
415 svr->dialer.recv_copier = NULL;
416 }
417
418 if (svr->dialer.send_copier)
419 {
420 efl_del(svr->dialer.send_copier);
421 svr->dialer.send_copier = NULL;
422 }
423
424 if (svr->dialer.input)
425 {
426 efl_del(svr->dialer.input);
427 svr->dialer.input = NULL;
428 }
429
430 if (svr->dialer.dialer)
431 {
432 efl_del(svr->dialer.dialer);
433 svr->dialer.dialer = NULL;
434 }
435}
436
437static void
438_ecore_ipc_dialer_eos(void *data, const Efl_Event *event EINA_UNUSED)
439{
440 Ecore_Ipc_Server *svr = data;
441
442 DBG("dialer %p %p eos", svr, svr->dialer.dialer);
443
444 _ecore_ipc_dialer_del(svr);
445
446 ecore_ipc_post_event_server_del(svr);
447}
448
449static void
450_ecore_ipc_dialer_error(void *data, const Efl_Event *event)
451{
452 Ecore_Ipc_Server *svr = data;
453 Eina_Error *perr = event->info;
454
455 WRN("dialer %p %p error %s", svr, svr->dialer.dialer, eina_error_msg_get(*perr));
456
457 if (!efl_io_closer_closed_get(svr->dialer.dialer))
458 efl_io_closer_close(svr->dialer.dialer); /* triggers EOS */
459}
460
461static void
462_ecore_ipc_dialer_connected(void *data, const Efl_Event *event EINA_UNUSED)
463{
464 Ecore_Ipc_Server *svr = data;
465
466 DBG("connected to %s %s",
467 efl_class_name_get(efl_class_get(svr->dialer.dialer)),
468 efl_net_dialer_address_dial_get(svr->dialer.dialer));
469
470 ecore_ipc_post_event_server_add(svr);
471}
472
473EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_dialer_cbs,
474 { EFL_IO_READER_EVENT_EOS, _ecore_ipc_dialer_eos },
475 { EFL_NET_DIALER_EVENT_ERROR, _ecore_ipc_dialer_error },
476 { EFL_NET_DIALER_EVENT_CONNECTED, _ecore_ipc_dialer_connected });
477
478static Eina_Bool ecore_ipc_server_data_process(Ecore_Ipc_Server *svr, void *data, int size, Eina_Bool *stolen);
479
480static void
481_ecore_ipc_dialer_copier_data(void *data, const Efl_Event *event EINA_UNUSED)
482{
483 Ecore_Ipc_Server *svr = data;
484 Eina_Binbuf *binbuf;
485 uint8_t *mem;
486 int size;
487 Eina_Bool stolen;
488
489 DBG("dialer %p recv_copier %p data", svr, svr->dialer.recv_copier);
490
491 binbuf = efl_io_copier_binbuf_steal(svr->dialer.recv_copier);
492 EINA_SAFETY_ON_NULL_RETURN(binbuf);
493 size = eina_binbuf_length_get(binbuf);
494 mem = eina_binbuf_string_steal(binbuf);
495 eina_binbuf_free(binbuf);
496
497 ecore_ipc_server_data_process(svr, mem, size, &stolen);
498 if (!stolen) free(mem);
499}
500
501static void
502_ecore_ipc_dialer_copier_error(void *data, const Efl_Event *event)
503{
504 Ecore_Ipc_Server *svr = data;
505 Eina_Error *perr = event->info;
506
507 WRN("dialer %p %p copier %p error %s", svr, svr->dialer.dialer, event->object, eina_error_msg_get(*perr));
508
509 if (!efl_io_closer_closed_get(svr->dialer.dialer))
510 efl_io_closer_close(svr->dialer.dialer);
511}
512
513EFL_CALLBACKS_ARRAY_DEFINE(_ecore_ipc_dialer_copier_cbs,
514 { EFL_IO_COPIER_EVENT_ERROR, _ecore_ipc_dialer_copier_error });
515
516#ifndef EFL_NET_DIALER_UNIX_CLASS
517static Ecore_Ipc_Server *
518ecore_ipc_server_connect_legacy(Ecore_Ipc_Type compl_type, char *name, int port, const void *data)
410{ 519{
411 Ecore_Ipc_Server *svr; 520 Ecore_Ipc_Server *svr;
412 Ecore_Ipc_Type type; 521 Ecore_Ipc_Type type;
@@ -447,6 +556,133 @@ ecore_ipc_server_connect(Ecore_Ipc_Type compl_type, char *name, int port, const
447 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER); 556 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
448 return svr; 557 return svr;
449} 558}
559#endif
560
561/* FIXME: need to add protocol type parameter */
562EAPI Ecore_Ipc_Server *
563ecore_ipc_server_connect(Ecore_Ipc_Type type, char *name, int port, const void *data)
564{
565 Ecore_Ipc_Server *svr;
566 Eo *loop = ecore_main_loop_get();
567 char *address = NULL;
568 Eina_Error err;
569
570 EINA_SAFETY_ON_NULL_RETURN_VAL(name, NULL);
571
572#ifndef EFL_NET_DIALER_UNIX_CLASS
573 if (((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER) ||
574 ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM))
575 {
576 DBG("no 'local' Efl.Net.Dialer for your system yet, use legacy Ecore_Con");
577 return ecore_ipc_server_connect_legacy(type, name, port, data);
578 }
579#endif
580
581 svr = calloc(1, sizeof(Ecore_Ipc_Server));
582 EINA_SAFETY_ON_NULL_RETURN_VAL(svr, NULL);
583
584 if (0) { }
585#ifdef EFL_NET_DIALER_UNIX_CLASS
586 if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_USER)
587 {
588 address = ecore_con_local_path_new(EINA_FALSE, name, port);
589 EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
590
591 svr->dialer.dialer = efl_add(EFL_NET_DIALER_UNIX_CLASS, ecore_main_loop_get());
592 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
593 }
594 else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_LOCAL_SYSTEM)
595 {
596 address = ecore_con_local_path_new(EINA_TRUE, name, port);
597 EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
598
599 svr->dialer.dialer = efl_add(EFL_NET_DIALER_UNIX_CLASS, ecore_main_loop_get());
600 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
601 }
602#endif /* EFL_NET_DIALER_UNIX_CLASS */
603 else if ((type & ECORE_IPC_TYPE) == ECORE_IPC_REMOTE_SYSTEM)
604 {
605 char buf[4096];
606
607 if (port <= 0)
608 {
609 ERR("remote system requires port>=0, got %d", port);
610 goto error_dialer;
611 }
612
613 snprintf(buf, sizeof(buf), "%s:%d", name, port);
614 address = strdup(buf);
615 EINA_SAFETY_ON_NULL_GOTO(address, error_dialer);
616
617 if ((type & ECORE_IPC_USE_SSL) == ECORE_IPC_USE_SSL)
618 {
619 svr->dialer.dialer = efl_add(EFL_NET_DIALER_SSL_CLASS, loop);
620 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
621 }
622 else
623 {
624 svr->dialer.dialer = efl_add(EFL_NET_DIALER_TCP_CLASS, loop);
625 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.dialer, error_dialer);
626 }
627
628 if ((type & ECORE_IPC_NO_PROXY) == ECORE_IPC_NO_PROXY)
629 efl_net_dialer_proxy_set(svr->dialer.dialer, "");
630 }
631 else
632 {
633 ERR("IPC Type must be one of: local_user, local_system or remote_system");
634 goto error_dialer;
635 }
636
637 efl_io_closer_close_on_destructor_set(svr->dialer.dialer, EINA_TRUE);
638 efl_event_callback_array_add(svr->dialer.dialer, _ecore_ipc_dialer_cbs(), svr);
639
640 svr->dialer.input = efl_add(EFL_IO_QUEUE_CLASS, loop);
641 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.input, error);
642
643 svr->dialer.send_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
644 efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE),
645 efl_io_copier_source_set(efl_added, svr->dialer.input),
646 efl_io_copier_destination_set(efl_added, svr->dialer.dialer),
647 efl_event_callback_array_add(efl_added, _ecore_ipc_dialer_copier_cbs(), svr));
648 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.send_copier, error);
649
650 svr->dialer.recv_copier = efl_add(EFL_IO_COPIER_CLASS, loop,
651 efl_io_closer_close_on_destructor_set(efl_added, EINA_FALSE),
652 efl_io_copier_source_set(efl_added, svr->dialer.dialer),
653 efl_event_callback_array_add(efl_added, _ecore_ipc_dialer_copier_cbs(), svr),
654 efl_event_callback_add(efl_added, EFL_IO_COPIER_EVENT_DATA, _ecore_ipc_dialer_copier_data, svr));
655 EINA_SAFETY_ON_NULL_GOTO(svr->dialer.recv_copier, error);
656
657 err = efl_net_dialer_dial(svr->dialer.dialer, address);
658 if (err)
659 {
660 WRN("Could not reach %s %s: %s",
661 efl_class_name_get(efl_class_get(svr->dialer.dialer)),
662 address, eina_error_msg_get(err));
663 goto error;
664 }
665 DBG("connecting %p %s address='%s'",
666 svr->dialer.dialer,
667 efl_class_name_get(efl_class_get(svr->dialer.dialer)),
668 address);
669
670 svr->data = (void *)data;
671 servers = eina_list_append(servers, svr);
672 ECORE_MAGIC_SET(svr, ECORE_MAGIC_IPC_SERVER);
673 free(address);
674 return svr;
675
676 error:
677 free(address);
678 _ecore_ipc_dialer_del(svr);
679 free(svr);
680 return NULL; /* dialer will trigger all cleanup on its own callbacks */
681
682 error_dialer:
683 free(svr);
684 return NULL;
685}
450 686
451EAPI void * 687EAPI void *
452ecore_ipc_server_del(Ecore_Ipc_Server *svr) 688ecore_ipc_server_del(Ecore_Ipc_Server *svr)
@@ -473,13 +709,17 @@ ecore_ipc_server_del(Ecore_Ipc_Server *svr)
473 cl->svr = NULL; 709 cl->svr = NULL;
474 ecore_ipc_client_del(cl); 710 ecore_ipc_client_del(cl);
475 } 711 }
712
713 if (svr->dialer.dialer) _ecore_ipc_dialer_del(svr);
476 if (svr->server) ecore_con_server_del(svr->server); 714 if (svr->server) ecore_con_server_del(svr->server);
477 servers = eina_list_remove(servers, svr); 715 servers = eina_list_remove(servers, svr);
478 716
479 if (svr->buf) free(svr->buf); 717 if (svr->buf) free(svr->buf);
480 ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE); 718 ECORE_MAGIC_SET(svr, ECORE_MAGIC_NONE);
719 DBG("server %p freed", svr);
481 free(svr); 720 free(svr);
482 } 721 }
722 else DBG("server %p has %d events pending, postpone deletion", svr, svr->event_count);
483 return data; 723 return data;
484} 724}
485 725
@@ -504,6 +744,11 @@ ecore_ipc_server_connected_get(Ecore_Ipc_Server *svr)
504 "ecore_ipc_server_connected_get"); 744 "ecore_ipc_server_connected_get");
505 return EINA_FALSE; 745 return EINA_FALSE;
506 } 746 }
747
748 if (svr->dialer.dialer)
749 return efl_net_dialer_connected_get(svr->dialer.dialer);
750 else if (!svr->server) return EINA_FALSE;
751
507 return ecore_con_server_connected_get(svr->server); 752 return ecore_con_server_connected_get(svr->server);
508} 753}
509 754
@@ -589,6 +834,48 @@ ecore_ipc_server_send(Ecore_Ipc_Server *svr, int major, int minor, int ref, int
589 *head |= md << (4 * 5); 834 *head |= md << (4 * 5);
590 *head = htonl(*head); 835 *head = htonl(*head);
591 svr->prev.o = msg; 836 svr->prev.o = msg;
837
838 if (svr->dialer.input)
839 {
840 Eina_Slice slice;
841 Eina_Error err;
842
843 slice.mem = dat;
844 slice.len = s;
845 err = efl_io_writer_write(svr->dialer.input, &slice, NULL);
846 if (err)
847 {
848 ERR("could not write queue=%p %zd bytes: %s",
849 svr->dialer.input, slice.len, eina_error_msg_get(err));
850 return 0;
851 }
852 if (slice.len < (size_t)s)
853 {
854 ERR("only wrote %zd of %d bytes to queue %p",
855 slice.len, s, svr->dialer.input);
856 return 0;
857 }
858
859 slice.mem = data;
860 slice.len = size;
861 err = efl_io_writer_write(svr->dialer.input, &slice, NULL);
862 if (err)
863 {
864 ERR("could not write queue=%p %zd bytes: %s",
865 svr->dialer.input, slice.len, eina_error_msg_get(err));
866 return 0;
867 }
868 if (slice.len < (size_t)size)
869 {
870 ERR("only wrote %zd of %d bytes to queue %p",
871 slice.len, size, svr->dialer.input);
872 return 0;
873 }
874
875 return s + size;
876 }
877 else if (!svr->server) return 0;
878
592 ret = ecore_con_server_send(svr->server, dat, s); 879 ret = ecore_con_server_send(svr->server, dat, s);
593 if (size > 0) ret += ecore_con_server_send(svr->server, data, size); 880 if (size > 0) ret += ecore_con_server_send(svr->server, data, size);
594 return ret; 881 return ret;
@@ -639,6 +926,17 @@ ecore_ipc_server_ip_get(Ecore_Ipc_Server *svr)
639 "ecore_ipc_server_ip_get"); 926 "ecore_ipc_server_ip_get");
640 return NULL; 927 return NULL;
641 } 928 }
929
930 if (svr->dialer.dialer)
931 {
932 if (efl_isa(svr->dialer.dialer, EFL_NET_DIALER_TCP_CLASS) ||
933 efl_isa(svr->dialer.dialer, EFL_NET_DIALER_SSL_CLASS))
934 return efl_net_dialer_address_dial_get(svr->dialer.dialer);
935 /* original IPC just returned IP for remote connections */
936 return NULL;
937 }
938 else if (!svr->server) return NULL;
939
642 return ecore_con_server_ip_get(svr->server); 940 return ecore_con_server_ip_get(svr->server);
643} 941}
644 942
@@ -651,6 +949,14 @@ ecore_ipc_server_flush(Ecore_Ipc_Server *svr)
651 "ecore_ipc_server_server_flush"); 949 "ecore_ipc_server_server_flush");
652 return; 950 return;
653 } 951 }
952 if (svr->dialer.input)
953 {
954 while (efl_io_queue_usage_get(svr->dialer.input) > 0)
955 efl_io_copier_flush(svr->dialer.send_copier);
956 return;
957 }
958 else if (!svr->server) return;
959
654 ecore_con_server_flush(svr->server); 960 ecore_con_server_flush(svr->server);
655} 961}
656 962
diff --git a/src/lib/ecore_ipc/ecore_ipc_private.h b/src/lib/ecore_ipc/ecore_ipc_private.h
index 939991370b..4770da4587 100644
--- a/src/lib/ecore_ipc/ecore_ipc_private.h
+++ b/src/lib/ecore_ipc/ecore_ipc_private.h
@@ -84,6 +84,15 @@ struct _Ecore_Ipc_Client
84struct _Ecore_Ipc_Server 84struct _Ecore_Ipc_Server
85{ 85{
86 ECORE_MAGIC; 86 ECORE_MAGIC;
87
88 /* when used as dialer: ecore_ipc_server_connect() */
89 struct {
90 Eo *input;
91 Eo *dialer;
92 Eo *recv_copier;
93 Eo *send_copier;
94 } dialer;
95
87 Ecore_Con_Server *server; 96 Ecore_Con_Server *server;
88 Eina_List *clients; 97 Eina_List *clients;
89 void *data; 98 void *data;