evas_async_events: Integrated Ecore_Pipe in evas_async_events
Summary: Integrated Ecore_Pipe in evas_async_events Reviewers: vtorri, artem.popov, cedric, jpeg, raster, #eflete Reviewed By: cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4622
This commit is contained in:
parent
966df3130a
commit
9d5a1d098c
|
@ -7,29 +7,15 @@
|
||||||
#endif
|
#endif
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "evas_common_private.h"
|
|
||||||
#include "evas_private.h"
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
# include <winsock2.h>
|
# 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 */
|
#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;
|
typedef struct _Evas_Event_Async Evas_Event_Async;
|
||||||
struct _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_max = 0;
|
||||||
static int _thread_id_update = 0;
|
static int _thread_id_update = 0;
|
||||||
|
|
||||||
static int _fd_write = -1;
|
static Eina_Bool _write_error = EINA_TRUE;
|
||||||
static int _fd_read = -1;
|
static Eina_Bool _read_error = EINA_TRUE;
|
||||||
static pid_t _fd_pid = 0;
|
static pid_t _fd_pid = 0;
|
||||||
|
|
||||||
static Eina_Spinlock async_lock;
|
static Eina_Spinlock async_lock;
|
||||||
|
@ -71,33 +57,79 @@ static Eina_Inarray async_queue;
|
||||||
static Evas_Event_Async *async_queue_cache = NULL;
|
static Evas_Event_Async *async_queue_cache = NULL;
|
||||||
static unsigned int async_queue_cache_max = 0;
|
static unsigned int async_queue_cache_max = 0;
|
||||||
|
|
||||||
|
static Ecore_Pipe *_async_pipe = NULL;
|
||||||
|
static int _event_count = 0;
|
||||||
|
|
||||||
|
|
||||||
static int _init_evas_event = 0;
|
static int _init_evas_event = 0;
|
||||||
|
static const int wakeup = 1;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (wakeup != *(int*)buf || sizeof(int) != len)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Evas_Event_Async *ev;
|
||||||
|
unsigned int ln, max;
|
||||||
|
int nr;
|
||||||
|
|
||||||
|
eina_spinlock_take(&async_lock);
|
||||||
|
|
||||||
|
ev = async_queue.members;
|
||||||
|
async_queue.members = async_queue_cache;
|
||||||
|
async_queue_cache = ev;
|
||||||
|
|
||||||
|
max = async_queue.max;
|
||||||
|
async_queue.max = async_queue_cache_max;
|
||||||
|
async_queue_cache_max = max;
|
||||||
|
|
||||||
|
ln = async_queue.len;
|
||||||
|
async_queue.len = 0;
|
||||||
|
|
||||||
|
eina_spinlock_release(&async_lock);
|
||||||
|
|
||||||
|
DBG("Evas async events queue length: %u", len);
|
||||||
|
nr = ln;
|
||||||
|
|
||||||
|
while (ln > 0)
|
||||||
|
{
|
||||||
|
if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
|
||||||
|
ev++;
|
||||||
|
ln--;
|
||||||
|
}
|
||||||
|
_event_count += nr;
|
||||||
|
|
||||||
|
_evas_async_events_fd_blocking_set(EINA_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
evas_async_events_init(void)
|
evas_async_events_init(void)
|
||||||
{
|
{
|
||||||
int filedes[2];
|
|
||||||
|
|
||||||
if (_init_evas_event++)
|
if (_init_evas_event++)
|
||||||
return _init_evas_event;
|
return _init_evas_event;
|
||||||
|
if ( !ecore_init() )
|
||||||
|
{
|
||||||
|
_init_evas_event = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
_fd_pid = getpid();
|
_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;
|
_init_evas_event = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
eina_file_close_on_exec(filedes[0], EINA_TRUE);
|
ecore_pipe_freeze(_async_pipe);
|
||||||
eina_file_close_on_exec(filedes[1], EINA_TRUE);
|
_read_error = EINA_FALSE;
|
||||||
|
_write_error = EINA_FALSE;
|
||||||
|
|
||||||
_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
|
|
||||||
|
|
||||||
eina_spinlock_new(&async_lock);
|
eina_spinlock_new(&async_lock);
|
||||||
eina_inarray_step_set(&async_queue, sizeof (Eina_Inarray), sizeof (Evas_Event_Async), 16);
|
eina_inarray_step_set(&async_queue, sizeof (Eina_Inarray), sizeof (Evas_Event_Async), 16);
|
||||||
|
@ -131,10 +163,10 @@ evas_async_events_shutdown(void)
|
||||||
eina_spinlock_free(&async_lock);
|
eina_spinlock_free(&async_lock);
|
||||||
eina_inarray_flush(&async_queue);
|
eina_inarray_flush(&async_queue);
|
||||||
|
|
||||||
pipe_close(_fd_read);
|
ecore_pipe_del(_async_pipe);
|
||||||
pipe_close(_fd_write);
|
_read_error = EINA_TRUE;
|
||||||
_fd_read = -1;
|
_write_error = EINA_TRUE;
|
||||||
_fd_write = -1;
|
ecore_shutdown();
|
||||||
|
|
||||||
return _init_evas_event;
|
return _init_evas_event;
|
||||||
}
|
}
|
||||||
|
@ -153,76 +185,19 @@ EAPI int
|
||||||
evas_async_events_fd_get(void)
|
evas_async_events_fd_get(void)
|
||||||
{
|
{
|
||||||
_evas_async_events_fork_handle();
|
_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;
|
|
||||||
|
|
||||||
ret = pipe_read(_fd_read, &wakeup, sizeof(int));
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EBADF:
|
|
||||||
case EINVAL:
|
|
||||||
case EIO:
|
|
||||||
case EISDIR:
|
|
||||||
_fd_read = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == sizeof(int))
|
|
||||||
{
|
|
||||||
Evas_Event_Async *ev;
|
|
||||||
unsigned int len, max;
|
|
||||||
int nr;
|
|
||||||
|
|
||||||
eina_spinlock_take(&async_lock);
|
|
||||||
|
|
||||||
ev = async_queue.members;
|
|
||||||
async_queue.members = async_queue_cache;
|
|
||||||
async_queue_cache = ev;
|
|
||||||
|
|
||||||
max = async_queue.max;
|
|
||||||
async_queue.max = async_queue_cache_max;
|
|
||||||
async_queue_cache_max = max;
|
|
||||||
|
|
||||||
len = async_queue.len;
|
|
||||||
async_queue.len = 0;
|
|
||||||
|
|
||||||
eina_spinlock_release(&async_lock);
|
|
||||||
|
|
||||||
DBG("Evas async events queue length: %u", len);
|
|
||||||
nr = len;
|
|
||||||
|
|
||||||
while (len > 0)
|
|
||||||
{
|
|
||||||
if (ev->func) ev->func((void *)ev->target, ev->type, ev->event_info);
|
|
||||||
ev++;
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
evas_async_events_process(void)
|
evas_async_events_process(void)
|
||||||
{
|
{
|
||||||
int nr, count = 0;
|
int count = 0;
|
||||||
|
if (_read_error) return -1;
|
||||||
if (_fd_read == -1) return -1;
|
|
||||||
|
|
||||||
_evas_async_events_fork_handle();
|
_evas_async_events_fork_handle();
|
||||||
|
|
||||||
while ((nr = _evas_async_events_process_single()) > 0) count += nr;
|
_event_count = 0;
|
||||||
|
while (ecore_pipe_wait(_async_pipe, 1, 0.0))
|
||||||
|
count = _event_count;
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -231,6 +206,7 @@ static void
|
||||||
_evas_async_events_fd_blocking_set(Eina_Bool blocking)
|
_evas_async_events_fd_blocking_set(Eina_Bool blocking)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_FCNTL
|
#ifdef HAVE_FCNTL
|
||||||
|
int _fd_read = ecore_pipe_read_fd(_async_pipe);
|
||||||
long flags = fcntl(_fd_read, F_GETFL);
|
long flags = fcntl(_fd_read, F_GETFL);
|
||||||
|
|
||||||
if (blocking) flags &= ~O_NONBLOCK;
|
if (blocking) flags &= ~O_NONBLOCK;
|
||||||
|
@ -246,11 +222,16 @@ EAPI int
|
||||||
evas_async_events_process_blocking(void)
|
evas_async_events_process_blocking(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
if (_read_error) return -1;
|
||||||
|
|
||||||
_evas_async_events_fork_handle();
|
_evas_async_events_fork_handle();
|
||||||
|
|
||||||
_evas_async_events_fd_blocking_set(EINA_TRUE);
|
_evas_async_events_fd_blocking_set(EINA_TRUE);
|
||||||
ret = _evas_async_events_process_single();
|
|
||||||
|
_event_count = 0;
|
||||||
|
ecore_pipe_wait(_async_pipe, 1, 0.0);
|
||||||
|
ret = _event_count;
|
||||||
|
|
||||||
_evas_async_events_fd_blocking_set(EINA_FALSE);
|
_evas_async_events_fd_blocking_set(EINA_FALSE);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -261,10 +242,10 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i
|
||||||
{
|
{
|
||||||
Evas_Event_Async *ev;
|
Evas_Event_Async *ev;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
Eina_Bool ret;
|
Eina_Bool ret = EINA_TRUE;;
|
||||||
|
|
||||||
if (!func) return EINA_FALSE;
|
if (!func) return EINA_FALSE;
|
||||||
if (_fd_write == -1) return EINA_FALSE;
|
if (_write_error) return EINA_FALSE;
|
||||||
|
|
||||||
_evas_async_events_fork_handle();
|
_evas_async_events_fork_handle();
|
||||||
|
|
||||||
|
@ -287,32 +268,12 @@ evas_async_events_put(const void *target, Evas_Callback_Type type, void *event_i
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
int wakeup = 1;
|
if (!ecore_pipe_write(_async_pipe, &wakeup, sizeof(int)))
|
||||||
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
|
|
||||||
{
|
{
|
||||||
ret = EINA_FALSE;
|
ret = EINA_FALSE;
|
||||||
|
_write_error = EINA_TRUE;
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
case EBADF:
|
|
||||||
case EINVAL:
|
|
||||||
case EIO:
|
|
||||||
case EPIPE:
|
|
||||||
_fd_write = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ret = EINA_TRUE;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue