evas_async_events: integrated Ecore_Pipe in evas_async_events

Summary:
Integrated Ecore_Pipe in evas_async_events

Reviewers: #eflete, raster, jpeg, vtorri, artem.popov, cedric

Reviewed By: cedric

Subscribers: cedric, jpeg

Differential Revision: https://phab.enlightenment.org/D4622

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Ivan Furs 2017-02-07 13:40:48 -08:00 committed by Cedric BAIL
parent bb928cbb93
commit ea0492e0c6
1 changed files with 57 additions and 125 deletions

View File

@ -7,29 +7,15 @@
#endif
#include <errno.h>
#include "evas_common_private.h"
#include "evas_private.h"
#ifdef _WIN32
# include <winsock2.h>
# define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
# define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
# define pipe_close(fd) closesocket(fd)
# define PIPE_FD_ERROR SOCKET_ERROR
#else
# include <fcntl.h>
# define pipe_write(fd, buffer, size) write((fd), buffer, size)
# define pipe_read(fd, buffer, size) read((fd), buffer, size)
# define pipe_close(fd) close(fd)
# define PIPE_FD_ERROR -1
#endif /* ! _WIN32 */
#include <fcntl.h>
#include "evas_common_private.h"
#include "evas_private.h"
#include "Ecore.h"
typedef struct _Evas_Event_Async Evas_Event_Async;
struct _Evas_Event_Async
@ -62,8 +48,8 @@ static int _thread_id = -1;
static int _thread_id_max = 0;
static int _thread_id_update = 0;
static int _fd_write = -1;
static int _fd_read = -1;
static Eina_Bool _write_error = EINA_TRUE;
static Eina_Bool _read_error = EINA_TRUE;
static pid_t _fd_pid = 0;
static Eina_Spinlock async_lock;
@ -71,53 +57,37 @@ static Eina_Inarray async_queue;
static Evas_Event_Async *async_queue_cache = NULL;
static unsigned int async_queue_cache_max = 0;
static Ecore_Pipe *_async_pipe = NULL;
static int _init_evas_event = 0;
static const int wakeup = 1;
Eina_Bool
_evas_fd_close_on_exec(int fd)
static void _evas_async_events_fd_blocking_set(Eina_Bool blocking EINA_UNUSED);
static void
_async_events_pipe_read_cb(void *data EINA_UNUSED, void *buf, unsigned int len)
{
#ifdef HAVE_FCNTL
int flags;
flags = fcntl(fd, F_GETFD);
if (flags == -1)
return EINA_FALSE;
flags |= FD_CLOEXEC;
if (fcntl(fd, F_SETFD, flags) == -1)
return EINA_FALSE;
return EINA_TRUE;
#else
(void) fd;
return EINA_FALSE;
#endif
if (wakeup == *(int*)buf && sizeof(int) == len)
_evas_async_events_fd_blocking_set(EINA_FALSE);
}
int
evas_async_events_init(void)
{
int filedes[2];
if (_init_evas_event++)
return _init_evas_event;
_fd_pid = getpid();
if (pipe(filedes) == -1)
_async_pipe = ecore_pipe_add(_async_events_pipe_read_cb, NULL);
if ( !_async_pipe )
{
_init_evas_event = 0;
return 0;
_init_evas_event = 0;
return 0;
}
_evas_fd_close_on_exec(filedes[0]);
_evas_fd_close_on_exec(filedes[1]);
_fd_read = filedes[0];
_fd_write = filedes[1];
#ifdef HAVE_FCNTL
if (fcntl(_fd_read, F_SETFL, O_NONBLOCK) < 0) ERR("Can't set NONBLOCK on async fd");
#endif
ecore_pipe_freeze(_async_pipe);
_read_error = EINA_FALSE;
_write_error = EINA_FALSE;
eina_spinlock_new(&async_lock);
eina_inarray_step_set(&async_queue, sizeof (Eina_Inarray), sizeof (Evas_Event_Async), 16);
@ -151,10 +121,9 @@ evas_async_events_shutdown(void)
eina_spinlock_free(&async_lock);
eina_inarray_flush(&async_queue);
pipe_close(_fd_read);
pipe_close(_fd_write);
_fd_read = -1;
_fd_write = -1;
ecore_pipe_del(_async_pipe);
_read_error = EINA_TRUE;
_write_error = EINA_TRUE;
return _init_evas_event;
}
@ -173,64 +142,46 @@ EAPI int
evas_async_events_fd_get(void)
{
_evas_async_events_fork_handle();
return _fd_read;
return ecore_pipe_read_fd(_async_pipe);
}
static int
_evas_async_events_process_single(void)
{
int ret, wakeup;
if (ecore_pipe_wait(_async_pipe, 1, 0.1) != 1)
return 0;
ret = pipe_read(_fd_read, &wakeup, sizeof(int));
if (ret < 0)
{
switch (errno)
{
case EBADF:
case EINVAL:
case EIO:
case EISDIR:
_fd_read = -1;
}
Evas_Event_Async *ev;
unsigned int len, max;
int nr;
return ret;
}
eina_spinlock_take(&async_lock);
if (ret == sizeof(int))
{
Evas_Event_Async *ev;
unsigned int len, max;
int nr;
ev = async_queue.members;
async_queue.members = async_queue_cache;
async_queue_cache = ev;
eina_spinlock_take(&async_lock);
max = async_queue.max;
async_queue.max = async_queue_cache_max;
async_queue_cache_max = max;
ev = async_queue.members;
async_queue.members = async_queue_cache;
async_queue_cache = ev;
len = async_queue.len;
async_queue.len = 0;
max = async_queue.max;
async_queue.max = async_queue_cache_max;
async_queue_cache_max = max;
eina_spinlock_release(&async_lock);
len = async_queue.len;
async_queue.len = 0;
DBG("Evas async events queue length: %u", len);
nr = len;
eina_spinlock_release(&async_lock);
while (len > 0)
{
if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
ev++;
len--;
}
DBG("Evas async events queue length: %u", len);
nr = len;
return nr;
while (len > 0)
{
if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
ev++;
len--;
}
return nr;
}
return 0;
}
EAPI int
@ -238,8 +189,7 @@ evas_async_events_process(void)
{
int nr, count = 0;
if (_fd_read == -1) return -1;
if (_read_error) return -1;
_evas_async_events_fork_handle();
while ((nr = _evas_async_events_process_single()) > 0) count += nr;
@ -251,6 +201,7 @@ static void
_evas_async_events_fd_blocking_set(Eina_Bool blocking)
{
#ifdef HAVE_FCNTL
int _fd_read = ecore_pipe_read_fd(_async_pipe);
long flags = fcntl(_fd_read, F_GETFL);
if (blocking) flags &= ~O_NONBLOCK;
@ -266,6 +217,7 @@ EAPI int
evas_async_events_process_blocking(void)
{
int ret;
if (_read_error) return -1;
_evas_async_events_fork_handle();
@ -281,10 +233,10 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i
{
Evas_Event_Async *ev;
unsigned int count;
Eina_Bool ret;
Eina_Bool ret = EINA_TRUE;;
if (!func) return EINA_FALSE;
if (_fd_write == -1) return EINA_FALSE;
if (_write_error) return EINA_FALSE;
_evas_async_events_fork_handle();
@ -307,32 +259,12 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i
if (count == 0)
{
int wakeup = 1;
ssize_t check;
do
{
check = pipe_write(_fd_write, &wakeup, sizeof (int));
}
while ((check != sizeof (int)) &&
((errno == EINTR) || (errno == EAGAIN)));
if (check == sizeof (int)) ret = EINA_TRUE;
else
if (!ecore_pipe_write(_async_pipe, &wakeup, sizeof(int)))
{
ret = EINA_FALSE;
switch (errno)
{
case EBADF:
case EINVAL:
case EIO:
case EPIPE:
_fd_write = -1;
}
_write_error = EINA_TRUE;
}
}
else ret = EINA_TRUE;
return ret;
}