diff --git a/legacy/ecore/src/lib/ecore/ecore.c b/legacy/ecore/src/lib/ecore/ecore.c index 45a32d3830..72c735ccd6 100644 --- a/legacy/ecore/src/lib/ecore/ecore.c +++ b/legacy/ecore/src/lib/ecore/ecore.c @@ -181,7 +181,7 @@ ecore_init(void) eina_condition_new(&_thread_cond, &_thread_mutex); eina_lock_new(&_thread_feedback_mutex); eina_condition_new(&_thread_feedback_cond, &_thread_feedback_mutex); - _thread_call = ecore_pipe_add(_thread_callback, NULL); + _thread_call = _ecore_pipe_add(_thread_callback, NULL); eina_lock_new(&_thread_safety); eina_lock_new(&_thread_id_lock); @@ -268,8 +268,8 @@ ecore_shutdown(void) */ p = _thread_call; _thread_call = NULL; - ecore_pipe_wait(p, 1, 0.1); - ecore_pipe_del(p); + _ecore_pipe_wait(p, 1, 0.1); + _ecore_pipe_del(p); eina_lock_free(&_thread_safety); eina_condition_free(&_thread_cond); eina_lock_free(&_thread_mutex); diff --git a/legacy/ecore/src/lib/ecore/ecore_main.c b/legacy/ecore/src/lib/ecore/ecore_main.c index fea9fa85da..96deb45773 100644 --- a/legacy/ecore/src/lib/ecore/ecore_main.c +++ b/legacy/ecore/src/lib/ecore/ecore_main.c @@ -996,23 +996,20 @@ ecore_main_loop_select_func_get(void) return main_loop_select; } -EAPI Ecore_Fd_Handler * -ecore_main_fd_handler_add(int fd, - Ecore_Fd_Handler_Flags flags, - Ecore_Fd_Cb func, - const void *data, - Ecore_Fd_Cb buf_func, - const void *buf_data) +Ecore_Fd_Handler * +_ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) { Ecore_Fd_Handler *fdh = NULL; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); - _ecore_lock(); - - if ((fd < 0) || (flags == 0) || (!func)) goto unlock; + if ((fd < 0) || (flags == 0) || (!func)) return NULL; fdh = ecore_fd_handler_calloc(1); - if (!fdh) goto unlock; + if (!fdh) return NULL; ECORE_MAGIC_SET(fdh, ECORE_MAGIC_FD_HANDLER); fdh->next_ready = NULL; fdh->fd = fd; @@ -1022,8 +1019,7 @@ ecore_main_fd_handler_add(int fd, int err = errno; ERR("Failed to add poll on fd %d (errno = %d: %s)!", fd, err, strerror(err)); ecore_fd_handler_mp_free(fdh); - fdh = NULL; - goto unlock; + return NULL; } fdh->read_active = EINA_FALSE; fdh->write_active = EINA_FALSE; @@ -1038,12 +1034,26 @@ ecore_main_fd_handler_add(int fd, fd_handlers = (Ecore_Fd_Handler *) eina_inlist_append(EINA_INLIST_GET(fd_handlers), EINA_INLIST_GET(fdh)); -unlock: - _ecore_unlock(); return fdh; } +EAPI Ecore_Fd_Handler * +ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data) +{ + Ecore_Fd_Handler *fdh = NULL; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + fdh = _ecore_main_fd_handler_add(fd, flags, func, data, buf_func, buf_data); + _ecore_unlock(); + return fdh; +} + EAPI Ecore_Fd_Handler * ecore_main_fd_handler_file_add(int fd, Ecore_Fd_Handler_Flags flags, diff --git a/legacy/ecore/src/lib/ecore/ecore_pipe.c b/legacy/ecore/src/lib/ecore/ecore_pipe.c index debdbe846d..54477dfb4c 100644 --- a/legacy/ecore/src/lib/ecore/ecore_pipe.c +++ b/legacy/ecore/src/lib/ecore/ecore_pipe.c @@ -123,6 +123,277 @@ ecore_pipe_add(Ecore_Pipe_Cb handler, const void *data) { Ecore_Pipe *p; + + _ecore_lock(); + p = _ecore_pipe_add(handler, data); + _ecore_unlock(); + + return p; +} + +/** + * Free an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object to be freed. + * @return The pointer to the private data + */ +EAPI void * +ecore_pipe_del(Ecore_Pipe *p) +{ + void *r; + EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); + _ecore_lock(); + r = _ecore_pipe_del(p); + _ecore_unlock(); + return r; +} + +/** + * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + */ +EAPI void +ecore_pipe_read_close(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close"); + goto out; + } + if (p->fd_handler) + { + _ecore_main_fd_handler_del(p->fd_handler); + p->fd_handler = NULL; + } + if (p->fd_read != PIPE_FD_INVALID) + { + pipe_close(p->fd_read); + p->fd_read = PIPE_FD_INVALID; + } +out: + _ecore_unlock(); +} + +/** + * Stop monitoring if necessary the pipe for reading. See ecore_pipe_thaw() + * for monitoring it again. + * + * @param p The Ecore_Pipe object. + * @since 1.1 + */ +EAPI void +ecore_pipe_freeze(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze"); + goto out; + } + if (p->fd_handler) + { + _ecore_main_fd_handler_del(p->fd_handler); + p->fd_handler = NULL; + } +out: + _ecore_unlock(); +} + +/** + * Start monitoring again the pipe for reading. See ecore_pipe_freeze() for + * stopping the monitoring activity. This will not work if + * ecore_pipe_read_close() was previously called on the same pipe. + * + * @param p The Ecore_Pipe object. + * @since 1.1 + */ +EAPI void +ecore_pipe_thaw(Ecore_Pipe *p) +{ + EINA_MAIN_LOOP_CHECK_RETURN; + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw"); + goto out; + } + 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); + } +out: + _ecore_unlock(); +} + +/** + * @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. + * @since 1.1 + * + * Negative value for @p wait means infite wait. + */ +EAPI int +ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait) +{ + int r; + _ecore_lock(); + r = _ecore_pipe_wait(p, message_count, wait); + _ecore_unlock(); + return r; +} + +/** + * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). + * + * @param p The Ecore_Pipe object. + */ +EAPI void +ecore_pipe_write_close(Ecore_Pipe *p) +{ + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close"); + goto out; + } + if (p->fd_write != PIPE_FD_INVALID) + { + pipe_close(p->fd_write); + p->fd_write = PIPE_FD_INVALID; + } +out: + _ecore_unlock(); +} + +/** + * Write on the file descriptor the data passed as parameter. + * + * @param p The Ecore_Pipe object. + * @param buffer The data to write into the pipe. + * @param nbytes The size of the @p buffer in bytes + * @return @c EINA_TRUE on a successful write, @c EINA_FALSE on error. + */ +EAPI Eina_Bool +ecore_pipe_write(Ecore_Pipe *p, + const void *buffer, + unsigned int nbytes) +{ + ssize_t ret; + size_t already_written = 0; + int retry = ECORE_PIPE_WRITE_RETRY; + Eina_Bool ok = EINA_FALSE; + + _ecore_lock(); + if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) + { + ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); + goto out; + } + + if (p->delete_me) goto out; + + if (p->fd_write == PIPE_FD_INVALID) goto out; + + /* First write the len into the pipe */ + do + { + 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? */ + ERR("The length of the data was not written complete" + " to the pipe"); + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EPIPE) + { + pipe_close(p->fd_write); + p->fd_write = PIPE_FD_INVALID; + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EINTR) + /* try it again */ + ; + else + { + ERR("An unhandled error (ret: %zd errno: %d)" + "occurred while writing to the pipe the length", + ret, errno); + } + } + while (retry--); + + if (retry != ECORE_PIPE_WRITE_RETRY) goto out; + + /* and now pass the data to the pipe */ + do + { + ret = pipe_write(p->fd_write, + ((unsigned char *)buffer) + already_written, + nbytes - already_written); + + if (ret == (ssize_t)(nbytes - already_written)) + { + ok = EINA_TRUE; + goto out; + } + 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; + goto out; + } + else if (ret == PIPE_FD_ERROR && errno == EINTR) + /* try it again */ + ; + else + { + ERR("An unhandled error (ret: %zd errno: %d)" + "occurred while writing to the pipe the length", + ret, errno); + } + } + while (retry--); + +out: + _ecore_unlock(); + return ok; +} + +/** + * @} + */ + +/* Private functions */ +Ecore_Pipe * +_ecore_pipe_add(Ecore_Pipe_Cb handler, + const void *data) +{ + Ecore_Pipe *p = NULL; int fds[2]; EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); @@ -149,21 +420,15 @@ ecore_pipe_add(Ecore_Pipe_Cb handler, _ecore_pipe_read, p, NULL, NULL); + return p; } -/** - * Free an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object to be freed. - * @return The pointer to the private data - */ -EAPI void * -ecore_pipe_del(Ecore_Pipe *p) +void * +_ecore_pipe_del(Ecore_Pipe *p) { - void *data; + void *data = NULL; - EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL); if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) { ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_del"); @@ -179,97 +444,10 @@ ecore_pipe_del(Ecore_Pipe *p) return data; } -/** - * Close the read end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - */ -EAPI void -ecore_pipe_read_close(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_close"); - return; - } - if (p->fd_handler) - { - _ecore_main_fd_handler_del(p->fd_handler); - p->fd_handler = NULL; - } - if (p->fd_read != PIPE_FD_INVALID) - { - pipe_close(p->fd_read); - p->fd_read = PIPE_FD_INVALID; - } -} - -/** - * Stop monitoring if necessary the pipe for reading. See ecore_pipe_thaw() - * for monitoring it again. - * - * @param p The Ecore_Pipe object. - * @since 1.1 - */ -EAPI void -ecore_pipe_freeze(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_freeze"); - return; - } - if (p->fd_handler) - { - _ecore_main_fd_handler_del(p->fd_handler); - p->fd_handler = NULL; - } -} - -/** - * Start monitoring again the pipe for reading. See ecore_pipe_freeze() for - * stopping the monitoring activity. This will not work if - * ecore_pipe_read_close() was previously called on the same pipe. - * - * @param p The Ecore_Pipe object. - * @since 1.1 - */ -EAPI void -ecore_pipe_thaw(Ecore_Pipe *p) -{ - EINA_MAIN_LOOP_CHECK_RETURN; - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_read_thaw"); - return; - } - 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); - } -} - -/** - * @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. - * @since 1.1 - * - * Negative value for @p wait means infite wait. - */ -EAPI int -ecore_pipe_wait(Ecore_Pipe *p, - int message_count, - double wait) +int +_ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait) { struct timeval tv, *t; fd_set rset; @@ -347,136 +525,27 @@ ecore_pipe_wait(Ecore_Pipe *p, return total; } -/** - * Close the write end of an Ecore_Pipe object created with ecore_pipe_add(). - * - * @param p The Ecore_Pipe object. - */ -EAPI void -ecore_pipe_write_close(Ecore_Pipe *p) -{ - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write_close"); - return; - } - if (p->fd_write != PIPE_FD_INVALID) - { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - } -} - -/** - * Write on the file descriptor the data passed as parameter. - * - * @param p The Ecore_Pipe object. - * @param buffer The data to write into the pipe. - * @param nbytes The size of the @p buffer in bytes - * @return @c EINA_TRUE on a successful write, @c EINA_FALSE on error. - */ -EAPI Eina_Bool -ecore_pipe_write(Ecore_Pipe *p, - const void *buffer, - unsigned int nbytes) -{ - ssize_t ret; - size_t already_written = 0; - int retry = ECORE_PIPE_WRITE_RETRY; - - if (!ECORE_MAGIC_CHECK(p, ECORE_MAGIC_PIPE)) - { - ECORE_MAGIC_FAIL(p, ECORE_MAGIC_PIPE, "ecore_pipe_write"); - return EINA_FALSE; - } - - if (p->delete_me) return EINA_FALSE; - - if (p->fd_write == PIPE_FD_INVALID) return EINA_FALSE; - - /* First write the len into the pipe */ - do - { - 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? */ - ERR("The length of the data was not written complete" - " to the pipe"); - return EINA_FALSE; - } - else if (ret == PIPE_FD_ERROR && errno == EPIPE) - { - pipe_close(p->fd_write); - p->fd_write = PIPE_FD_INVALID; - return EINA_FALSE; - } - else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else - { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - - if (retry != ECORE_PIPE_WRITE_RETRY) return EINA_FALSE; - - /* and now pass the data to the pipe */ - do - { - ret = pipe_write(p->fd_write, - ((unsigned char *)buffer) + already_written, - nbytes - already_written); - - if (ret == (ssize_t)(nbytes - already_written)) - return EINA_TRUE; - 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; - return EINA_FALSE; - } - else if (ret == PIPE_FD_ERROR && errno == EINTR) - /* try it again */ - ; - else - { - ERR("An unhandled error (ret: %zd errno: %d)" - "occurred while writing to the pipe the length", - ret, errno); - } - } - while (retry--); - - return EINA_FALSE; -} - -/** - * @} - */ - -/* Private function */ static void _ecore_pipe_unhandle(Ecore_Pipe *p) { p->handling--; if (p->delete_me) { - ecore_pipe_del(p); + _ecore_pipe_del(p); + } +} + +static void +_ecore_pipe_handler_call(Ecore_Pipe *p, + unsigned char *buf, + size_t len) +{ + void *data = (void*) p->data; + if (!p->delete_me) + { + _ecore_unlock(); + p->handler(data, buf, len); + _ecore_lock(); } } @@ -519,8 +588,7 @@ _ecore_pipe_read(void *data, if (i == 0) { /* no data on first try through means an error */ - if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + _ecore_pipe_handler_call(p, NULL, 0); if (p->passed_data) free(p->passed_data); p->passed_data = NULL; p->already_read = 0; @@ -557,8 +625,7 @@ _ecore_pipe_read(void *data, { if (WSAGetLastError() != WSAEWOULDBLOCK) { - if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + _ecore_pipe_handler_call(p, NULL, 0); if (p->passed_data) free(p->passed_data); p->passed_data = NULL; p->already_read = 0; @@ -579,8 +646,7 @@ _ecore_pipe_read(void *data, * never happen */ if (p->len == 0) { - if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + _ecore_pipe_handler_call(p, NULL, 0); /* reset all values to 0 */ if (p->passed_data) free(p->passed_data); p->passed_data = NULL; @@ -598,8 +664,7 @@ _ecore_pipe_read(void *data, /* alloc failed - error case */ if (!p->passed_data) { - if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + _ecore_pipe_handler_call(p, NULL, 0); /* close the pipe */ p->already_read = 0; p->len = 0; @@ -621,8 +686,7 @@ _ecore_pipe_read(void *data, /* if we read enough data to finish the message/buffer */ if (ret == (ssize_t)(p->len - p->already_read)) { - if (!p->delete_me) - p->handler((void *)p->data, p->passed_data, p->len); + _ecore_pipe_handler_call(p, p->passed_data, p->len); free(p->passed_data); /* reset all values to 0 */ p->passed_data = NULL; @@ -663,8 +727,7 @@ _ecore_pipe_read(void *data, { if (WSAGetLastError() != WSAEWOULDBLOCK) { - if (!p->delete_me) - p->handler((void *)p->data, NULL, 0); + _ecore_pipe_handler_call(p, NULL, 0); if (p->passed_data) free(p->passed_data); p->passed_data = NULL; p->already_read = 0; diff --git a/legacy/ecore/src/lib/ecore/ecore_private.h b/legacy/ecore/src/lib/ecore/ecore_private.h index ce1199765c..f0add822fe 100644 --- a/legacy/ecore/src/lib/ecore/ecore_private.h +++ b/legacy/ecore/src/lib/ecore/ecore_private.h @@ -170,6 +170,20 @@ void *_ecore_event_signal_exit_new(void); void *_ecore_event_signal_power_new(void); void *_ecore_event_signal_realtime_new(void); +Ecore_Pipe *_ecore_pipe_add(Ecore_Pipe_Cb handler, + const void *data); +int _ecore_pipe_wait(Ecore_Pipe *p, + int message_count, + double wait); +void *_ecore_pipe_del(Ecore_Pipe *p); + +Ecore_Fd_Handler * + _ecore_main_fd_handler_add(int fd, + Ecore_Fd_Handler_Flags flags, + Ecore_Fd_Cb func, + const void *data, + Ecore_Fd_Cb buf_func, + const void *buf_data); void *_ecore_main_fd_handler_del(Ecore_Fd_Handler *fd_handler); void _ecore_main_shutdown(void);