forked from enlightenment/efl
ecore: add Efl.Loop.Fd.
This allow you to monitor fd and get notification using Eo events. I have not implemented the buffered read as used by X. I think that if this is useful, we should just do another class to handle bufferred fd.
This commit is contained in:
parent
45d17f100e
commit
c96383e42c
|
@ -10,6 +10,7 @@ ecore_eolian_files_legacy = \
|
||||||
ecore_eolian_files = \
|
ecore_eolian_files = \
|
||||||
lib/ecore/efl_loop.eo \
|
lib/ecore/efl_loop.eo \
|
||||||
lib/ecore/efl_loop_user.eo \
|
lib/ecore/efl_loop_user.eo \
|
||||||
|
lib/ecore/efl_loop_fd.eo \
|
||||||
lib/ecore/ecore_parent.eo \
|
lib/ecore/ecore_parent.eo \
|
||||||
$(ecore_eolian_files_legacy)
|
$(ecore_eolian_files_legacy)
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ lib/ecore/ecore_idler.c \
|
||||||
lib/ecore/ecore_job.c \
|
lib/ecore/ecore_job.c \
|
||||||
lib/ecore/ecore_main.c \
|
lib/ecore/ecore_main.c \
|
||||||
lib/ecore/efl_loop_user.c \
|
lib/ecore/efl_loop_user.c \
|
||||||
|
lib/ecore/efl_loop_fd.c \
|
||||||
lib/ecore/ecore_pipe.c \
|
lib/ecore/ecore_pipe.c \
|
||||||
lib/ecore/ecore_poller.c \
|
lib/ecore/ecore_poller.c \
|
||||||
lib/ecore/ecore_time.c \
|
lib/ecore/ecore_time.c \
|
||||||
|
|
|
@ -64,6 +64,8 @@ extern "C" {
|
||||||
|
|
||||||
#include "efl_loop_user.eo.h"
|
#include "efl_loop_user.eo.h"
|
||||||
|
|
||||||
|
#include "efl_loop_fd.eo.h"
|
||||||
|
|
||||||
/* We ue the factory pattern here, so you shouldn't call eo_add directly. */
|
/* We ue the factory pattern here, so you shouldn't call eo_add directly. */
|
||||||
EAPI Eo *ecore_main_loop_get(void);
|
EAPI Eo *ecore_main_loop_get(void);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <Ecore.h>
|
||||||
|
|
||||||
|
#include "ecore_private.h"
|
||||||
|
|
||||||
|
#define MY_CLASS EFL_LOOP_FD_CLASS
|
||||||
|
|
||||||
|
typedef struct _Efl_Loop_Fd_Data Efl_Loop_Fd_Data;
|
||||||
|
struct _Efl_Loop_Fd_Data
|
||||||
|
{
|
||||||
|
Ecore_Fd_Handler *handler;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
unsigned int read;
|
||||||
|
unsigned int write;
|
||||||
|
unsigned int error;
|
||||||
|
} references;
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
Eina_Bool file : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_efl_loop_fd_read_cb(void *data, Ecore_Fd_Handler *fd_handler)
|
||||||
|
{
|
||||||
|
Eo *obj = data;
|
||||||
|
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
||||||
|
{
|
||||||
|
eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_READ, NULL);
|
||||||
|
}
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
||||||
|
{
|
||||||
|
eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_WRITE, NULL);
|
||||||
|
}
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_ERROR))
|
||||||
|
{
|
||||||
|
eo_event_callback_call(obj, EFL_LOOP_FD_EVENT_ERROR, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_fd_reset(Eo *obj, Efl_Loop_Fd_Data *pd)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (pd->handler) ecore_main_fd_handler_del(pd->handler);
|
||||||
|
pd->handler = NULL;
|
||||||
|
if (pd->fd < 0) return ;
|
||||||
|
flags |= pd->references.read > 0 ? ECORE_FD_READ : 0;
|
||||||
|
flags |= pd->references.write > 0 ? ECORE_FD_WRITE : 0;
|
||||||
|
flags |= pd->references.error > 0 ? ECORE_FD_ERROR : 0;
|
||||||
|
if (flags == 0) return ;
|
||||||
|
|
||||||
|
if (pd->file)
|
||||||
|
pd->handler = ecore_main_fd_handler_file_add(pd->fd, flags, _efl_loop_fd_read_cb, obj, NULL, NULL);
|
||||||
|
else
|
||||||
|
pd->handler = ecore_main_fd_handler_add(pd->fd, flags, _efl_loop_fd_read_cb, obj, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_fd_fd_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
|
||||||
|
{
|
||||||
|
pd->fd = fd;
|
||||||
|
pd->file = EINA_FALSE;
|
||||||
|
_efl_loop_fd_reset(obj, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_efl_loop_fd_fd_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
|
||||||
|
{
|
||||||
|
return pd->file ? -1 : pd->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_fd_fd_file_set(Eo *obj, Efl_Loop_Fd_Data *pd, int fd)
|
||||||
|
{
|
||||||
|
pd->fd = fd;
|
||||||
|
pd->file = EINA_TRUE;
|
||||||
|
_efl_loop_fd_reset(obj, pd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_efl_loop_fd_fd_file_get(Eo *obj EINA_UNUSED, Efl_Loop_Fd_Data *pd)
|
||||||
|
{
|
||||||
|
return pd->file ? pd->fd : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_check_fd_event_catcher_add(void *data, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
const Eo_Callback_Array_Item *array = event->info;
|
||||||
|
Efl_Loop_Fd_Data *fd = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; array[i].desc != NULL; i++)
|
||||||
|
{
|
||||||
|
if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
|
||||||
|
{
|
||||||
|
if (fd->references.read++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
|
||||||
|
{
|
||||||
|
if (fd->references.write++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
|
||||||
|
{
|
||||||
|
if (fd->references.error++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EO_CALLBACK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_check_fd_event_catcher_del(void *data, const Eo_Event *event)
|
||||||
|
{
|
||||||
|
const Eo_Callback_Array_Item *array = event->info;
|
||||||
|
Efl_Loop_Fd_Data *fd = data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; array[i].desc != NULL; i++)
|
||||||
|
{
|
||||||
|
if (array[i].desc == EFL_LOOP_FD_EVENT_READ)
|
||||||
|
{
|
||||||
|
if (fd->references.read++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
else if (array[i].desc == EFL_LOOP_FD_EVENT_WRITE)
|
||||||
|
{
|
||||||
|
if (fd->references.write++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
if (array[i].desc == EFL_LOOP_FD_EVENT_ERROR)
|
||||||
|
{
|
||||||
|
if (fd->references.error++ > 0) continue;
|
||||||
|
_efl_loop_fd_reset(event->obj, fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return EO_CALLBACK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EO_CALLBACKS_ARRAY_DEFINE(fd_watch,
|
||||||
|
{ EO_BASE_EVENT_CALLBACK_ADD, _check_fd_event_catcher_add },
|
||||||
|
{ EO_BASE_EVENT_CALLBACK_DEL, _check_fd_event_catcher_del });
|
||||||
|
|
||||||
|
static Eo_Base *
|
||||||
|
_efl_loop_fd_eo_base_constructor(Eo *obj, Efl_Loop_Fd_Data *pd)
|
||||||
|
{
|
||||||
|
eo_constructor(eo_super(obj, MY_CLASS));
|
||||||
|
|
||||||
|
eo_event_callback_array_add(obj, fd_watch(), pd);
|
||||||
|
|
||||||
|
pd->fd = -1;
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_fd_eo_base_destructor(Eo *obj, Efl_Loop_Fd_Data *pd)
|
||||||
|
{
|
||||||
|
eo_destructor(eo_super(obj, MY_CLASS));
|
||||||
|
|
||||||
|
ecore_main_fd_handler_del(pd->handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "efl_loop_fd.eo.c"
|
|
@ -0,0 +1,46 @@
|
||||||
|
import eina_types;
|
||||||
|
|
||||||
|
class Efl.Loop.Fd (Efl.Loop_User)
|
||||||
|
{
|
||||||
|
[[Fds are objects that what the activity on a given
|
||||||
|
file descriptor. This file descriptor can be a
|
||||||
|
network, a file, provided by a library.
|
||||||
|
|
||||||
|
The object will trigger relevant event depending
|
||||||
|
on what is happening.]]
|
||||||
|
|
||||||
|
legacy_prefix: null;
|
||||||
|
methods {
|
||||||
|
@property fd {
|
||||||
|
[[Define which file descriptor to watch. If it is a file, use file_fd variant.]]
|
||||||
|
set {
|
||||||
|
[[Define the fd to watch on.]]
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
fd: int; [[The file descriptor.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property fd_file {
|
||||||
|
[[Define which file descriptor to watch when watching a file.]]
|
||||||
|
set {
|
||||||
|
[[Define the fd to watch on.]]
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
fd: int; [[The file descriptor.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
events {
|
||||||
|
read;
|
||||||
|
write;
|
||||||
|
error;
|
||||||
|
}
|
||||||
|
implements {
|
||||||
|
Eo.Base.constructor;
|
||||||
|
Eo.Base.destructor;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue