Hello,
Here's a patch for handling EBADF (Bad file descriptor) error after select()
(following the thread "random abort caused by ecore").
It uses fcntl() for finding which fd raises EBADF. I tested the patch with
the attached program (somehow dirty but maybe shows the patch works).
Please mail me with any suggestions.
--
André Dieb Martins
Embedded Systems and Pervasive Computing Lab (Embedded)
Electrical Engineering Department (DEE)
Center of Electrical Engineering and Informatics (CEEI)
Federal University of Campina Grande (UFCG)
Blog: http://genuinepulse.blogspot.com/
Mail: dieb at embedded.ufcg.edu.br, andre.dieb at gmail.com
Index: src/lib/ecore/ecore_main.c
===================================================================
--- src/lib/ecore/ecore_main.c (revision 39915)
+++ src/lib/ecore/ecore_main.c (working copy)
@@ -18,6 +18,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
#define FIX_HZ 1
@@ -33,6 +34,7 @@
static int _ecore_main_select(double timeout);
static void _ecore_main_fd_handlers_cleanup(void);
+static void _ecore_main_fd_handlers_bads_rem(void);
static void _ecore_main_fd_handlers_call(void);
static int _ecore_main_fd_handlers_buf_call(void);
static void _ecore_main_loop_iterate_internal(int once_only);
@@ -354,11 +356,14 @@
}
}
if (_ecore_signal_count_get()) return -1;
+
ret = select(max_fd + 1, &rfds, &wfds, &exfds, t);
_ecore_loop_time = ecore_time_get();
if (ret < 0)
{
if (errno == EINTR) return -1;
+ else if (errno == EBADF)
+ _ecore_main_fd_handlers_bads_rem();
}
if (ret > 0)
{
@@ -379,6 +384,45 @@
}
static void
+_ecore_main_fd_handlers_bads_rem(void)
+{
+ fprintf(stderr, "Removing bad fds\n");
+ Ecore_Fd_Handler *fdh;
+ Eina_Inlist *l;
+
+ for (l = EINA_INLIST_GET(fd_handlers); l; )
+ {
+ fdh = (Ecore_Fd_Handler *) l;
+ l = l->next;
+ errno = 0;
+
+ if ((fcntl(fdh->fd, F_GETFD) < 0) && (errno == EBADF))
+ {
+ fprintf(stderr, "Found bad fd at index %d\n", fdh->fd);
+ if (fdh->flags & ECORE_FD_ERROR)
+ {
+ fprintf(stderr, "Fd set for error! calling user\n");
+ if (!fdh->func(fdh->data, fdh))
+ {
+ fprintf(stderr, "Fd function err returned 0, remove it\n");
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ _ecore_main_fd_handlers_cleanup();
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Problematic fd found at %d! setting it for delete\n", fdh->fd);
+ fdh->delete_me = 1;
+ fd_handlers_delete_me = 1;
+ _ecore_main_fd_handlers_cleanup();
+ }
+ }
+
+ }
+}
+
+static void
_ecore_main_fd_handlers_cleanup(void)
{
Ecore_Fd_Handler *fdh;
@@ -392,6 +436,7 @@
l = l->next;
if (fdh->delete_me)
{
+ fprintf(stderr, "Removing fd %d\n", fdh->fd);
fd_handlers = (Ecore_Fd_Handler *) eina_inlist_remove(EINA_INLIST_GET(fd_handlers),
EINA_INLIST_GET(fdh));
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_NONE);
#include <Ecore.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
int myfunc(void *data, Ecore_Fd_Handler *fdh) {
char *d;
d = (char *) data;
fprintf(stderr, "Myfunc! %s\n", d);
return 0;
}
int main(void) {
int fd[2];
ecore_init();
pipe(fd);
ecore_main_fd_handler_add(fd[0], ECORE_FD_READ, myfunc, "hi", NULL, NULL);
ecore_main_fd_handler_add(fd[1], ECORE_FD_WRITE, myfunc, "hello", NULL, NULL);
write(fd[1], "hello", strlen("hello")+1);
close(fd[1]);
close(fd[0]);
ecore_main_loop_begin();
return 0;
}
------------------------------------------------------------------------------
This SF.net email is sponsored by:
High Quality Requirements in a Collaborative Environment.
Download a free trial of Rational Requirements Composer Now!
http://p.sf.net/sfu/www-ibm-com
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel