Ecore: ecore_con : make ecore_con work on Windows

The ecore_con module needed a port of the local connections
with named pipes. The other connections (TCP, UDP) are using
BSD sockets, which are also used on Windows.

No abstract sockets on Windows.

NB: Should I backport that commit to 1.0 ?

SVN revision: 59385
This commit is contained in:
Vincent Torri 2011-05-14 17:52:30 +00:00
parent 021819f4f9
commit 3e9bc8fddd
7 changed files with 903 additions and 33 deletions

View File

@ -169,10 +169,15 @@
2011-05-12 Carsten Haitzler (The Rasterman) 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 to plug in external animator tick sources like vblank interrupts
and so on. and so on.
2011-05-14 Cedric Bail 2011-05-14 Cedric Bail
* Sync GNUTLS threads activation with Eina. * Sync GNUTLS threads activation with Eina.
2011-05-14 Vincent Torri
* Make ecore_con work on Windows (only the local connections
need a port)

View File

@ -172,7 +172,6 @@ case "$host_os" in
want_notify_win32="yes" want_notify_win32="yes"
want_curl="yes" want_curl="yes"
want_glib="auto" want_glib="auto"
want_ecore_con="no"
want_ecore_imf="yes" want_ecore_imf="yes"
want_ecore_win32="yes" want_ecore_win32="yes"
want_ecore_evas_software_gdi="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.])], [AC_HELP_STRING([--disable-abstract-sockets], [disable abstract sockets.])],
[ [
if test "x${enableval}" = "xyes" ; then if test "x${enableval}" = "xyes" ; then
want_abstract_sockets="yes" want_ecore_con_abstract_sockets="yes"
else else
want_abstract_sockets="no" want_ecore_con_abstract_sockets="no"
fi 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]) AC_DEFINE([HAVE_ABSTRACT_SOCKETS], [1], [Have abstract sockets namespace])
fi fi
@ -361,8 +360,9 @@ case "$host_os" in
requirements_ecore_imf="evil ${requirements_ecore_imf}" requirements_ecore_imf="evil ${requirements_ecore_imf}"
requirements_ecore_imf_evas="evil ${requirements_ecore_imf_evas}" requirements_ecore_imf_evas="evil ${requirements_ecore_imf_evas}"
EFL_ECORE_BUILD="-DEFL_ECORE_BUILD" 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_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_BUILD="-DEFL_ECORE_IMF_BUILD"
EFL_ECORE_IMF_EVAS_BUILD="-DEFL_ECORE_IMF_EVAS_BUILD" EFL_ECORE_IMF_EVAS_BUILD="-DEFL_ECORE_IMF_EVAS_BUILD"
EFL_ECORE_INPUT_BUILD="-DEFL_ECORE_INPUT_BUILD" EFL_ECORE_INPUT_BUILD="-DEFL_ECORE_INPUT_BUILD"
@ -388,8 +388,9 @@ case "$host_os" in
esac esac
AC_SUBST(EFL_ECORE_BUILD) 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_EVAS_BUILD)
AC_SUBST(EFL_ECORE_FILE_BUILD)
AC_SUBST(EFL_ECORE_IMF_BUILD) AC_SUBST(EFL_ECORE_IMF_BUILD)
AC_SUBST(EFL_ECORE_IMF_EVAS_BUILD) AC_SUBST(EFL_ECORE_IMF_EVAS_BUILD)
AC_SUBST(EFL_ECORE_INPUT_BUILD) AC_SUBST(EFL_ECORE_INPUT_BUILD)

View File

@ -14,9 +14,13 @@
# undef EAPI # undef EAPI
#endif #endif
#ifdef _MSC_VER #ifdef _WIN32
# ifdef BUILDING_DLL # ifdef EFL_ECORE_CON_BUILD
# define EAPI __declspec(dllexport) # ifdef DLL_EXPORT
# define EAPI __declspec(dllexport)
# else
# define EAPI
# endif
# else # else
# define EAPI __declspec(dllimport) # define EAPI __declspec(dllimport)
# endif # endif

View File

