Hi
While working on suspend/resume on my embedded system I ran into to the
race problem between select and signals. See this link for a description
of the problem:
http://www.xs4all.nl/~evbergen/unix-signals.html
The problem is that the following code in ecore_main_select is not an
atomic operation and could end up in select waiting forever even though
there is a signal to be served and put in the event queue:
if (_ecore_signal_count_get()) return -1;
ret = select(max_fd + 1, &rfds, &wfds, &exfds, t);
My proposed solution (see attached patch) is something similar to that
described in above link, namely to create a pipe to flag a signal
arrival to select. NOTE: the attached patch currently only handles
sigusr1 and sigusr2 and has almost no error checking.
As far as I can tell, the attached patch still have a race around
sig_count and sigXXX_count. I thought about adding the signal number to
the signal pipe to avoid this race, but that solution could result in
pipe buffer overflow and then signals would get lost.
Before I continue working on this patch, I really like your comments and
suggestions.
Thanks
-- Lars Munch
Index: src/lib/ecore/ecore_signal.c
===================================================================
RCS file: /var/cvs/e/e17/libs/ecore/src/lib/ecore/ecore_signal.c,v
retrieving revision 1.35
diff -u -r1.35 ecore_signal.c
--- src/lib/ecore/ecore_signal.c 26 Aug 2007 11:17:21 -0000 1.35
+++ src/lib/ecore/ecore_signal.c 23 Jan 2008 15:53:28 -0000
@@ -60,6 +60,9 @@
static volatile siginfo_t *sigrt_info = NULL;
#endif
+static int pipe_fd[2];
+static Ecore_Fd_Handler *pipe_handler;
+
void
_ecore_signal_shutdown(void)
{
@@ -110,13 +113,52 @@
#endif
}
+static void
+_ecore_signal_pipe_fd_flag()
+{
+ int count;
+ char f = 1;
+
+ /* Empty signal pipe completely */
+ for(count = 0; read(pipe_fd[0], &f, sizeof(f)) > 0; count++) ;
+
+ /* Put one flag into signal pipe */
+ write(pipe_fd[1], &f, sizeof(f));
+}
+
+static int
+_ecore_signal_pipe_fb_callback(void *data, Ecore_Fd_Handler *fdh)
+{
+ int count;
+ char f;
+
+ /* Empty signal pipe completely */
+ for(count = 0; read(fdh->fd, &f, sizeof(f)) > 0; count++) ;
+
+ if(count)
+ _ecore_signal_call();
+
+ return 1;
+}
+
void
_ecore_signal_init(void)
{
+ int ret;
#ifdef SIGRTMIN
int i, num = SIGRTMAX - SIGRTMIN;
#endif
+ ret = pipe(pipe_fd);
+ assert(!ret);
+
+ fcntl(pipe_fd[0], F_SETFL, O_NONBLOCK);
+ fcntl(pipe_fd[1], F_SETFL, O_NONBLOCK);
+
+ pipe_handler = ecore_main_fd_handler_add(pipe_fd[0], ECORE_FD_READ,
+ _ecore_signal_pipe_fb_callback,
+ NULL, NULL, NULL);
+
_ecore_signal_callback_set(SIGPIPE, _ecore_signal_callback_ignore);
_ecore_signal_callback_set(SIGALRM, _ecore_signal_callback_ignore);
_ecore_signal_callback_set(SIGCHLD, _ecore_signal_callback_sigchld);
@@ -401,6 +443,8 @@
else
sigusr1_info.si_signo = 0;
+ _ecore_signal_pipe_fd_flag();
+
sigusr1_count++;
sig_count++;
}
@@ -413,6 +457,8 @@
else
sigusr2_info.si_signo = 0;
+ _ecore_signal_pipe_fd_flag();
+
sigusr2_count++;
sig_count++;
}
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel