#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
+#include <math.h>
+
+#ifdef HAVE_ISFINITE
+# define ECORE_FINITE(t) isfinite(t)
+#else
+# ifdef _MSC_VER
+# define ECORE_FINITE(t) _finite(t)
+# else
+# define ECORE_FINITE(t) finite(t)
+# endif
+#endif
+
+#define FIX_HZ 1
+
+#ifdef FIX_HZ
+# ifndef _MSC_VER
+# include <sys/param.h>
+# endif
+# ifndef HZ
+# define HZ 100
+# endif
+#endif
#ifdef HAVE_EVIL
# include <Evil.h>
int handling;
size_t already_read;
void *passed_data;
+ int message;
Eina_Bool delete_me : 1;
};
}
/**
+ * @brief Wait from another thread on the read side of a pipe.
+ *
+ * @param p The pipe to watch on.
+ * @param message_count The minimal number of message to wait before exiting.
+ * @param wait The amount of time in second to wait before exiting.
+ * @return the number of message catched during that wait call.
+ *
+ * Negative value for @p wait means infite wait.
+ */
+EAPI int
+ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait)
+{
+ struct timeval tv, *t;
+ fd_set rset;
+ double end = 0.0;
+ double timeout;
+ int ret;
+ int total = 0;
+
+ if (p->fd_read == PIPE_FD_INVALID)
+ return -1;
+
+ FD_ZERO(&rset);
+ FD_SET(p->fd_read, &rset);
+
+ if (wait >= 0.0)
+ end = ecore_time_get() + wait;
+ timeout = wait;
+
+ while (message_count > 0 && (timeout > 0.0 || wait <= 0.0))
+ {
+ if (wait >= 0.0)
+ {
+ /* finite() tests for NaN, too big, too small, and infinity. */
+ if ((!ECORE_FINITE(timeout)) || (timeout == 0.0))
+ {
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ }
+ else if (timeout > 0.0)
+ {
+ int sec, usec;
+#ifdef FIX_HZ
+ timeout += (0.5 / HZ);
+ 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;
+ }
+ t = &tv;
+ }
+ else
+ {
+ t = NULL;
+ }
+
+ ret = main_loop_select(p->fd_read + 1, &rset, NULL, NULL, t);
+
+ if (ret > 0)
+ {
+ _ecore_pipe_read(p, NULL);
+ message_count -= p->message;
+ total += p->message;
+ p->message = 0;
+ }
+ else if (ret == 0)
+ {
+ break;
+ }
+ else if (errno != EINTR)
+ {
+ close(p->fd_read);
+ p->fd_read = PIPE_FD_INVALID;
+ break;
+ }
+
+ if (wait >= 0.0)
+ timeout = end - ecore_time_get();
+ }
+
+ return total;
+}
+
+/**
* Close the write end of an Ecore_Pipe object created with ecore_pipe_add().
*
* @param p The Ecore_Pipe object.
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
+ p->message++;
}
else if (ret >= 0)
{