forked from enlightenment/efl
ecore_main: Add ECORE_FD_ALWAYS flag
This allows an fd handler to be called after select exits unconditionally. Our wayland client code needs this to be thread safe, as it needs to call prepare_read before entering select, and then either read or cancel_read after select. Signed-off-by: Derek Foreman <derek.foreman.samsung@gmail.com> Reviewed-by: Chris Michael <cp.michael@samsung.com> Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D7914
This commit is contained in:
parent
46885653bc
commit
66ce295fc9
|
@ -1388,7 +1388,13 @@ enum _Ecore_Fd_Handler_Flags
|
|||
{
|
||||
ECORE_FD_READ = 1, /**< Fd Read mask */
|
||||
ECORE_FD_WRITE = 2, /**< Fd Write mask */
|
||||
ECORE_FD_ERROR = 4 /**< Fd Error mask */
|
||||
ECORE_FD_ERROR = 4, /**< Fd Error mask */
|
||||
/* ECORE_FD_ALWAYS is intended to fix a problem with wayland
|
||||
* and threads. It causes the fd handler to be called
|
||||
* in any state, so wayland libs can call read_cancel
|
||||
* if nothing is available to read. Everyone else should
|
||||
* stay away. */
|
||||
ECORE_FD_ALWAYS = 8, /**< Fd Always mask - DO NOT USE! */
|
||||
};
|
||||
typedef enum _Ecore_Fd_Handler_Flags Ecore_Fd_Handler_Flags;
|
||||
|
||||
|
|
|
@ -248,7 +248,7 @@ _ecore_try_add_to_call_list(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd, Ecore_Fd_Han
|
|||
DBG("next_ready");
|
||||
return;
|
||||
}
|
||||
if (fdh->read_active || fdh->write_active || fdh->error_active)
|
||||
if (fdh->read_active || fdh->write_active || fdh->error_active || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
DBG("added");
|
||||
// make sure next_ready is non-null by pointing to ourselves
|
||||
|
@ -583,6 +583,10 @@ _ecore_main_fdh_epoll_mark_active(Eo *obj, Efl_Loop_Data *pd)
|
|||
fdh->write_active = EINA_TRUE;
|
||||
fdh->error_active = EINA_TRUE;
|
||||
}
|
||||
/* We'll add this one anyway outside this function,
|
||||
don't want it twice */
|
||||
if (fdh->flags & ECORE_FD_ALWAYS)
|
||||
continue;
|
||||
|
||||
_ecore_try_add_to_call_list(obj, pd, fdh);
|
||||
}
|
||||
|
@ -1357,6 +1361,9 @@ _ecore_main_fd_handler_add(Eo *obj,
|
|||
if (is_file)
|
||||
pd->file_fd_handlers = eina_list_append
|
||||
(pd->file_fd_handlers, fdh);
|
||||
if (fdh->flags & ECORE_FD_ALWAYS)
|
||||
pd->always_fd_handlers = eina_list_append
|
||||
(pd->always_fd_handlers, fdh);
|
||||
pd->fd_handlers = (Ecore_Fd_Handler *)
|
||||
eina_inlist_append(EINA_INLIST_GET(pd->fd_handlers),
|
||||
EINA_INLIST_GET(fdh));
|
||||
|
@ -1664,6 +1671,9 @@ _ecore_main_content_clear(Eo *obj, Efl_Loop_Data *pd)
|
|||
if (pd->file_fd_handlers)
|
||||
pd->file_fd_handlers =
|
||||
eina_list_free(pd->file_fd_handlers);
|
||||
if (pd->always_fd_handlers)
|
||||
pd->always_fd_handlers =
|
||||
eina_list_free(pd->always_fd_handlers);
|
||||
if (pd->fd_handlers_to_delete)
|
||||
pd->fd_handlers_to_delete =
|
||||
eina_list_free(pd->fd_handlers_to_delete);
|
||||
|
@ -1741,7 +1751,7 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
|||
fd_set rfds, wfds, exfds;
|
||||
Ecore_Fd_Handler *fdh;
|
||||
Eina_List *l;
|
||||
int max_fd, ret;
|
||||
int max_fd, ret, outval;
|
||||
#ifndef _WIN32
|
||||
int err_no;
|
||||
#endif
|
||||
|
@ -1785,17 +1795,17 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
|||
{
|
||||
if (!fdh->delete_me)
|
||||
{
|
||||
if (fdh->flags & ECORE_FD_READ)
|
||||
if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &rfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
}
|
||||
if (fdh->flags & ECORE_FD_WRITE)
|
||||
if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &wfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
}
|
||||
if (fdh->flags & ECORE_FD_ERROR)
|
||||
if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &exfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
|
@ -1815,17 +1825,17 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
|||
{
|
||||
if (!fdh->delete_me)
|
||||
{
|
||||
if (fdh->flags & ECORE_FD_READ)
|
||||
if ((fdh->flags & ECORE_FD_READ) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &rfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
}
|
||||
if (fdh->flags & ECORE_FD_WRITE)
|
||||
if ((fdh->flags & ECORE_FD_WRITE) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &wfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
}
|
||||
if (fdh->flags & ECORE_FD_ERROR)
|
||||
if ((fdh->flags & ECORE_FD_ERROR) || (fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
FD_SET(fdh->fd, &exfds);
|
||||
if (fdh->fd > max_fd) max_fd = fdh->fd;
|
||||
|
@ -1851,7 +1861,11 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
|||
if (ret < 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
if (err_no == EINTR) return -1;
|
||||
if (err_no == EINTR)
|
||||
{
|
||||
outval = -1;
|
||||
goto BAIL;
|
||||
}
|
||||
else if (err_no == EBADF) _ecore_main_fd_handlers_bads_rem(obj, pd);
|
||||
#endif
|
||||
}
|
||||
|
@ -1890,13 +1904,22 @@ _ecore_main_select(Eo *obj, Efl_Loop_Data *pd, double timeout)
|
|||
_ecore_try_add_to_call_list(obj, pd, fdh);
|
||||
}
|
||||
}
|
||||
outval = 1;
|
||||
goto BAIL;
|
||||
}
|
||||
outval = 0;
|
||||
BAIL:
|
||||
EINA_LIST_FOREACH(pd->always_fd_handlers, l, fdh)
|
||||
_ecore_try_add_to_call_list(obj, pd, fdh);
|
||||
|
||||
if (ret > 0)
|
||||
{
|
||||
_ecore_main_fd_handlers_cleanup(obj, pd);
|
||||
#ifdef _WIN32
|
||||
_ecore_main_win32_handlers_cleanup(obj, pd);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return outval || pd->always_fd_handlers;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -2017,6 +2040,8 @@ _ecore_main_fd_handlers_cleanup(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
|
|||
EINA_INLIST_GET(fdh));
|
||||
if (fdh->file)
|
||||
pd->file_fd_handlers = eina_list_remove(pd->file_fd_handlers, fdh);
|
||||
if (fdh->flags & ECORE_FD_ALWAYS)
|
||||
pd->always_fd_handlers = eina_list_remove(pd->always_fd_handlers, fdh);
|
||||
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
|
||||
ecore_fd_handler_mp_free(fdh);
|
||||
pd->fd_handlers_to_delete = eina_list_remove_list
|
||||
|
@ -2074,7 +2099,8 @@ _ecore_main_fd_handlers_call(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd)
|
|||
{
|
||||
if ((fdh->read_active) ||
|
||||
(fdh->write_active) ||
|
||||
(fdh->error_active))
|
||||
(fdh->error_active) ||
|
||||
(fdh->flags & ECORE_FD_ALWAYS))
|
||||
{
|
||||
fdh->references++;
|
||||
if (!_ecore_call_fd_cb(fdh->func, fdh->data, fdh))
|
||||
|
|
|
@ -138,6 +138,7 @@ struct _Efl_Loop_Data
|
|||
Ecore_Fd_Handler *fd_handlers;
|
||||
Eina_List *fd_handlers_with_prep;
|
||||
Eina_List *file_fd_handlers;
|
||||
Eina_List *always_fd_handlers;
|
||||
Eina_List *fd_handlers_with_buffer;
|
||||
Eina_List *fd_handlers_to_delete;
|
||||
Ecore_Fd_Handler *fd_handlers_to_call;
|
||||
|
|
Loading…
Reference in New Issue