2008-11-11 23:54:25 -08:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
2009-01-31 10:33:39 -08:00
|
|
|
#include <stdio.h>
|
2008-11-11 23:54:25 -08:00
|
|
|
#include <errno.h>
|
2011-06-09 07:54:24 -07:00
|
|
|
#include <math.h>
|
|
|
|
|
2016-06-13 12:44:10 -07:00
|
|
|
#ifdef HAVE_IEEEFP_H
|
|
|
|
# include <ieeefp.h> /* for Solaris */
|
2012-12-02 23:30:33 -08:00
|
|
|
#endif
|
|
|
|
|
2011-06-09 07:54:24 -07:00
|
|
|
#ifdef HAVE_ISFINITE
|
2011-10-20 22:40:39 -07:00
|
|
|
# define ECORE_FINITE(t) isfinite(t)
|
2011-06-09 07:54:24 -07:00
|
|
|
#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
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
#ifdef HAVE_EVIL
|
|
|
|
# include <Evil.h>
|
|
|
|
#endif
|
|
|
|
|
2011-11-05 10:49:49 -07:00
|
|
|
#ifdef HAVE_ESCAPE
|
|
|
|
# include <Escape.h>
|
|
|
|
#endif
|
|
|
|
|
2012-03-07 08:14:47 -08:00
|
|
|
#ifdef HAVE_EXOTIC
|
|
|
|
# include <Exotic.h>
|
|
|
|
#endif
|
|
|
|
|
2008-11-11 23:54:25 -08:00
|
|
|
/*
|
|
|
|
* On Windows, pipe() is implemented with sockets.
|
|
|
|
* Contrary to Linux, Windows uses different functions
|
|
|
|
* for sockets and fd's: write() is for fd's and send
|
|
|
|
* is for sockets. So I need to put some win32 code
|
|
|
|
* here. I can't think of a solution where the win32
|
|
|
|
* code is in Evil and not here.
|
|
|
|
*/
|
|
|
|
|
2013-03-18 15:38:01 -07:00
|
|
|
#define PIPE_FD_INVALID -1
|
|
|
|
|
2008-11-11 23:54:25 -08:00
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
# include <winsock2.h>
|
|
|
|
|
|
|
|
# define pipe_write(fd, buffer, size) send((fd), (char *)(buffer), size, 0)
|
|
|
|
# define pipe_read(fd, buffer, size) recv((fd), (char *)(buffer), size, 0)
|
2009-05-29 07:32:57 -07:00
|
|
|
# define pipe_close(fd) closesocket(fd)
|
2011-10-20 22:40:39 -07:00
|
|
|
# define PIPE_FD_ERROR SOCKET_ERROR
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2017-04-17 00:55:34 -07:00
|
|
|
# ifdef HAVE_SYS_EPOLL_H
|
|
|
|
# include <sys/epoll.h>
|
|
|
|
# endif /* HAVE_SYS_EPOLL_H */
|
|
|
|
# ifdef HAVE_SYS_TIMERFD_H
|
|
|
|
# include <sys/timerfd.h>
|
|
|
|
# endif
|
2008-11-11 23:54:25 -08:00
|
|
|
# include <unistd.h>
|
|
|
|
# include <fcntl.h>
|
|
|
|
|
|
|
|
# define pipe_write(fd, buffer, size) write((fd), buffer, size)
|
|
|
|
# define pipe_read(fd, buffer, size) read((fd), buffer, size)
|
2009-05-29 07:32:57 -07:00
|
|
|
# define pipe_close(fd) close(fd)
|
2011-10-20 22:40:39 -07:00
|
|
|
# define PIPE_FD_ERROR -1
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
#endif /* ! _WIN32 */
|
|
|
|
|
2012-11-18 22:26:48 -08:00
|
|
|
#include "Ecore.h"
|
2012-02-24 03:20:25 -08:00
|
|
|
#include "ecore_private.h"
|
|
|
|
|
2012-11-18 22:26:48 -08:00
|
|
|
/* How of then we should retry to write to the pipe */
|
|
|
|
#define ECORE_PIPE_WRITE_RETRY 6
|
|
|
|
|
2011-12-11 00:29:35 -08:00
|
|
|
struct _Ecore_Pipe
|
|
|
|
{
|
|
|
|
ECORE_MAGIC;
|
|
|
|
int fd_read;
|
|
|
|
int fd_write;
|
|
|
|
Ecore_Fd_Handler *fd_handler;
|
|
|
|
const void *data;
|
|
|
|
Ecore_Pipe_Cb handler;
|
|
|
|
unsigned int len;
|
|
|
|
int handling;
|
2015-10-04 07:34:48 -07:00
|
|
|
unsigned int already_read;
|
2011-12-11 00:29:35 -08:00
|
|
|
void *passed_data;
|
|
|
|
int message;
|
2017-04-16 20:28:41 -07:00
|
|
|
#ifndef _WIN32
|
|
|
|
int pollfd;
|
|
|
|
int timerfd;
|
|
|
|
#endif
|
2011-12-11 00:29:35 -08:00
|
|
|
Eina_Bool delete_me : 1;
|
|
|
|
};
|
|
|
|
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Pipe);
|
2008-11-11 23:54:25 -08:00
|
|
|
|
2011-10-20 22:40:39 -07:00
|
|
|
static Eina_Bool _ecore_pipe_read(void *data,
|
|
|
|
Ecore_Fd_Handler *fd_handler);
|
2010-10-17 00:03:28 -07:00
|
|
|
|
2008-11-11 23:54:25 -08:00
|
|
|
EAPI Ecore_Pipe *
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_pipe_add(Ecore_Pipe_Cb handler,
|
|
|
|
const void *data)
|
2008-11-11 23:54:25 -08:00
|
|
|
{
|
|
|
|
Ecore_Pipe *p;
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
p = _ecore_pipe_add(handler, data);
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void *
|
|
|
|
ecore_pipe_del(Ecore_Pipe *p)
|
|
|
|
{
|
2012-12-24 01:35:56 -08:00
|
|
|
if (!p) return NULL;
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
2016-01-14 14:52:37 -08:00
|
|
|
return _ecore_pipe_del(p);
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
|
|
|
|
2009-04-22 18:38:55 -07:00
|
|
|
EAPI void
|
2009-04-23 00:08:50 -07:00
|
|
|
ecore_pipe_read_close(Ecore_Pipe *p)
|
2009-04-22 18:38:55 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2009-04-22 18:38:55 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close");
|
2016-01-14 14:52:37 -08:00
|
|
|
return ;
|
2009-04-22 18:38:55 -07:00
|
|
|
}
|
2010-10-12 17:37:12 -07:00
|
|
|
if (p->fd_handler)
|
|
|
|
{
|
2011-08-11 22:22:07 -07:00
|
|
|
_ecore_main_fd_handler_del(p->fd_handler);
|
2010-10-12 17:37:12 -07:00
|
|
|
p->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
if (p->fd_read != PIPE_FD_INVALID)
|
|
|
|
{
|
|
|
|
pipe_close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
}
|
2009-04-22 18:38:55 -07:00
|
|
|
}
|
|
|
|
|
2013-02-24 16:32:27 -08:00
|
|
|
EAPI int
|
|
|
|
ecore_pipe_read_fd(Ecore_Pipe *p)
|
|
|
|
{
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(PIPE_FD_INVALID);
|
|
|
|
return p->fd_read;
|
|
|
|
}
|
|
|
|
|
2011-05-30 09:52:19 -07:00
|
|
|
EAPI void
|
|
|
|
ecore_pipe_freeze(Ecore_Pipe *p)
|
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-05-30 09:52:19 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
2011-06-06 23:37:25 -07:00
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze");
|
2016-01-14 14:52:37 -08:00
|
|
|
return ;
|
2011-05-30 09:52:19 -07:00
|
|
|
}
|
|
|
|
if (p->fd_handler)
|
|
|
|
{
|
2011-08-11 22:22:07 -07:00
|
|
|
_ecore_main_fd_handler_del(p->fd_handler);
|
2011-05-30 09:52:19 -07:00
|
|
|
p->fd_handler = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2011-05-31 01:05:16 -07:00
|
|
|
ecore_pipe_thaw(Ecore_Pipe *p)
|
2011-05-30 09:52:19 -07:00
|
|
|
{
|
2012-03-29 01:52:25 -07:00
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN;
|
2011-05-30 09:52:19 -07:00
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
2011-06-06 23:37:25 -07:00
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw");
|
2016-01-14 14:52:37 -08:00
|
|
|
return ;
|
2011-05-30 09:52:19 -07:00
|
|
|
}
|
|
|
|
if (!p->fd_handler && p->fd_read != PIPE_FD_INVALID)
|
|
|
|
{
|
|
|
|
p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
|
|
|
|
ECORE_FD_READ,
|
|
|
|
_ecore_pipe_read,
|
|
|
|
p,
|
|
|
|
NULL, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-09 07:54:24 -07:00
|
|
|
EAPI int
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_pipe_wait(Ecore_Pipe *p,
|
|
|
|
int message_count,
|
|
|
|
double wait)
|
2011-06-09 07:54:24 -07:00
|
|
|
{
|
2016-01-14 14:52:37 -08:00
|
|
|
return _ecore_pipe_wait(p, message_count, wait);
|
2011-06-09 07:54:24 -07:00
|
|
|
}
|
|
|
|
|
2009-04-22 18:38:55 -07:00
|
|
|
EAPI void
|
2009-04-23 00:08:50 -07:00
|
|
|
ecore_pipe_write_close(Ecore_Pipe *p)
|
2009-04-22 18:38:55 -07:00
|
|
|
{
|
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close");
|
2016-01-14 14:52:37 -08:00
|
|
|
return ;
|
2009-04-22 18:38:55 -07:00
|
|
|
}
|
2010-10-12 17:37:12 -07:00
|
|
|
if (p->fd_write != PIPE_FD_INVALID)
|
|
|
|
{
|
|
|
|
pipe_close(p->fd_write);
|
|
|
|
p->fd_write = PIPE_FD_INVALID;
|
|
|
|
}
|
2009-04-22 18:38:55 -07:00
|
|
|
}
|
|
|
|
|
2013-02-24 16:32:27 -08:00
|
|
|
EAPI int
|
|
|
|
ecore_pipe_write_fd(Ecore_Pipe *p)
|
|
|
|
{
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(PIPE_FD_INVALID);
|
|
|
|
return p->fd_write;
|
|
|
|
}
|
|
|
|
|
2010-06-10 04:57:12 -07:00
|
|
|
EAPI Eina_Bool
|
2011-10-20 22:40:39 -07:00
|
|
|
ecore_pipe_write(Ecore_Pipe *p,
|
|
|
|
const void *buffer,
|
|
|
|
unsigned int nbytes)
|
2008-11-11 23:54:25 -08:00
|
|
|
{
|
|
|
|
ssize_t ret;
|
2011-10-20 22:40:39 -07:00
|
|
|
size_t already_written = 0;
|
|
|
|
int retry = ECORE_PIPE_WRITE_RETRY;
|
2012-11-06 02:49:05 -08:00
|
|
|
Eina_Bool ok = EINA_FALSE;
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write");
|
2012-11-06 02:49:05 -08:00
|
|
|
goto out;
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
2009-04-22 18:38:55 -07:00
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
if (p->delete_me) goto out;
|
2011-04-20 07:15:33 -07:00
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
if (p->fd_write == PIPE_FD_INVALID) goto out;
|
2009-04-22 18:38:55 -07:00
|
|
|
|
|
|
|
/* First write the len into the pipe */
|
2008-11-11 23:54:25 -08:00
|
|
|
do
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ret = pipe_write(p->fd_write, &nbytes, sizeof(nbytes));
|
|
|
|
if (ret == sizeof(nbytes))
|
|
|
|
{
|
|
|
|
retry = ECORE_PIPE_WRITE_RETRY;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (ret > 0)
|
|
|
|
{
|
|
|
|
/* XXX What should we do here? */
|
2011-10-20 22:40:39 -07:00
|
|
|
ERR("The length of the data was not written complete"
|
|
|
|
" to the pipe");
|
2012-11-06 02:49:05 -08:00
|
|
|
goto out;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
else if (ret == PIPE_FD_ERROR && errno == EPIPE)
|
|
|
|
{
|
|
|
|
pipe_close(p->fd_write);
|
|
|
|
p->fd_write = PIPE_FD_INVALID;
|
2012-11-06 02:49:05 -08:00
|
|
|
goto out;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
else if (ret == PIPE_FD_ERROR && errno == EINTR)
|
|
|
|
/* try it again */
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
2012-02-18 04:55:26 -08:00
|
|
|
ERR("An unhandled error (ret: %zd errno: %d)"
|
2010-09-29 23:09:20 -07:00
|
|
|
"occurred while writing to the pipe the length",
|
|
|
|
ret, errno);
|
|
|
|
}
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
|
|
|
while (retry--);
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
if (retry != ECORE_PIPE_WRITE_RETRY) goto out;
|
2008-11-11 23:54:25 -08:00
|
|
|
|
|
|
|
/* and now pass the data to the pipe */
|
|
|
|
do
|
|
|
|
{
|
2010-09-29 23:09:20 -07:00
|
|
|
ret = pipe_write(p->fd_write,
|
2009-08-12 17:27:53 -07:00
|
|
|
((unsigned char *)buffer) + already_written,
|
|
|
|
nbytes - already_written);
|
2011-04-20 07:15:33 -07:00
|
|
|
|
2010-09-29 23:09:20 -07:00
|
|
|
if (ret == (ssize_t)(nbytes - already_written))
|
2012-11-06 02:49:05 -08:00
|
|
|
{
|
|
|
|
ok = EINA_TRUE;
|
|
|
|
goto out;
|
|
|
|
}
|
2010-09-29 23:09:20 -07:00
|
|
|
else if (ret >= 0)
|
|
|
|
{
|
|
|
|
already_written -= ret;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (ret == PIPE_FD_ERROR && errno == EPIPE)
|
|
|
|
{
|
|
|
|
pipe_close(p->fd_write);
|
|
|
|
p->fd_write = PIPE_FD_INVALID;
|
2012-11-06 02:49:05 -08:00
|
|
|
goto out;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
else if (ret == PIPE_FD_ERROR && errno == EINTR)
|
|
|
|
/* try it again */
|
|
|
|
;
|
|
|
|
else
|
|
|
|
{
|
2012-02-18 04:55:26 -08:00
|
|
|
ERR("An unhandled error (ret: %zd errno: %d)"
|
2010-09-29 23:09:20 -07:00
|
|
|
"occurred while writing to the pipe the length",
|
|
|
|
ret, errno);
|
|
|
|
}
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
|
|
|
while (retry--);
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
out:
|
|
|
|
return ok;
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
|
|
|
|
2013-02-24 16:32:27 -08:00
|
|
|
EAPI Ecore_Pipe *
|
|
|
|
ecore_pipe_full_add(Ecore_Pipe_Cb handler,
|
|
|
|
const void *data,
|
|
|
|
int fd_read,
|
|
|
|
int fd_write,
|
|
|
|
Eina_Bool read_survive_fork,
|
2014-07-25 17:19:30 -07:00
|
|
|
Eina_Bool write_survive_fork)
|
2012-11-06 02:49:05 -08:00
|
|
|
{
|
|
|
|
Ecore_Pipe *p = NULL;
|
|
|
|
int fds[2];
|
|
|
|
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
|
|
|
|
if (!handler) return NULL;
|
|
|
|
|
|
|
|
p = ecore_pipe_calloc(1);
|
|
|
|
if (!p) return NULL;
|
|
|
|
|
2013-02-24 16:32:27 -08:00
|
|
|
if (fd_read == -1 &&
|
|
|
|
fd_write == -1)
|
2012-11-06 02:49:05 -08:00
|
|
|
{
|
2013-02-24 16:32:27 -08:00
|
|
|
if (pipe(fds))
|
|
|
|
{
|
|
|
|
ecore_pipe_mp_free(p);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
fd_read = fds[0];
|
|
|
|
fd_write = fds[1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fd_read = fd_read == -1 ? PIPE_FD_INVALID : fd_read;
|
|
|
|
fd_write = fd_write == -1 ? PIPE_FD_INVALID : fd_write;
|
2012-11-06 02:49:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
ECORE_MAGIC_SET(p, ECORE_MAGIC_PIPE);
|
2013-02-24 16:32:27 -08:00
|
|
|
p->fd_read = fd_read;
|
|
|
|
p->fd_write = fd_write;
|
2012-11-06 02:49:05 -08:00
|
|
|
p->handler = handler;
|
|
|
|
p->data = data;
|
|
|
|
|
2013-02-24 16:32:27 -08:00
|
|
|
if (!read_survive_fork)
|
2017-04-18 16:55:31 -07:00
|
|
|
eina_file_close_on_exec(fd_read, EINA_TRUE);
|
2013-02-24 16:32:27 -08:00
|
|
|
if (!write_survive_fork)
|
2017-04-18 16:55:31 -07:00
|
|
|
eina_file_close_on_exec(fd_write, EINA_TRUE);
|
2012-12-07 03:01:41 -08:00
|
|
|
|
2017-04-17 00:55:34 -07:00
|
|
|
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_SYS_TIMERFD_H)
|
2017-04-16 20:28:41 -07:00
|
|
|
struct epoll_event pollev = { 0 };
|
|
|
|
p->pollfd = epoll_create(1);
|
|
|
|
p->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
2017-04-18 16:55:31 -07:00
|
|
|
eina_file_close_on_exec(p->pollfd, EINA_TRUE);
|
2017-04-16 20:28:41 -07:00
|
|
|
|
2017-04-17 01:01:58 -07:00
|
|
|
pollev.data.ptr = (void *)(uintptr_t)(p->fd_read);
|
2017-04-16 20:28:41 -07:00
|
|
|
pollev.events = EPOLLIN;
|
|
|
|
epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->fd_read, &pollev);
|
|
|
|
|
2017-04-17 01:01:58 -07:00
|
|
|
pollev.data.ptr = (void *)(uintptr_t)(p->timerfd);
|
2017-04-16 20:28:41 -07:00
|
|
|
pollev.events = EPOLLIN;
|
|
|
|
epoll_ctl(p->pollfd, EPOLL_CTL_ADD, p->timerfd, &pollev);
|
|
|
|
#endif
|
|
|
|
|
2017-04-17 17:55:50 -07:00
|
|
|
if (fcntl(p->fd_read, F_SETFL, O_NONBLOCK) < 0)
|
|
|
|
ERR("can't set pipe to NONBLOCK");
|
2012-11-06 02:49:05 -08:00
|
|
|
p->fd_handler = ecore_main_fd_handler_add(p->fd_read,
|
|
|
|
ECORE_FD_READ,
|
|
|
|
_ecore_pipe_read,
|
|
|
|
p,
|
|
|
|
NULL, NULL);
|
|
|
|
|
2014-07-25 17:19:30 -07:00
|
|
|
return p;
|
2013-02-24 16:32:27 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Private functions */
|
|
|
|
Ecore_Pipe *
|
|
|
|
_ecore_pipe_add(Ecore_Pipe_Cb handler,
|
|
|
|
const void *data)
|
|
|
|
{
|
|
|
|
return ecore_pipe_full_add(handler, data,
|
|
|
|
-1, -1,
|
2014-07-25 17:19:30 -07:00
|
|
|
EINA_FALSE, EINA_FALSE);
|
2012-11-06 02:49:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
_ecore_pipe_del(Ecore_Pipe *p)
|
|
|
|
{
|
|
|
|
void *data = NULL;
|
|
|
|
|
|
|
|
if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE))
|
|
|
|
{
|
|
|
|
ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del");
|
|
|
|
return NULL;
|
|
|
|
}
|
2017-04-17 00:55:34 -07:00
|
|
|
#if defined(HAVE_SYS_EPOLL_H) && defined(HAVE_SYS_TIMERFD_H)
|
2017-04-16 20:28:41 -07:00
|
|
|
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);
|
2017-04-17 22:16:53 -07:00
|
|
|
p->timerfd = PIPE_FD_INVALID;
|
|
|
|
p->pollfd = PIPE_FD_INVALID;
|
2017-04-16 20:28:41 -07:00
|
|
|
#endif
|
2012-11-06 02:49:05 -08:00
|
|
|
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);
|
|
|
|
if (p->fd_read != PIPE_FD_INVALID) pipe_close(p->fd_read);
|
|
|
|
if (p->fd_write != PIPE_FD_INVALID) pipe_close(p->fd_write);
|
2016-07-11 06:02:45 -07:00
|
|
|
p->fd_handler = NULL;
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
p->fd_write = PIPE_FD_INVALID;
|
2012-11-06 02:49:05 -08:00
|
|
|
data = (void *)p->data;
|
|
|
|
ecore_pipe_mp_free(p);
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2017-04-17 22:16:53 -07:00
|
|
|
static void
|
|
|
|
_ecore_pipe_unhandle(Ecore_Pipe *p)
|
|
|
|
{
|
|
|
|
p->handling--;
|
|
|
|
if (p->delete_me)
|
|
|
|
{
|
|
|
|
_ecore_pipe_del(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-17 00:55:34 -07:00
|
|
|
#if ! defined(HAVE_SYS_EPOLL_H) || ! defined(HAVE_SYS_TIMERFD_H)
|
2012-11-06 02:49:05 -08:00
|
|
|
int
|
|
|
|
_ecore_pipe_wait(Ecore_Pipe *p,
|
|
|
|
int message_count,
|
|
|
|
double wait)
|
|
|
|
{
|
|
|
|
struct timeval tv, *t;
|
2015-08-27 00:58:10 -07:00
|
|
|
fd_set rset, wset, exset;
|
2012-11-06 02:49:05 -08:00
|
|
|
double end = 0.0;
|
|
|
|
double timeout;
|
|
|
|
int ret;
|
|
|
|
int total = 0;
|
|
|
|
|
|
|
|
EINA_MAIN_LOOP_CHECK_RETURN_VAL(-1);
|
|
|
|
if (p->fd_read == PIPE_FD_INVALID)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
FD_ZERO(&rset);
|
2015-08-27 00:58:10 -07:00
|
|
|
FD_ZERO(&wset);
|
|
|
|
FD_ZERO(&exset);
|
2012-11-06 02:49:05 -08:00
|
|
|
FD_SET(p->fd_read, &rset);
|
|
|
|
|
|
|
|
if (wait >= 0.0)
|
2015-05-05 03:28:14 -07:00
|
|
|
end = ecore_time_get() + wait;
|
2012-11-06 02:49:05 -08:00
|
|
|
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. */
|
2017-03-21 11:11:19 -07:00
|
|
|
if ((!ECORE_FINITE(timeout)) || (EINA_DBL_EQ(timeout, 0.0)))
|
2016-12-19 16:31:21 -08:00
|
|
|
{
|
|
|
|
tv.tv_sec = 0;
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
}
|
|
|
|
else if (timeout > 0.0)
|
|
|
|
{
|
|
|
|
int sec, usec;
|
2012-11-06 02:49:05 -08:00
|
|
|
#ifdef FIX_HZ
|
2016-12-19 16:31:21 -08:00
|
|
|
timeout += (0.5 / HZ);
|
2017-04-16 20:28:41 -07:00
|
|
|
#endif
|
2016-12-19 16:31:21 -08:00
|
|
|
sec = (int)timeout;
|
|
|
|
usec = (int)((timeout - (double)sec) * 1000000);
|
|
|
|
tv.tv_sec = sec;
|
|
|
|
tv.tv_usec = usec;
|
|
|
|
}
|
|
|
|
t = &tv;
|
2012-11-06 02:49:05 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
t = NULL;
|
|
|
|
}
|
|
|
|
|
2015-08-27 00:58:10 -07:00
|
|
|
ret = main_loop_select(p->fd_read + 1, &rset, &wset, &exset, t);
|
2012-11-06 02:49:05 -08:00
|
|
|
|
|
|
|
if (ret > 0)
|
|
|
|
{
|
2017-04-17 22:16:53 -07:00
|
|
|
p->handling++;
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_read(p, NULL);
|
|
|
|
message_count -= p->message;
|
|
|
|
total += p->message;
|
|
|
|
p->message = 0;
|
2017-04-17 22:16:53 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2012-11-06 02:49:05 -08:00
|
|
|
}
|
|
|
|
else if (ret == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (errno != EINTR)
|
|
|
|
{
|
2015-07-31 00:58:19 -07:00
|
|
|
if (p->fd_read != PIPE_FD_INVALID)
|
|
|
|
{
|
|
|
|
close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
}
|
2012-11-06 02:49:05 -08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wait >= 0.0)
|
2015-05-05 03:28:14 -07:00
|
|
|
timeout = end - ecore_time_get();
|
2012-11-06 02:49:05 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
2017-04-16 20:28:41 -07:00
|
|
|
#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;
|
|
|
|
|
2017-04-17 17:55:50 -07:00
|
|
|
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;
|
|
|
|
}
|
2017-04-16 20:28:41 -07:00
|
|
|
|
2017-04-17 22:16:53 -07:00
|
|
|
p->handling++;
|
2017-04-16 20:28:41 -07:00
|
|
|
if (fd_read_found)
|
|
|
|
{
|
|
|
|
_ecore_pipe_read(p, NULL);
|
|
|
|
message_count -= p->message;
|
|
|
|
total += p->message;
|
|
|
|
p->message = 0;
|
|
|
|
}
|
|
|
|
|
2017-04-17 22:21:06 -07:00
|
|
|
if ((fd_timer_found) && (p->timerfd != PIPE_FD_INVALID))
|
2017-04-16 20:28:41 -07:00
|
|
|
{
|
2017-04-17 22:30:22 -07:00
|
|
|
if (pipe_read(p->timerfd, &timerfdbuf, sizeof(timerfdbuf))
|
|
|
|
< sizeof(timerfdbuf))
|
|
|
|
WRN("Could not read timerfd data");
|
2017-04-17 22:16:53 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2017-04-16 20:28:41 -07:00
|
|
|
break;
|
|
|
|
}
|
2017-04-17 22:16:53 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2017-04-16 20:28:41 -07:00
|
|
|
}
|
|
|
|
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
|
2012-11-06 02:49:05 -08:00
|
|
|
static void
|
|
|
|
_ecore_pipe_handler_call(Ecore_Pipe *p,
|
|
|
|
unsigned char *buf,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
void *data = (void*) p->data;
|
2014-04-24 18:29:01 -07:00
|
|
|
|
|
|
|
// clear all values of pipe first.
|
|
|
|
p->passed_data = NULL;
|
|
|
|
p->already_read = 0;
|
|
|
|
p->len = 0;
|
|
|
|
p->message++;
|
|
|
|
|
2012-11-06 02:49:05 -08:00
|
|
|
if (!p->delete_me)
|
|
|
|
{
|
|
|
|
p->handler(data, buf, len);
|
2010-10-12 17:35:09 -07:00
|
|
|
}
|
2014-04-24 18:29:01 -07:00
|
|
|
|
|
|
|
// free p->passed_data
|
|
|
|
free(buf);
|
2010-10-12 17:35:09 -07:00
|
|
|
}
|
2008-11-11 23:54:25 -08:00
|
|
|
|
2010-06-24 09:15:56 -07:00
|
|
|
static Eina_Bool
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_pipe_read(void *data,
|
2012-11-25 01:55:32 -08:00
|
|
|
Ecore_Fd_Handler *fd_handler EINA_UNUSED)
|
2008-11-11 23:54:25 -08:00
|
|
|
{
|
2011-10-20 22:40:39 -07:00
|
|
|
Ecore_Pipe *p = (Ecore_Pipe *)data;
|
|
|
|
int i;
|
2008-11-11 23:54:25 -08:00
|
|
|
|
2010-10-12 17:35:09 -07:00
|
|
|
p->handling++;
|
|
|
|
for (i = 0; i < 16; i++)
|
2008-11-11 23:54:25 -08:00
|
|
|
{
|
2011-10-20 22:40:39 -07:00
|
|
|
ssize_t ret;
|
2010-09-29 23:09:20 -07:00
|
|
|
|
|
|
|
/* if we already have read some data we don't need to read the len
|
|
|
|
* but to finish the already started job
|
|
|
|
*/
|
|
|
|
if (p->len == 0)
|
|
|
|
{
|
|
|
|
/* read the len of the passed data */
|
2011-10-20 22:40:39 -07:00
|
|
|
ret = pipe_read(p->fd_read, &p->len, sizeof(p->len));
|
|
|
|
|
2017-04-17 17:55:50 -07:00
|
|
|
/* catch the non error case first */
|
2011-10-20 22:40:39 -07:00
|
|
|
/* read amount ok - nothing more to do */
|
|
|
|
if (ret == sizeof(p->len))
|
|
|
|
;
|
|
|
|
else if (ret > 0)
|
|
|
|
{
|
2017-04-17 17:55:50 -07:00
|
|
|
/* we got more data than we asked for - definite error */
|
2011-10-20 22:40:39 -07:00
|
|
|
ERR("Only read %i bytes from the pipe, although"
|
|
|
|
" we need to read %i bytes.",
|
|
|
|
(int)ret, (int)sizeof(p->len));
|
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
else if (ret == 0)
|
|
|
|
{
|
2017-04-17 17:55:50 -07:00
|
|
|
/* we got no data */
|
2011-10-20 22:40:39 -07:00
|
|
|
if (i == 0)
|
|
|
|
{
|
2017-04-17 17:55:50 -07:00
|
|
|
/* no data on first try through means an error */
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_handler_call(p, NULL, 0);
|
2011-10-20 22:40:39 -07:00
|
|
|
pipe_close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
p->fd_handler = NULL;
|
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-04-17 17:55:50 -07:00
|
|
|
/* no data after first loop try is ok */
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
}
|
2009-10-25 00:02:03 -07:00
|
|
|
#ifndef _WIN32
|
2011-10-20 22:40:39 -07:00
|
|
|
else if ((ret == PIPE_FD_ERROR) &&
|
|
|
|
((errno == EINTR) || (errno == EAGAIN)))
|
|
|
|
{
|
2013-05-22 04:40:56 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2011-10-20 22:40:39 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("An unhandled error (ret: %i errno: %i [%s])"
|
|
|
|
"occurred while reading from the pipe the length",
|
|
|
|
(int)ret, errno, strerror(errno));
|
2013-05-22 04:40:56 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2011-10-20 22:40:39 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
2009-10-25 00:02:03 -07:00
|
|
|
#else
|
2011-10-20 22:40:39 -07:00
|
|
|
else /* ret == PIPE_FD_ERROR is the only other case on Windows */
|
|
|
|
{
|
|
|
|
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
|
|
|
{
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_handler_call(p, NULL, 0);
|
2011-10-20 22:40:39 -07:00
|
|
|
pipe_close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
p->fd_handler = NULL;
|
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
}
|
2009-10-25 00:02:03 -07:00
|
|
|
#endif
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
2008-11-11 23:54:25 -08:00
|
|
|
|
2011-07-06 23:23:46 -07:00
|
|
|
/* if somehow we got less than or equal to 0 we got an errnoneous
|
2011-07-18 03:34:25 -07:00
|
|
|
* messages so call callback with null and len we got. this case should
|
|
|
|
* never happen */
|
|
|
|
if (p->len == 0)
|
2011-07-06 23:23:46 -07:00
|
|
|
{
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_handler_call(p, NULL, 0);
|
2011-07-06 23:23:46 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we dont have a buffer to hold the data, so alloc it */
|
2010-09-29 23:09:20 -07:00
|
|
|
if (!p->passed_data)
|
2011-07-06 23:23:46 -07:00
|
|
|
{
|
|
|
|
p->passed_data = malloc(p->len);
|
|
|
|
/* alloc failed - error case */
|
|
|
|
if (!p->passed_data)
|
|
|
|
{
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_handler_call(p, NULL, 0);
|
2017-04-17 17:55:50 -07:00
|
|
|
/* close the pipe */
|
2011-07-06 23:23:46 -07:00
|
|
|
pipe_close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
p->fd_handler = NULL;
|
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
}
|
2008-11-11 23:54:25 -08:00
|
|
|
|
2010-09-29 23:09:20 -07:00
|
|
|
/* and read the passed data */
|
|
|
|
ret = pipe_read(p->fd_read,
|
2009-08-12 17:27:53 -07:00
|
|
|
((unsigned char *)p->passed_data) + p->already_read,
|
|
|
|
p->len - p->already_read);
|
2011-04-20 07:15:33 -07:00
|
|
|
|
2010-09-29 23:09:20 -07:00
|
|
|
/* catch the non error case first */
|
2011-07-06 23:23:46 -07:00
|
|
|
/* if we read enough data to finish the message/buffer */
|
2017-02-10 20:05:44 -08:00
|
|
|
if (ret == (ssize_t)(p->len - p->already_read))
|
2014-04-24 18:29:01 -07:00
|
|
|
_ecore_pipe_handler_call(p, p->passed_data, p->len);
|
2011-07-06 23:23:46 -07:00
|
|
|
else if (ret > 0)
|
2010-09-29 23:09:20 -07:00
|
|
|
{
|
2011-07-06 23:23:46 -07:00
|
|
|
/* more data left to read */
|
2015-10-04 07:34:48 -07:00
|
|
|
p->already_read += (unsigned int) ret;
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
|
|
|
else if (ret == 0)
|
|
|
|
{
|
2011-07-18 03:34:25 -07:00
|
|
|
/* 0 bytes to read - could be more to read next select wake up */
|
2011-10-20 22:40:39 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
2010-09-29 23:09:20 -07:00
|
|
|
}
|
2009-10-25 00:02:03 -07:00
|
|
|
#ifndef _WIN32
|
2011-04-20 07:15:33 -07:00
|
|
|
else if ((ret == PIPE_FD_ERROR) &&
|
2011-01-20 22:25:36 -08:00
|
|
|
((errno == EINTR) || (errno == EAGAIN)))
|
2011-07-06 23:23:46 -07:00
|
|
|
{
|
|
|
|
_ecore_pipe_unhandle(p);
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
2010-09-29 23:09:20 -07:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ERR("An unhandled error (ret: %zd errno: %d)"
|
|
|
|
"occurred while reading from the pipe the data",
|
|
|
|
ret, errno);
|
2010-10-12 17:35:09 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2010-09-29 23:09:20 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
2009-10-25 00:02:03 -07:00
|
|
|
#else
|
|
|
|
else /* ret == PIPE_FD_ERROR is the only other case on Windows */
|
|
|
|
{
|
|
|
|
if (WSAGetLastError() != WSAEWOULDBLOCK)
|
|
|
|
{
|
2012-11-06 02:49:05 -08:00
|
|
|
_ecore_pipe_handler_call(p, NULL, 0);
|
2009-10-25 00:02:03 -07:00
|
|
|
pipe_close(p->fd_read);
|
|
|
|
p->fd_read = PIPE_FD_INVALID;
|
|
|
|
p->fd_handler = NULL;
|
2010-10-12 17:35:09 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2009-10-25 00:02:03 -07:00
|
|
|
return ECORE_CALLBACK_CANCEL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2008-11-11 23:54:25 -08:00
|
|
|
}
|
2011-04-20 07:15:33 -07:00
|
|
|
|
2010-10-12 17:35:09 -07:00
|
|
|
_ecore_pipe_unhandle(p);
|
2008-11-11 23:54:25 -08:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
2011-10-20 22:40:39 -07:00
|
|
|
|