{
EINA_INLIST;
ECORE_MAGIC;
+ Ecore_Fd_Handler *next_ready;
int fd;
Ecore_Fd_Handler_Flags flags;
Ecore_Fd_Cb func;
static Eina_List *fd_handlers_with_buffer = NULL;
static Eina_List *fd_handlers_to_delete = NULL;
-static Eina_List *fd_handlers_to_call = NULL;
-static Eina_List *fd_handlers_to_call_current;
-static Eina_List *fd_handlers_to_call_current_next;
+/* single linked list of ready fdhs, terminated by loop to self */
+static Ecore_Fd_Handler *fd_handlers_to_call;
+static Ecore_Fd_Handler *fd_handlers_to_call_current;
#ifdef _WIN32
static Ecore_Win32_Handler *win32_handlers = NULL;
#endif
}
+static inline void
+_ecore_try_add_to_call_list(Ecore_Fd_Handler *fdh)
+{
+ /* check if this fdh is already in the list */
+ if (fdh->next_ready)
+ return;
+ if (fdh->read_active || fdh->write_active || fdh->error_active)
+ {
+ /*
+ * make sure next_ready is non-null by pointing to ourselves
+ * use that to indicate this fdh is in the ready list
+ * insert at the head of the list to avoid trouble
+ */
+ fdh->next_ready = fd_handlers_to_call ? fd_handlers_to_call : fdh;
+ fd_handlers_to_call = fdh;
+ }
+}
+
#ifdef HAVE_EPOLL
static inline int
_ecore_get_epoll_fd(void)
for (i = 0; i < ret; i++)
{
Ecore_Fd_Handler *fdh;
- Eina_Bool pst, st;
fdh = ev[i].data.ptr;
if (!ECORE_MAGIC_CHECK(fdh, ECORE_MAGIC_FD_HANDLER))
ERR("deleted fd in epoll");
continue;
}
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((ev[i].events & EPOLLIN) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((ev[i].events & EPOLLOUT) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((ev[i].events & EPOLLERR) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+
+ if (ev[i].events & EPOLLIN)
+ fdh->read_active = EINA_TRUE;
+ if (ev[i].events & EPOLLOUT)
+ fdh->write_active = EINA_TRUE;
+ if (ev[i].events & EPOLLERR)
+ fdh->error_active = EINA_TRUE;
+
+ _ecore_try_add_to_call_list(fdh);
}
return ret;
static inline int _ecore_main_fdh_poll_mark_active(void)
{
Ecore_Fd_Handler *fdh;
- Eina_Bool pst, st;
int ret = 0;
/* call the prepare callback for all handlers */
if (fdh->delete_me)
continue;
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((fdh->gfd.revents & G_IO_IN) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((fdh->gfd.revents & G_IO_OUT) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((fdh->gfd.revents & G_IO_ERR) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+ if (fdh->gfd.revents & G_IO_IN)
+ fdh->read_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_OUT)
+ fdh->write_active = EINA_TRUE;
+ if (fdh->gfd.revents & G_IO_ERR)
+ fdh->error_active = EINA_TRUE;
+
+ _ecore_try_add_to_call_list(fdh);
+
if (fdh->gfd.revents & (G_IO_IN|G_IO_OUT|G_IO_ERR)) ret++;
}
fdh = calloc(1, sizeof(Ecore_Fd_Handler));
if (!fdh) return NULL;
ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER);
+ fdh->next_ready = NULL;
fdh->fd = fd;
fdh->flags = flags;
if (_ecore_main_fdh_poll_add(fdh) < 0)
fd_handlers_with_prep = eina_list_free(fd_handlers_with_prep);
if (fd_handlers_to_delete)
fd_handlers_to_delete = eina_list_free(fd_handlers_to_delete);
- if (fd_handlers_to_call)
- fd_handlers_to_call = eina_list_free(fd_handlers_to_call);
+ fd_handlers_to_call = NULL;
fd_handlers_to_call_current = NULL;
fd_handlers_to_delete = NULL;
fd_handler_current = NULL;
{
if (!fdh->delete_me)
{
- Eina_Bool pst, st;
- pst = st = fdh->read_active | fdh->write_active | fdh->error_active;
- if ((FD_ISSET(fdh->fd, &rfds)) && (!fdh->read_active))
- st = fdh->read_active = EINA_TRUE;
- if ((FD_ISSET(fdh->fd, &wfds)) && (!fdh->write_active))
- st = fdh->write_active = EINA_TRUE;
- if ((FD_ISSET(fdh->fd, &exfds)) && (!fdh->error_active))
- st = fdh->error_active = EINA_TRUE;
- if (pst != st)
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
+ if (FD_ISSET(fdh->fd, &rfds))
+ fdh->read_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, &wfds))
+ fdh->write_active = EINA_TRUE;
+ if (FD_ISSET(fdh->fd, &exfds))
+ fdh->error_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
}
}
#endif /* HAVE_EPOLL */
static void
_ecore_main_fd_handlers_call(void)
{
+ /* grab a new list */
if (!fd_handlers_to_call_current)
{
- /* regular main loop, start from head */
fd_handlers_to_call_current = fd_handlers_to_call;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
- }
- else
- {
- /* recursive main loop, continue from where we were */
- fd_handlers_to_call_current = fd_handlers_to_call_current_next;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current);
+ fd_handlers_to_call = NULL;
}
while (fd_handlers_to_call_current)
{
- Ecore_Fd_Handler *fdh = fd_handlers_to_call_current->data;
+ Ecore_Fd_Handler *fdh = fd_handlers_to_call_current;
if (!fdh->delete_me)
{
}
}
- fd_handlers_to_call = eina_list_remove_list(fd_handlers_to_call, fd_handlers_to_call_current);
- fd_handlers_to_call_current = fd_handlers_to_call_current_next;
- fd_handlers_to_call_current_next = eina_list_next(fd_handlers_to_call_current_next);
+ /* stop when we point to ourselves */
+ if (fdh->next_ready == fdh)
+ {
+ fdh->next_ready = NULL;
+ fd_handlers_to_call_current = NULL;
+ break;
+ }
+
+ fd_handlers_to_call_current = fdh->next_ready;
+ fdh->next_ready = NULL;
}
}
if (fdh->buf_func(fdh->buf_data, fdh))
{
ret |= fdh->func(fdh->data, fdh);
- if (!fdh->read_active)
- {
- fdh->read_active = EINA_TRUE;
- if ((!fdh->write_active) && (!fdh->error_active))
- fd_handlers_to_call = eina_list_append(fd_handlers_to_call, fdh);
- }
+ fdh->read_active = EINA_TRUE;
+ _ecore_try_add_to_call_list(fdh);
}
fdh->references--;
}