diff --git a/legacy/ecore/ChangeLog b/legacy/ecore/ChangeLog index c783ae689d..9266d94af2 100644 --- a/legacy/ecore/ChangeLog +++ b/legacy/ecore/ChangeLog @@ -169,10 +169,15 @@ 2011-05-12 Carsten Haitzler (The Rasterman) - * Add a custom Ecore Aniamtor source and tick ability to be able + * Add a custom Ecore Animator source and tick ability to be able to plug in external animator tick sources like vblank interrupts and so on. 2011-05-14 Cedric Bail * Sync GNUTLS threads activation with Eina. + +2011-05-14 Vincent Torri + + * Make ecore_con work on Windows (only the local connections + need a port) diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index 838e6321b7..aabb223757 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -172,7 +172,6 @@ case "$host_os" in want_notify_win32="yes" want_curl="yes" want_glib="auto" - want_ecore_con="no" want_ecore_imf="yes" want_ecore_win32="yes" want_ecore_evas_software_gdi="yes" @@ -271,14 +270,14 @@ AC_ARG_ENABLE([abstract-sockets], [AC_HELP_STRING([--disable-abstract-sockets], [disable abstract sockets.])], [ if test "x${enableval}" = "xyes" ; then - want_abstract_sockets="yes" + want_ecore_con_abstract_sockets="yes" else - want_abstract_sockets="no" + want_ecore_con_abstract_sockets="no" fi ], - [want_abstract_sockets="yes"]) + [want_ecore_con_abstract_sockets=${want_abstract_sockets}]) -if test "x${want_abstract_sockets}" = "xyes" ; then +if test "x${want_ecore_con_abstract_sockets}" = "xyes" ; then AC_DEFINE([HAVE_ABSTRACT_SOCKETS], [1], [Have abstract sockets namespace]) fi @@ -361,8 +360,9 @@ case "$host_os" in requirements_ecore_imf="evil ${requirements_ecore_imf}" requirements_ecore_imf_evas="evil ${requirements_ecore_imf_evas}" EFL_ECORE_BUILD="-DEFL_ECORE_BUILD" - EFL_ECORE_FILE_BUILD="-DEFL_ECORE_FILE_BUILD" + EFL_ECORE_CON_BUILD="-DEFL_ECORE_CON_BUILD" EFL_ECORE_EVAS_BUILD="-DEFL_ECORE_EVAS_BUILD" + EFL_ECORE_FILE_BUILD="-DEFL_ECORE_FILE_BUILD" EFL_ECORE_IMF_BUILD="-DEFL_ECORE_IMF_BUILD" EFL_ECORE_IMF_EVAS_BUILD="-DEFL_ECORE_IMF_EVAS_BUILD" EFL_ECORE_INPUT_BUILD="-DEFL_ECORE_INPUT_BUILD" @@ -388,8 +388,9 @@ case "$host_os" in esac AC_SUBST(EFL_ECORE_BUILD) -AC_SUBST(EFL_ECORE_FILE_BUILD) +AC_SUBST(EFL_ECORE_CON_BUILD) AC_SUBST(EFL_ECORE_EVAS_BUILD) +AC_SUBST(EFL_ECORE_FILE_BUILD) AC_SUBST(EFL_ECORE_IMF_BUILD) AC_SUBST(EFL_ECORE_IMF_EVAS_BUILD) AC_SUBST(EFL_ECORE_INPUT_BUILD) diff --git a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h b/legacy/ecore/src/lib/ecore_con/Ecore_Con.h index 60c3ebacf3..4d9460f187 100644 --- a/legacy/ecore/src/lib/ecore_con/Ecore_Con.h +++ b/legacy/ecore/src/lib/ecore_con/Ecore_Con.h @@ -14,9 +14,13 @@ # undef EAPI #endif -#ifdef _MSC_VER -# ifdef BUILDING_DLL -# define EAPI __declspec(dllexport) +#ifdef _WIN32 +# ifdef EFL_ECORE_CON_BUILD +# ifdef DLL_EXPORT +# define EAPI __declspec(dllexport) +# else +# define EAPI +# endif # else # define EAPI __declspec(dllimport) # endif diff --git a/legacy/ecore/src/lib/ecore_con/Makefile.am b/legacy/ecore/src/lib/ecore_con/Makefile.am index e2969bd796..128c47cb01 100644 --- a/legacy/ecore/src/lib/ecore_con/Makefile.am +++ b/legacy/ecore/src/lib/ecore_con/Makefile.am @@ -5,6 +5,7 @@ AM_CPPFLAGS = \ -I$(top_builddir)/src/lib/ecore_con \ -I$(top_srcdir)/src/lib/ecore \ -I$(top_srcdir)/src/lib/ecore_con \ +@EFL_ECORE_CON_BUILD@ \ @SSL_CFLAGS@ \ @CURL_CFLAGS@ \ @EINA_CFLAGS@ \ @@ -19,8 +20,13 @@ includesdir = $(includedir)/ecore-@VMAJ@ libecore_con_la_SOURCES = \ ecore_con.c \ ecore_con_ssl.c \ -ecore_con_url.c \ -ecore_con_local.c +ecore_con_url.c + +if ECORE_HAVE_WIN32 +libecore_con_la_SOURCES += ecore_con_local_win32.c +else +libecore_con_la_SOURCES += ecore_con_local.c +endif if HAVE_CARES libecore_con_la_SOURCES += ecore_con_ares.c diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con.c b/legacy/ecore/src/lib/ecore_con/ecore_con.c index 13a4517312..6450781c06 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con.c +++ b/legacy/ecore/src/lib/ecore_con/ecore_con.c @@ -351,8 +351,13 @@ ecore_con_server_add(Ecore_Con_Type compl_type, (type == ECORE_CON_LOCAL_SYSTEM) || (type == ECORE_CON_LOCAL_ABSTRACT)) /* Local */ +#ifdef _WIN32 + if (!ecore_con_local_listen(svr)) + goto error; +#else if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) goto error; +#endif if ((type == ECORE_CON_REMOTE_TCP) || (type == ECORE_CON_REMOTE_NODELAY)) @@ -470,10 +475,17 @@ ecore_con_server_connect(Ecore_Con_Type compl_type, (type == ECORE_CON_LOCAL_SYSTEM) || (type == ECORE_CON_LOCAL_ABSTRACT)) /* Local */ +#ifdef _WIN32 + if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, + _ecore_con_event_server_add_free)) + goto + error; +#else if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr, _ecore_con_event_server_add_free)) goto error; +#endif if ((type == ECORE_CON_REMOTE_TCP) || (type == ECORE_CON_REMOTE_NODELAY)) @@ -1191,7 +1203,7 @@ ecore_con_event_server_del(Ecore_Con_Server *svr) } void -ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num) +ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate) { Ecore_Con_Event_Server_Data *e; @@ -1200,14 +1212,19 @@ ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num) svr->event_count++; e->server = svr; - e->data = malloc(num); - if (!e->data) + if (duplicate) { - ERR("alloc!"); - free(e); - return; + e->data = malloc(num); + if (!e->data) + { + ERR("alloc!"); + free(e); + return; + } + memcpy(e->data, buf, num); } - memcpy(e->data, buf, num); + else + e->data = buf; e->size = num; ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, _ecore_con_event_server_data_free, NULL); @@ -1250,7 +1267,7 @@ ecore_con_event_client_del(Ecore_Con_Client *cl) } void -ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num) +ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate) { Ecore_Con_Event_Client_Data *e; e = malloc(sizeof(Ecore_Con_Event_Client_Data)); @@ -1260,15 +1277,19 @@ ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num) cl->event_count++; _ecore_con_cl_timer_update(cl); e->client = cl; - e->data = malloc(num); - if (!e->data) + if (duplicate) { - free(cl->client_addr); - free(cl); - return; + e->data = malloc(num); + if (!e->data) + { + free(cl->client_addr); + free(cl); + return; + } + memcpy(e->data, buf, num); } - - memcpy(e->data, buf, num); + else + e->data = buf; e->size = num; ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, (Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); @@ -1349,6 +1370,10 @@ _ecore_con_server_free(Ecore_Con_Server *svr) } } +#ifdef _WIN32 + ecore_con_local_win32_server_del(svr); +#endif + if (svr->write_buf) free(svr->write_buf); @@ -1410,6 +1435,11 @@ _ecore_con_client_free(Ecore_Con_Client *cl) break; } } + +#ifdef _WIN32 + ecore_con_local_win32_client_del(cl); +#endif + if (cl->buf) free(cl->buf); @@ -2060,7 +2090,7 @@ _ecore_con_cl_read(Ecore_Con_Server *svr) } if ((!svr->delete_me) && (num > 0)) - ecore_con_event_server_data(svr, buf, num); + ecore_con_event_server_data(svr, buf, num, EINA_TRUE); if (lost_server) _ecore_con_server_kill(svr); @@ -2146,7 +2176,7 @@ _ecore_con_cl_udp_handler(void *data, num = read(svr->fd, buf, READBUFSIZ); if ((!svr->delete_me) && (num > 0)) - ecore_con_event_server_data(svr, buf, num); + ecore_con_event_server_data(svr, buf, num, EINA_TRUE); if (num < 0 && (errno != EAGAIN) && (errno != EINTR)) { @@ -2229,7 +2259,7 @@ _ecore_con_svr_udp_handler(void *data, svr->client_count++; ecore_con_event_client_add(cl); - ecore_con_event_client_data(cl, buf, num); + ecore_con_event_client_data(cl, buf, num, EINA_TRUE); return ECORE_CALLBACK_RENEW; } @@ -2237,11 +2267,12 @@ _ecore_con_svr_udp_handler(void *data, static void _ecore_con_svr_cl_read(Ecore_Con_Client *cl) { - DBG("cl=%p", cl); int num = 0; Eina_Bool lost_client = EINA_TRUE; unsigned char buf[READBUFSIZ]; + DBG("cl=%p", cl); + if (cl->handshaking) { /* add an extra handshake attempt just before read, even though @@ -2271,7 +2302,7 @@ _ecore_con_svr_cl_read(Ecore_Con_Client *cl) } if ((!cl->delete_me) && (num > 0)) - ecore_con_event_client_data(cl, buf, num); + ecore_con_event_client_data(cl, buf, num, EINA_TRUE); if (lost_client) { @@ -2327,6 +2358,11 @@ _ecore_con_server_flush(Ecore_Con_Server *svr) { int count, num; +#ifdef _WIN32 + if (ecore_con_local_win32_server_flush(svr)) + return; +#endif + if (!svr->write_buf && svr->fd_handler) { ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); @@ -2386,6 +2422,11 @@ _ecore_con_client_flush(Ecore_Con_Client *cl) { int num, count = 0; +#ifdef _WIN32 + if (ecore_con_local_win32_client_flush(cl)) + return; +#endif + if (!cl->buf && cl->fd_handler) { ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c b/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c new file mode 100644 index 0000000000..ed634bb9a5 --- /dev/null +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_local_win32.c @@ -0,0 +1,784 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include + +#include "Ecore_Con.h" +#include "ecore_con_private.h" + +#define BUFSIZE 512 + + +static int _ecore_con_local_init_count = 0; + +int +ecore_con_local_init(void) +{ + if (++_ecore_con_local_init_count != 1) + return _ecore_con_local_init_count; + + return _ecore_con_local_init_count; +} + +int +ecore_con_local_shutdown(void) +{ + if (--_ecore_con_local_init_count != 0) + return _ecore_con_local_init_count; + + return _ecore_con_local_init_count; +} + + +static Eina_Bool +_ecore_con_local_win32_server_read_client_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl; + void *buf; + DWORD n; + Eina_Bool broken_pipe = EINA_FALSE; + + cl = (Ecore_Con_Client *)data; + + if (!ResetEvent(cl->host_server->event_read)) + return ECORE_CALLBACK_RENEW; + + buf = malloc(cl->host_server->nbr_bytes); + if (!buf) + return ECORE_CALLBACK_RENEW; + + if (ReadFile(cl->host_server->pipe, buf, cl->host_server->nbr_bytes, &n, NULL)) + { + if (!cl->delete_me) + ecore_con_event_client_data(cl, buf, cl->host_server->nbr_bytes, EINA_FALSE); + cl->host_server->want_write = 1; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + broken_pipe = EINA_TRUE; + } + + if (broken_pipe) + { +#if 0 + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_client_error(cl, msg); + free(msg); + } +#endif + if (!cl->delete_me) + ecore_con_event_client_del(cl); + cl->dead = EINA_TRUE; + return ECORE_CALLBACK_CANCEL; + } + + if (cl->host_server->want_write) + ecore_con_local_win32_client_flush(cl); + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_server_peek_client_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl; +#if 0 + char *msg; +#endif + + cl = (Ecore_Con_Client *)data; + + if (!ResetEvent(cl->host_server->event_peek)) + return ECORE_CALLBACK_RENEW; + +#if 0 + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(cl->host_server, msg); + free(msg); + } +#endif + if (!cl->host_server->delete_me) + ecore_con_event_server_del(cl->host_server); + cl->host_server->dead = EINA_TRUE; + return ECORE_CALLBACK_CANCEL; + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_client_peek_server_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Server *svr; +#if 0 + char *msg; +#endif + + svr = (Ecore_Con_Server *)data; + + if (!ResetEvent(svr->event_peek)) + return ECORE_CALLBACK_RENEW; +#if 0 + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } +#endif + if (!svr->delete_me) + ecore_con_event_server_del(svr); + svr->dead = EINA_TRUE; + return ECORE_CALLBACK_CANCEL; + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +static Eina_Bool +_ecore_con_local_win32_client_read_server_handler(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Server *svr; + void *buf; + DWORD n; + Eina_Bool broken_pipe = EINA_FALSE; + + svr = (Ecore_Con_Server *)data; + + if (!ResetEvent(svr->event_read)) + return ECORE_CALLBACK_RENEW; + + buf = malloc(svr->nbr_bytes); + if (!buf) + return ECORE_CALLBACK_RENEW; + + if (ReadFile(svr->pipe, buf, svr->nbr_bytes, &n, NULL)) + { + if (!svr->delete_me) + ecore_con_event_server_data(svr, buf, svr->nbr_bytes, EINA_FALSE); + svr->want_write = 1; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + broken_pipe = EINA_TRUE; + } + + if (broken_pipe) + { +#if 0 + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } +#endif + if (!svr->delete_me) + ecore_con_event_server_del(svr); + svr->dead = EINA_TRUE; + return ECORE_CALLBACK_CANCEL; + } + + if (svr->want_write) + ecore_con_local_win32_server_flush(svr); + + ecore_main_win32_handler_del(wh); + + return ECORE_CALLBACK_DONE; +} + +/* thread to read data sent by the server to the client */ +static unsigned int __stdcall +_ecore_con_local_win32_client_read_server_thread(void *data) +{ + Ecore_Con_Server *svr; + DWORD nbr_bytes = 0; + + svr = (Ecore_Con_Server *)data; + + svr->read_stopped = EINA_FALSE; + + while (!svr->read_stop) + { + if (PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) + { + if (nbr_bytes <= 0) + continue; + + svr->nbr_bytes = nbr_bytes; + if (!SetEvent(svr->event_read)) + continue; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + { + if (!SetEvent(svr->event_peek)) + continue; + break; + } + } + } + + printf(" ### %s\n", __FUNCTION__); + svr->read_stopped = EINA_TRUE; + _endthreadex(0); + return 0; +} + +/* thread to read data sent by the client to the server */ +static unsigned int __stdcall +_ecore_con_local_win32_server_read_client_thread(void *data) +{ + Ecore_Con_Client *cl; + DWORD nbr_bytes = 0; + + cl = (Ecore_Con_Client *)data; + + cl->host_server->read_stopped = EINA_FALSE; + + while (!cl->host_server->read_stop) + { + if (PeekNamedPipe(cl->host_server->pipe, NULL, 0, NULL, &nbr_bytes, NULL)) + { + if (nbr_bytes <= 0) + continue; + + cl->host_server->nbr_bytes = nbr_bytes; + if (!SetEvent(cl->host_server->event_read)) + continue; + } + else + { + if (GetLastError() == ERROR_BROKEN_PIPE) + { + if (!SetEvent(cl->host_server->event_peek)) + continue; + break; + } + } + } + + printf(" ### %s\n", __FUNCTION__); + cl->host_server->read_stopped = EINA_TRUE; + _endthreadex(0); + return 0; +} + +static Eina_Bool +_ecore_con_local_win32_client_add(void *data, Ecore_Win32_Handler *wh) +{ + Ecore_Con_Client *cl = NULL; + Ecore_Con_Server *svr; + Ecore_Win32_Handler *handler_read; + Ecore_Win32_Handler *handler_peek; + + svr = (Ecore_Con_Server *)data; + + if (!svr->pipe) + return ECORE_CALLBACK_CANCEL; + + if (svr->dead) + return ECORE_CALLBACK_CANCEL; + + if (svr->delete_me) + return ECORE_CALLBACK_CANCEL; + + if ((svr->client_limit >= 0) && (!svr->reject_excess_clients) && + (svr->client_count >= (unsigned int)svr->client_limit)) + return ECORE_CALLBACK_CANCEL; + + cl = calloc(1, sizeof(Ecore_Con_Client)); + if (!cl) + { + ERR("allocation failed"); + return ECORE_CALLBACK_CANCEL; + } + + cl->host_server = svr; + ECORE_MAGIC_SET(cl, ECORE_MAGIC_CON_CLIENT); + + cl->host_server->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!cl->host_server->event_read) + { + ERR("Can not create event read"); + goto free_cl; + } + + handler_read = ecore_main_win32_handler_add(cl->host_server->event_read, + _ecore_con_local_win32_server_read_client_handler, + cl); + if (!handler_read) + { + ERR("Can not create handler read"); + goto close_event_read; + } + + cl->host_server->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!cl->host_server->event_peek) + { + ERR("Can not create event peek"); + goto del_handler_read; + } + + handler_peek = ecore_main_win32_handler_add(cl->host_server->event_peek, + _ecore_con_local_win32_server_peek_client_handler, + cl); + if (!handler_peek) + { + ERR("Can not create handler peek"); + goto close_event_peek; + } + + cl->host_server->read_stopped = EINA_TRUE; + cl->host_server->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_server_read_client_thread, cl, CREATE_SUSPENDED, NULL); + if (!cl->host_server->thread_read) + { + ERR("Can not launch thread"); + goto del_handler_peek; + } + + svr->clients = eina_list_append(svr->clients, cl); + svr->client_count++; + + if (!cl->delete_me) + ecore_con_event_client_add(cl); + + ecore_main_win32_handler_del(wh); + + ResumeThread(cl->host_server->thread_read); + return ECORE_CALLBACK_DONE; + + del_handler_peek: + ecore_main_win32_handler_del(handler_peek); + close_event_peek: + CloseHandle(cl->host_server->event_peek); + del_handler_read: + ecore_main_win32_handler_del(handler_read); + close_event_read: + CloseHandle(cl->host_server->event_read); + free_cl: + free(cl); + + return ECORE_CALLBACK_CANCEL; +} + +static unsigned int __stdcall +_ecore_con_local_win32_listening(void *data) +{ + Ecore_Con_Server *svr; + BOOL res; + + svr = (Ecore_Con_Server *)data; + + while (1) + { + res = ConnectNamedPipe(svr->pipe, NULL); + if (!res) + { + ERR("Opening the connection to the client failed"); + CloseHandle(svr->pipe); + svr->pipe = NULL; + } + break; + } + + DBG("Client connected"); + + printf(" ### %s\n", __FUNCTION__); + _endthreadex(0); + return 0; +} + +Eina_Bool +ecore_con_local_listen(Ecore_Con_Server *svr) +{ + char buf[256]; + HANDLE thread_listening; + Ecore_Win32_Handler *handler; + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + { + ERR("Your system does not support abstract sockets!"); + return EINA_FALSE; + } + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); + else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) + { + const char *computername; + + computername = getenv("CoMPUTERNAME"); + snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); + } + + svr->path = strdup(buf); + if (!svr->path) + { + ERR("Allocation failed"); + return EINA_FALSE; + } + + /* + * synchronuous + * block mode + * wait mode + */ + svr->pipe = CreateNamedPipe(svr->path, + PIPE_ACCESS_DUPLEX, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, + BUFSIZE, + BUFSIZE, + 5000, + NULL); + if (svr->pipe == INVALID_HANDLE_VALUE) + { + ERR("Creation of the named pipe failed"); + goto free_path; + } + + /* + * We use ConnectNamedPipe() to wait for a client to connect. + * As the function is blocking, to let the main loop continuing + * its iterations, we call ConnectNamedPipe() in a thread + */ + thread_listening = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_listening, svr, CREATE_SUSPENDED, NULL); + if (!thread_listening) + { + ERR("Creation of the listening thread failed"); + goto close_pipe; + } + + handler = ecore_main_win32_handler_add(thread_listening, + _ecore_con_local_win32_client_add, + svr); + if (!handler) + { + ERR("Creation of the client add handler failed"); + goto del_handler; + } + + svr->read_stopped = EINA_TRUE; + ResumeThread(thread_listening); + + return EINA_TRUE; + + del_handler: + ecore_main_win32_handler_del(handler); + close_pipe: + CloseHandle(svr->pipe); + free_path: + free(svr->path); + svr->path = NULL; + + return EINA_FALSE; +} + +void +ecore_con_local_win32_server_del(Ecore_Con_Server *svr) +{ + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return; + + if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return; + + svr->read_stop = 1; + while (!svr->read_stopped) + Sleep(100); + + if (svr->event_peek) + CloseHandle(svr->event_peek); + svr->event_peek = NULL; + if (svr->event_read) + CloseHandle(svr->event_read); + svr->event_read = NULL; + free(svr->path); + svr->path = NULL; + if (svr->pipe) + CloseHandle(svr->pipe); + svr->pipe = NULL; +} + +void +ecore_con_local_win32_client_del(Ecore_Con_Client *cl) +{ + if ((cl->host_server->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return; + + if (((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((cl->host_server->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return; + + cl->host_server->read_stop = 1; + while (!cl->host_server->read_stopped) + Sleep(100); + + if (cl->host_server->event_peek) + CloseHandle(cl->host_server->event_peek); + cl->host_server->event_peek = NULL; + if (cl->host_server->event_read) + CloseHandle(cl->host_server->event_read); + cl->host_server->event_read = NULL; + free(cl->host_server->path); + cl->host_server->path = NULL; + if (cl->host_server->pipe) + CloseHandle(cl->host_server->pipe); + cl->host_server->pipe = NULL; +} + +Eina_Bool +ecore_con_local_connect(Ecore_Con_Server *svr, + Eina_Bool (*cb_done)(void *data, + Ecore_Fd_Handler *fd_handler), + void (*cb_free)(void *data, void *ev)) +{ + char buf[256]; + Ecore_Win32_Handler *handler_read; + Ecore_Win32_Handler *handler_peek; + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + { + ERR("Your system does not support abstract sockets!"); + return EINA_FALSE; + } + + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_USER) + snprintf(buf, sizeof(buf), "\\\\.\\pipe\\%s", svr->name); + else if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_SYSTEM) + { + const char *computername; + + computername = getenv("COMPUTERNAME"); + snprintf(buf, sizeof(buf), "\\\\%s\\pipe\\%s", computername, svr->name); + } + + while (1) + { + svr->pipe = CreateFile(buf, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL); + if (svr->pipe != INVALID_HANDLE_VALUE) + break; + + /* if pipe not busy, we exit */ + if (GetLastError() != ERROR_PIPE_BUSY) + { + ERR("Connection to a server failed"); + return EINA_FALSE; + } + + /* pipe busy, so we wait for it */ + if (!WaitNamedPipe(buf, NMPWAIT_WAIT_FOREVER)) + { + ERR("Can not wait for a server"); + goto close_pipe; + } + } + + svr->path = strdup(buf); + if (!svr->path) + { + ERR("Allocation failed"); + goto close_pipe; + } + + svr->event_read = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!svr->event_read) + { + ERR("Can not create event read"); + goto free_path; + } + + handler_read = ecore_main_win32_handler_add(svr->event_read, + _ecore_con_local_win32_client_read_server_handler, + svr); + if (!handler_read) + { + ERR("Can not create handler read"); + goto close_event_read; + } + + svr->event_peek = CreateEvent(NULL, TRUE, FALSE, NULL); + if (!svr->event_peek) + { + ERR("Can not create event peek"); + goto del_handler_read; + } + + handler_peek = ecore_main_win32_handler_add(svr->event_peek, + _ecore_con_local_win32_client_peek_server_handler, + svr); + if (!handler_peek) + { + ERR("Can not create handler peek"); + goto close_event_peek; + } + + svr->thread_read = (HANDLE)_beginthreadex(NULL, 0, _ecore_con_local_win32_client_read_server_thread, svr, CREATE_SUSPENDED, NULL); + if (!svr->thread_read) + { + ERR("Can not launch thread"); + goto del_handler_peek; + } + + if (!svr->delete_me) + { + Ecore_Con_Event_Server_Add *e; + + e = calloc(1, sizeof(Ecore_Con_Event_Server_Add)); + if (e) + { + svr->event_count++; + e->server = svr; + ecore_event_add(ECORE_CON_EVENT_SERVER_ADD, e, + cb_free, NULL); + } + } + + ResumeThread(svr->thread_read); + + return EINA_TRUE; + + del_handler_peek: + ecore_main_win32_handler_del(handler_peek); + close_event_peek: + CloseHandle(svr->event_peek); + del_handler_read: + ecore_main_win32_handler_del(handler_read); + close_event_read: + CloseHandle(svr->event_read); + free_path: + free(svr->path); + svr->path = NULL; + close_pipe: + CloseHandle(svr->pipe); + + return EINA_FALSE; +} + +Eina_Bool +ecore_con_local_win32_server_flush(Ecore_Con_Server *svr) +{ + int num; + BOOL res; + DWORD written; + + /* This check should never be true */ + if ((svr->type & ECORE_CON_TYPE) == ECORE_CON_LOCAL_ABSTRACT) + return EINA_TRUE; + + if (((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_USER) && + ((svr->type & ECORE_CON_TYPE) != ECORE_CON_LOCAL_SYSTEM)) + return EINA_FALSE; + + num = svr->write_buf_size - svr->write_buf_offset; + if (num <= 0) return EINA_TRUE; + + res = WriteFile(svr->pipe, svr->write_buf + svr->write_buf_offset, num, &written, NULL); + if (!res) + { + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_server_error(svr, msg); + free(msg); + } + if (!svr->delete_me) + ecore_con_event_server_del(svr); + svr->dead = EINA_TRUE; + } + + svr->write_buf_offset += written; + if (svr->write_buf_offset >= svr->write_buf_size) + { + svr->write_buf_size = 0; + svr->write_buf_offset = 0; + free(svr->write_buf); + svr->write_buf = NULL; + svr->want_write = 0; + } + else if (written < (DWORD)num) + svr->want_write = 1; + + return EINA_TRUE; +} + +Eina_Bool +ecore_con_local_win32_client_flush(Ecore_Con_Client *cl) +{ + Ecore_Con_Type type; + int num; + BOOL res; + DWORD written; + + type = cl->host_server->type & ECORE_CON_TYPE; + + /* This check should never be true */ + if (type == ECORE_CON_LOCAL_ABSTRACT) + return EINA_TRUE; + + if ((type != ECORE_CON_LOCAL_USER) && + (type != ECORE_CON_LOCAL_SYSTEM)) + return EINA_FALSE; + + num = cl->buf_size - cl->buf_offset; + if (num <= 0) return EINA_TRUE; + + res = WriteFile(cl->host_server->pipe, cl->buf + cl->buf_offset, num, &written, NULL); + if (!res) + { + char *msg; + + msg = evil_last_error_get(); + if (msg) + { + ecore_con_event_client_error(cl, msg); + free(msg); + } + if (!cl->delete_me) + ecore_con_event_client_del(cl); + cl->dead = EINA_TRUE; + } + + cl->buf_offset += written; + if (cl->buf_offset >= cl->buf_size) + { + cl->buf_size = 0; + cl->buf_offset = 0; + free(cl->buf); + cl->buf = NULL; + cl->host_server->want_write = 0; + } + else if (written < (DWORD)num) + cl->host_server->want_write = 1; + + return EINA_TRUE; +} diff --git a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h b/legacy/ecore/src/lib/ecore_con/ecore_con_private.h index 057434152c..f484b2db6a 100644 --- a/legacy/ecore/src/lib/ecore_con/ecore_con_private.h +++ b/legacy/ecore/src/lib/ecore_con/ecore_con_private.h @@ -157,6 +157,16 @@ struct _Ecore_Con_Server Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */ Eina_Bool reject_excess_clients : 1; Eina_Bool delete_me : 1; +#ifdef _WIN32 + Eina_Bool want_write : 1; + Eina_Bool read_stop : 1; + Eina_Bool read_stopped : 1; + HANDLE pipe; + HANDLE thread_read; + HANDLE event_read; + HANDLE event_peek; + DWORD nbr_bytes; +#endif }; #ifdef HAVE_CURL @@ -200,9 +210,26 @@ struct _Ecore_Con_Lookup /* from ecore_con.c */ void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); +void ecore_con_event_server_data(Ecore_Con_Server *svr, unsigned char *buf, int num, Eina_Bool duplicate); +void ecore_con_event_server_del(Ecore_Con_Server *svr); void ecore_con_event_server_error(Ecore_Con_Server *svr, const char *error); +void ecore_con_event_client_add(Ecore_Con_Client *cl); +void ecore_con_event_client_data(Ecore_Con_Client *cl, unsigned char *buf, int num, Eina_Bool duplicate); +void ecore_con_event_client_del(Ecore_Con_Client *cl); void ecore_con_event_client_error(Ecore_Con_Client *cl, const char *error); +/* from ecore_local_win32.c */ +#ifdef _WIN32 +Eina_Bool ecore_con_local_listen(Ecore_Con_Server *svr); +Eina_Bool ecore_con_local_connect(Ecore_Con_Server *svr, + Eina_Bool (*cb_done)(void *data, + Ecore_Fd_Handler *fd_handler), + void (*cb_free)(void *data, void *ev)); +Eina_Bool ecore_con_local_win32_server_flush(Ecore_Con_Server *svr); +Eina_Bool ecore_con_local_win32_client_flush(Ecore_Con_Client *cl); +void ecore_con_local_win32_server_del(Ecore_Con_Server *svr); +void ecore_con_local_win32_client_del(Ecore_Con_Client *cl); +#else /* from ecore_local.c */ int ecore_con_local_init(void); int ecore_con_local_shutdown(void); @@ -218,6 +245,8 @@ int ecore_con_local_listen(Ecore_Con_Server *svr, void *data, Ecore_Fd_Handler *fd_handler), void *data); +#endif + /* from ecore_con_info.c */ int ecore_con_info_init(void); int ecore_con_info_shutdown(void);