#else
+# include <sys/epoll.h>
+# include <sys/timerfd.h>
# include <unistd.h>
# include <fcntl.h>
unsigned int already_read;
void *passed_data;
int message;
+#ifndef _WIN32
+ int pollfd;
+ int timerfd;
+#endif
Eina_Bool delete_me : 1;
};
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Pipe);
if (!write_survive_fork)
_ecore_fd_close_on_exec(fd_write);
+#ifndef _WIN32
+ struct epoll_event pollev = { 0 };
+ p->pollfd = epoll_create(1);
+ p->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
+ _ecore_fd_close_on_exec(p->timerfd);
+
+ pollev.data.ptr = p->fd_read;
+ pollev.events = EPOLLIN;
+ epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->fd_read, &pollev);
+
+ pollev.data.ptr = p->timerfd;
+ pollev.events = EPOLLIN;
+ epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->timerfd, &pollev);
+#endif
+
if (fcntl(p->fd_read, F_SETFL, O_NONBLOCK) < 0) ERR("can't set pipe to NONBLOCK");
p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
ECORE_FD_READ,
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del");
return NULL;
}
+#ifndef _WIN32
+ epoll_ctl(p->pollfd, EPOLL_CTL_DEL, p->fd_read, NULL);
+ epoll_ctl(p->pollfd, EPOLL_CTL_DEL, p->timerfd, NULL);
+ if (p->timerfd >= 0) close(p->timerfd);
+ if (p->pollfd >= 0) close(p->pollfd);
+#endif
p->delete_me = EINA_TRUE;
if (p->handling > 0) return (void *)p->data;
if (p->fd_handler) _ecore_main_fd_handler_del(p->fd_handler);
return data;
}
+#ifdef _WIN32
int
_ecore_pipe_wait(Ecore_Pipe *p,
int message_count,
int sec, usec;
#ifdef FIX_HZ
timeout += (0.5 / HZ);
+#endif
sec = (int)timeout;
usec = (int)((timeout - (double)sec) * 1000000);
-#else
- sec = (int)timeout;
- usec = (int)((timeout - (double)sec) * 1000000);
-#endif
tv.tv_sec = sec;
tv.tv_usec = usec;
}
return total;
}
+#else
+int
+_ecore_pipe_wait(Ecore_Pipe *p,
+ int message_count,
+ double wait)
+{
+ int64_t timerfdbuf;
+ struct epoll_event pollincoming[2];
+ double end = 0.0;
+ double timeout;
+ int ret;
+ int total = 0;
+ int time_exit=-1;
+ struct itimerspec tspec_new;
+ struct itimerspec tspec_old;
+
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
+ if (p->fd_read == PIPE_FD_INVALID)
+ return -1;
+
+ if (wait >= 0.0)
+ end = ecore_time_get() + wait;
+ timeout = wait;
+
+ while (message_count > 0 && (timeout > 0.0 || wait <= 0.0))
+ {
+ time_exit = -1;
+ if (wait >= 0.0)
+ {
+ /* finite() tests for NaN, too big, too small, and infinity. */
+ if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
+ {
+ tspec_new.it_value.tv_sec = 0;
+ tspec_new.it_value.tv_nsec = 0;
+ tspec_new.it_interval.tv_sec = 0;
+ tspec_new.it_interval.tv_nsec = 0;
+ time_exit = 0;
+ }
+ else if (timeout > 0.0)
+ {
+ int sec, usec;
+#ifdef FIX_HZ
+ timeout += (0.5 / HZ);
+#endif
+ sec = (int)timeout;
+ usec = (int)((timeout - (double)sec) * 1000000000);
+ tspec_new.it_value.tv_sec = sec;
+ tspec_new.it_value.tv_nsec = (int)(usec) % 1000000000;
+ tspec_new.it_interval.tv_sec = 0;
+ tspec_new.it_interval.tv_nsec = 0;
+
+ }
+ timerfd_settime(p->timerfd, 0, &tspec_new, &tspec_old);
+ }
+
+ ret = epoll_wait(p->pollfd, pollincoming, 2, time_exit);
+
+ if (ret > 0)
+ {
+ Eina_Bool fd_read_found = EINA_FALSE;
+ Eina_Bool fd_timer_found = EINA_FALSE;
+
+ for(int i = 0; i < ret;i++)
+ {
+ if ((&p->fd_read == pollincoming[i].data.ptr))
+ fd_read_found = EINA_TRUE;
+
+ if ((&p->timerfd == pollincoming[i].data.ptr))
+ fd_timer_found = EINA_TRUE;
+ }
+
+ if (fd_read_found)
+ {
+ _ecore_pipe_read(p, NULL);
+ message_count -= p->message;
+ total += p->message;
+ p->message = 0;
+ }
+
+ if (fd_timer_found)
+ {
+ pipe_read(p->timerfd, &timerfdbuf, sizeof(timerfdbuf));
+ break;
+ }
+ }
+ else if (ret == 0)
+ {
+ break;
+ }
+ else if (errno != EINTR)
+ {
+ if (p->fd_read != PIPE_FD_INVALID)
+ {
+ close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ }
+ break;
+ }
+
+ if (wait >= 0.0)
+ timeout = end - ecore_time_get();
+ }
+ return total;
+}
+
+#endif
static void
_ecore_pipe_unhandle(Ecore_Pipe *p)
{