ecore: add ecore_pipe_wait.

SVN revision: 60135
This commit is contained in:
Cedric BAIL 2011-06-09 14:54:24 +00:00
parent a82325e41d
commit 707f908ba1
5 changed files with 120 additions and 2 deletions

View File

@ -210,3 +210,7 @@
* Add ecore_pipe_freeze/thaw to suspend and restart watching the pipe
inside the main loop.
2011-06-09 Cedric Bail
* Add ecore_pipe_wait (should only called from outside of the main loop).

View File

@ -788,6 +788,7 @@ extern "C" {
EAPI void ecore_pipe_read_close(Ecore_Pipe *p);
EAPI void ecore_pipe_thaw(Ecore_Pipe *p);
EAPI void ecore_pipe_freeze(Ecore_Pipe *p);
EAPI int ecore_pipe_wait(Ecore_Pipe *p, int message_count, double wait);
/**
* @}

View File

@ -147,9 +147,9 @@ static Eina_Bool win32_handlers_delete_me = EINA_FALSE;
#endif
#ifdef _WIN32
static Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
Ecore_Select_Function main_loop_select = _ecore_main_win32_select;
#else
static Ecore_Select_Function main_loop_select = select;
Ecore_Select_Function main_loop_select = select;
#endif
#ifndef USE_G_MAIN_LOOP

View File

@ -5,6 +5,28 @@
#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>
@ -60,6 +82,7 @@ struct _Ecore_Pipe
int handling;
size_t already_read;
void *passed_data;
int message;
Eina_Bool delete_me : 1;
};
@ -413,6 +436,94 @@ ecore_pipe_thaw(Ecore_Pipe *p)
}
}
/**
* @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().
*
@ -642,6 +753,7 @@ _ecore_pipe_read(void *data, Ecore_Fd_Handler *fd_handler __UNUSED__)
p->passed_data = NULL;
p->already_read = 0;
p->len = 0;
p->message++;
}
else if (ret >= 0)
{

View File

@ -198,5 +198,6 @@ void _ecore_main_loop_shutdown(void);
extern int _ecore_fps_debug;
extern double _ecore_time_loop_time;
extern Eina_Bool _ecore_glib_always_integrate;
extern Ecore_Select_Function main_loop_select;
#endif