@ -5,6 +5,7 @@ AM_CPPFLAGS = \
-I$(top_builddir)/src/lib/ecore_con \ -I$(top_builddir)/src/lib/ecore_con \
-I$(top_srcdir)/src/lib/ecore \ -I$(top_srcdir)/src/lib/ecore \
-I$(top_srcdir)/src/lib/ecore_con \ -I$(top_srcdir)/src/lib/ecore_con \
@EFL_ECORE_CON_BUILD@ \
@SSL_CFLAGS@ \ @SSL_CFLAGS@ \
@CURL_CFLAGS@ \ @CURL_CFLAGS@ \
@EINA_CFLAGS@ \ @EINA_CFLAGS@ \
@ -19,8 +20,13 @@ includesdir = $(includedir)/ecore-@VMAJ@
libecore_con_la_SOURCES = \ libecore_con_la_SOURCES = \
ecore_con.c \ ecore_con.c \
ecore_con_ssl.c \ ecore_con_ssl.c \
ecore_con_url.c \ ecore_con_url.c
ecore_con_local.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 if HAVE_CARES
libecore_con_la_SOURCES += ecore_con_ares.c libecore_con_la_SOURCES += ecore_con_ares.c

View File

@ -351,8 +351,13 @@ ecore_con_server_add(Ecore_Con_Type compl_type,
(type == ECORE_CON_LOCAL_SYSTEM) || (type == ECORE_CON_LOCAL_SYSTEM) ||
(type == ECORE_CON_LOCAL_ABSTRACT)) (type == ECORE_CON_LOCAL_ABSTRACT))
/* Local */ /* Local */
#ifdef _WIN32
if (!ecore_con_local_listen(svr))
goto error;
#else
if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr)) if (!ecore_con_local_listen(svr, _ecore_con_svr_tcp_handler, svr))
goto error; goto error;
#endif
if ((type == ECORE_CON_REMOTE_TCP) || if ((type == ECORE_CON_REMOTE_TCP) ||
(type == ECORE_CON_REMOTE_NODELAY)) (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_SYSTEM) ||
(type == ECORE_CON_LOCAL_ABSTRACT)) (type == ECORE_CON_LOCAL_ABSTRACT))
/* Local */ /* 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, if (!ecore_con_local_connect(svr, _ecore_con_cl_handler, svr,
_ecore_con_event_server_add_free)) _ecore_con_event_server_add_free))
goto goto
error; error;
#endif
if ((type == ECORE_CON_REMOTE_TCP) || if ((type == ECORE_CON_REMOTE_TCP) ||
(type == ECORE_CON_REMOTE_NODELAY)) (type == ECORE_CON_REMOTE_NODELAY))
@ -1191,7 +1203,7 @@ ecore_con_event_server_del(Ecore_Con_Server *svr)
} }
void 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; 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++; svr->event_count++;
e->server = svr; e->server = svr;
e->data = malloc(num); if (duplicate)
if (!e->data)
{ {
ERR("alloc!"); e->data = malloc(num);
free(e); if (!e->data)
return; {
ERR("alloc!");
free(e);
return;
}
memcpy(e->data, buf, num);
} }
memcpy(e->data, buf, num); else
e->data = buf;
e->size = num; e->size = num;
ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e, ecore_event_add(ECORE_CON_EVENT_SERVER_DATA, e,
_ecore_con_event_server_data_free, NULL); _ecore_con_event_server_data_free, NULL);
@ -1250,7 +1267,7 @@ ecore_con_event_client_del(Ecore_Con_Client *cl)
} }
void 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; Ecore_Con_Event_Client_Data *e;
e = malloc(sizeof(Ecore_Con_Event_Client_Data)); 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++; cl->event_count++;
_ecore_con_cl_timer_update(cl); _ecore_con_cl_timer_update(cl);
e->client = cl; e->client = cl;
e->data = malloc(num); if (duplicate)
if (!e->data)
{ {
free(cl->client_addr); e->data = malloc(num);
free(cl); if (!e->data)
return; {
free(cl->client_addr);
free(cl);
return;
}
memcpy(e->data, buf, num);
} }
else
memcpy(e->data, buf, num); e->data = buf;
e->size = num; e->size = num;
ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e, ecore_event_add(ECORE_CON_EVENT_CLIENT_DATA, e,
(Ecore_End_Cb)_ecore_con_event_client_data_free, cl->host_server); (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) if (svr->write_buf)
free(svr->write_buf); free(svr->write_buf);
@ -1410,6 +1435,11 @@ _ecore_con_client_free(Ecore_Con_Client *cl)
break; break;
} }
} }
#ifdef _WIN32
ecore_con_local_win32_client_del(cl);
#endif
if (cl->buf) if (cl->buf)
free(cl->buf); free(cl->buf);
@ -2060,7 +2090,7 @@ _ecore_con_cl_read(Ecore_Con_Server *svr)
} }
if ((!svr->delete_me) && (num > 0)) 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) if (lost_server)
_ecore_con_server_kill(svr); _ecore_con_server_kill(svr);
@ -2146,7 +2176,7 @@ _ecore_con_cl_udp_handler(void *data,
num = read(svr->fd, buf, READBUFSIZ); num = read(svr->fd, buf, READBUFSIZ);
if ((!svr->delete_me) && (num > 0)) 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)) if (num < 0 && (errno != EAGAIN) && (errno != EINTR))
{ {
@ -2229,7 +2259,7 @@ _ecore_con_svr_udp_handler(void *data,
svr->client_count++; svr->client_count++;
ecore_con_event_client_add(cl); 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; return ECORE_CALLBACK_RENEW;
} }
@ -2237,11 +2267,12 @@ _ecore_con_svr_udp_handler(void *data,
static void static void
_ecore_con_svr_cl_read(Ecore_Con_Client *cl) _ecore_con_svr_cl_read(Ecore_Con_Client *cl)
{ {
DBG("cl=%p", cl);
int num = 0; int num = 0;
Eina_Bool lost_client = EINA_TRUE; Eina_Bool lost_client = EINA_TRUE;
unsigned char buf[READBUFSIZ]; unsigned char buf[READBUFSIZ];
DBG("cl=%p", cl);
if (cl->handshaking) if (cl->handshaking)
{ {
/* add an extra handshake attempt just before read, even though /* 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)) 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) if (lost_client)
{ {
@ -2327,6 +2358,11 @@ _ecore_con_server_flush(Ecore_Con_Server *svr)
{ {
int count, num; int count, num;
#ifdef _WIN32
if (ecore_con_local_win32_server_flush(svr))
return;
#endif
if (!svr->write_buf && svr->fd_handler) if (!svr->write_buf && svr->fd_handler)
{ {
ecore_main_fd_handler_active_set(svr->fd_handler, ECORE_FD_READ); 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; int num, count = 0;
#ifdef _WIN32
if (ecore_con_local_win32_client_flush(cl))
return;
#endif
if (!cl->buf && cl->fd_handler) if (!cl->buf && cl->fd_handler)
{ {
ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ); ecore_main_fd_handler_active_set(cl->fd_handler, ECORE_FD_READ);

View File

@ -0,0 +1,784 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <process.h>
#include <Evil.h>
#include <Ecore.h>
#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;
}

View File

@ -157,6 +157,16 @@ struct _Ecore_Con_Server
Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */ Eina_Bool verify : 1; /* EINA_TRUE if certificates will be verified */
Eina_Bool reject_excess_clients : 1; Eina_Bool reject_excess_clients : 1;
Eina_Bool delete_me : 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 #ifdef HAVE_CURL
@ -200,9 +210,26 @@ struct _Ecore_Con_Lookup
/* from ecore_con.c */ /* from ecore_con.c */
void ecore_con_server_infos_del(Ecore_Con_Server *svr, void *info); 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_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); 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 */ /* from ecore_local.c */
int ecore_con_local_init(void); int ecore_con_local_init(void);
int ecore_con_local_shutdown(void); int ecore_con_local_shutdown(void);
@ -218,6 +245,8 @@ int ecore_con_local_listen(Ecore_Con_Server *svr,
void *data, void *data,
Ecore_Fd_Handler *fd_handler), Ecore_Fd_Handler *fd_handler),
void *data); void *data);
#endif
/* from ecore_con_info.c */ /* from ecore_con_info.c */
int ecore_con_info_init(void); int ecore_con_info_init(void);
int ecore_con_info_shutdown(void); int ecore_con_info_shutdown(void);