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.
|
||||
* 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_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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @since 1.1.0
|
||||
|
|
|
@ -305,9 +305,60 @@ unlock:
|
|||
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
|
||||
ecore_fork_reset(void)
|
||||
{
|
||||
Eina_List *l, *ln;
|
||||
Ecore_Fork_Cb *fcb;
|
||||
|
||||
eina_lock_take(&_thread_safety);
|
||||
|
||||
ecore_pipe_del(_thread_call);
|
||||
|
@ -316,6 +367,24 @@ ecore_fork_reset(void)
|
|||
if (_thread_cb) ecore_pipe_write(_thread_call, &wakeup, sizeof (int));
|
||||
|
||||
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
|
||||
ecore_evas_init(void)
|
||||
{
|
||||
|
@ -240,10 +255,11 @@ ecore_evas_init(void)
|
|||
goto shutdown_ecore;
|
||||
}
|
||||
|
||||
ecore_fork_reset_callback_add(_ecore_evas_fork_cb, NULL);
|
||||
fd = evas_async_events_fd_get();
|
||||
if (fd > 0)
|
||||
_ecore_evas_async_events_fd = ecore_main_fd_handler_add(fd,
|
||||
ECORE_FD_READ,
|
||||
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);
|
||||
|
||||
|
@ -309,6 +325,8 @@ ecore_evas_shutdown(void)
|
|||
if (_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);
|
||||
_ecore_evas_log_dom = -1;
|
||||
ecore_shutdown();
|
||||
|
|
Loading…
Reference in New Issue