forked from enlightenment/efl
extend ecore fork infra to handle pipe re-create afetr fork for
ecore-evas. SVN revision: 75194
This commit is contained in:
parent
b51f30b082
commit
fe00bc661a
|
@ -852,3 +852,9 @@
|
||||||
|
|
||||||
* Correctly shutdown Ecore_Thread.
|
* Correctly shutdown Ecore_Thread.
|
||||||
* Add a way to reset Ecore_Thread internal pipe after a fork via ecore_fork_reset.
|
* Add a way to reset Ecore_Thread internal pipe after a fork via ecore_fork_reset.
|
||||||
|
|
||||||
|
2012-08-13 Carsten Haitzler (The Rasterman)
|
||||||
|
|
||||||
|
* Fix ecore fork reset function to allow for callbacks to be
|
||||||
|
attached so ecore-evas can reset evas async fd on fork.
|
||||||
|
|
||||||
|
|
|
@ -380,25 +380,6 @@ extern "C" {
|
||||||
|
|
||||||
EAPI int ecore_init(void);
|
EAPI int ecore_init(void);
|
||||||
EAPI int ecore_shutdown(void);
|
EAPI int ecore_shutdown(void);
|
||||||
/**
|
|
||||||
* Reset the ecore internal state after a fork
|
|
||||||
*
|
|
||||||
* Ecore maintains internal data that can be affected by the fork() system call
|
|
||||||
* which creates a duplicate of the current process. This also duplicates
|
|
||||||
* file descriptors which is problematic in that these file descriptors still
|
|
||||||
* point to their original sources. This function makes ecore reset internal
|
|
||||||
* state (e.g. pipes used for signalling between threads) so they function
|
|
||||||
* correctly afterwards.
|
|
||||||
*
|
|
||||||
* It is highly suggested that you call this function after any fork()
|
|
||||||
* system call inside the child process if you intend to use ecore features
|
|
||||||
* after this point and not call any exec() family functions. Not doing so
|
|
||||||
* will cause possible misbehaviour.
|
|
||||||
*
|
|
||||||
* @since 1.7
|
|
||||||
*/
|
|
||||||
EAPI void ecore_fork_reset(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
*/
|
*/
|
||||||
|
@ -472,6 +453,46 @@ typedef void (*Ecore_Cb)(void *data);
|
||||||
*/
|
*/
|
||||||
typedef void *(*Ecore_Data_Cb)(void *data);
|
typedef void *(*Ecore_Data_Cb)(void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a function to be called by ecore_fork_reset()
|
||||||
|
*
|
||||||
|
* This queues @p func to be called (and passed @p data as its argument) when
|
||||||
|
* ecore_fork_reset() is called. This allows other libraries and subsystems
|
||||||
|
* to also reset their internal state after a fork.
|
||||||
|
*
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_fork_reset_callback_add(Ecore_Cb func, const void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes the callback specified
|
||||||
|
*
|
||||||
|
* This deletes the callback added by ecore_fork_reset_callback_add() using
|
||||||
|
* the function and data pointer to specify which to remove.
|
||||||
|
*
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
EAPI Eina_Bool ecore_fork_reset_callback_del(Ecore_Cb func, const void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the ecore internal state after a fork
|
||||||
|
*
|
||||||
|
* Ecore maintains internal data that can be affected by the fork() system call
|
||||||
|
* which creates a duplicate of the current process. This also duplicates
|
||||||
|
* file descriptors which is problematic in that these file descriptors still
|
||||||
|
* point to their original sources. This function makes ecore reset internal
|
||||||
|
* state (e.g. pipes used for signalling between threads) so they function
|
||||||
|
* correctly afterwards.
|
||||||
|
*
|
||||||
|
* It is highly suggested that you call this function after any fork()
|
||||||
|
* system call inside the child process if you intend to use ecore features
|
||||||
|
* after this point and not call any exec() family functions. Not doing so
|
||||||
|
* will cause possible misbehaviour.
|
||||||
|
*
|
||||||
|
* @since 1.7
|
||||||
|
*/
|
||||||
|
EAPI void ecore_fork_reset(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Call callback asynchronously in the main loop.
|
* @brief Call callback asynchronously in the main loop.
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
|
|
|
@ -305,9 +305,60 @@ unlock:
|
||||||
return _ecore_init_count;
|
return _ecore_init_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct _Ecore_Fork_Cb
|
||||||
|
{
|
||||||
|
Ecore_Cb func;
|
||||||
|
void *data;
|
||||||
|
Eina_Bool delete_me : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _Ecore_Fork_Cb Ecore_Fork_Cb;
|
||||||
|
|
||||||
|
static int fork_cbs_walking = 0;
|
||||||
|
static Eina_List *fork_cbs = NULL;
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_fork_reset_callback_add(Ecore_Cb func, const void *data)
|
||||||
|
{
|
||||||
|
Ecore_Fork_Cb *fcb;
|
||||||
|
|
||||||
|
fcb = calloc(1, sizeof(Ecore_Fork_Cb));
|
||||||
|
if (!fcb) return EINA_FALSE;
|
||||||
|
fcb->func = func;
|
||||||
|
fcb->data = (void *)data;
|
||||||
|
fork_cbs = eina_list_append(fork_cbs, fcb);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Bool
|
||||||
|
ecore_fork_reset_callback_del(Ecore_Cb func, const void *data)
|
||||||
|
{
|
||||||
|
Eina_List *l;
|
||||||
|
Ecore_Fork_Cb *fcb;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH(fork_cbs, l, fcb)
|
||||||
|
{
|
||||||
|
if ((fcb->func == func) && (fcb->data == data))
|
||||||
|
{
|
||||||
|
if (!fork_cbs_walking)
|
||||||
|
{
|
||||||
|
fork_cbs = eina_list_remove_list(fork_cbs, l);
|
||||||
|
free(fcb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fcb->delete_me = EINA_TRUE;
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
ecore_fork_reset(void)
|
ecore_fork_reset(void)
|
||||||
{
|
{
|
||||||
|
Eina_List *l, *ln;
|
||||||
|
Ecore_Fork_Cb *fcb;
|
||||||
|
|
||||||
eina_lock_take(&_thread_safety);
|
eina_lock_take(&_thread_safety);
|
||||||
|
|
||||||
ecore_pipe_del(_thread_call);
|
ecore_pipe_del(_thread_call);
|
||||||
|
@ -316,6 +367,24 @@ ecore_fork_reset(void)
|
||||||
if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int));
|
if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int));
|
||||||
|
|
||||||
eina_lock_release(&_thread_safety);
|
eina_lock_release(&_thread_safety);
|
||||||
|
|
||||||
|
// should this be done withing the eina lock stuff?
|
||||||
|
|
||||||
|
fork_cbs_walking++;
|
||||||
|
EINA_LIST_FOREACH(fork_cbs, l, fcb)
|
||||||
|
{
|
||||||
|
fcb->func(fcb->data);
|
||||||
|
}
|
||||||
|
fork_cbs_walking--;
|
||||||
|
|
||||||
|
EINA_LIST_FOREACH_SAFE(fork_cbs, l, ln, fcb)
|
||||||
|
{
|
||||||
|
if (fcb->delete_me)
|
||||||
|
{
|
||||||
|
fork_cbs = eina_list_remove_list(fork_cbs, l);
|
||||||
|
free(fcb);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -218,6 +218,21 @@ ecore_evas_engine_type_supported_get(Ecore_Evas_Engine_Type engine)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_evas_fork_cb(void *data __UNUSED__)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (_ecore_evas_async_events_fd)
|
||||||
|
ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
|
||||||
|
fd = evas_async_events_fd_get();
|
||||||
|
if (fd >= 0)
|
||||||
|
_ecore_evas_async_events_fd =
|
||||||
|
ecore_main_fd_handler_add(fd, ECORE_FD_READ,
|
||||||
|
_ecore_evas_async_events_fd_handler, NULL,
|
||||||
|
NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
ecore_evas_init(void)
|
ecore_evas_init(void)
|
||||||
{
|
{
|
||||||
|
@ -240,12 +255,13 @@ ecore_evas_init(void)
|
||||||
goto shutdown_ecore;
|
goto shutdown_ecore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL);
|
||||||
fd = evas_async_events_fd_get();
|
fd = evas_async_events_fd_get();
|
||||||
if (fd > 0)
|
if (fd >= 0)
|
||||||
_ecore_evas_async_events_fd = ecore_main_fd_handler_add(fd,
|
_ecore_evas_async_events_fd =
|
||||||
ECORE_FD_READ,
|
ecore_main_fd_handler_add(fd, ECORE_FD_READ,
|
||||||
_ecore_evas_async_events_fd_handler, NULL,
|
_ecore_evas_async_events_fd_handler, NULL,
|
||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
|
|
||||||
ecore_evas_idle_enterer =
|
ecore_evas_idle_enterer =
|
||||||
ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
|
ecore_idle_enterer_add(_ecore_evas_idle_enter, NULL);
|
||||||
|
@ -308,6 +324,8 @@ ecore_evas_shutdown(void)
|
||||||
|
|
||||||
if (_ecore_evas_async_events_fd)
|
if (_ecore_evas_async_events_fd)
|
||||||
ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
|
ecore_main_fd_handler_del(_ecore_evas_async_events_fd);
|
||||||
|
|
||||||
|
ecore_fork_reset_callback_del(_ecore_evas_fork_cb, NULL);
|
||||||
|
|
||||||
eina_log_domain_unregister(_ecore_evas_log_dom);
|
eina_log_domain_unregister(_ecore_evas_log_dom);
|
||||||
_ecore_evas_log_dom = -1;
|
_ecore_evas_log_dom = -1;
|
||||||
|
|
Loading…
Reference in New Issue