From 8bef23c4e42f0d89b7a43dcf03dd304ce32f10c3 Mon Sep 17 00:00:00 2001 From: Constantin Papizh <p.const@bk.ru> Date: Fri, 6 Nov 2020 19:50:50 +0300 Subject: [PATCH] Timer type --- dap-sdk/core/include/dap_common.h | 4 ++ dap-sdk/core/src/dap_common.c | 2 - dap-sdk/net/core/dap_events_socket.c | 2 +- dap-sdk/net/core/dap_timerfd.c | 86 ++++++++++++++++++++------ dap-sdk/net/core/include/dap_timerfd.h | 8 +++ 5 files changed, 80 insertions(+), 22 deletions(-) diff --git a/dap-sdk/core/include/dap_common.h b/dap-sdk/core/include/dap_common.h index 430c7af507..5ed8b225ad 100755 --- a/dap-sdk/core/include/dap_common.h +++ b/dap-sdk/core/include/dap_common.h @@ -33,6 +33,10 @@ #include <stdlib.h> #include <stdio.h> #include <time.h> +#ifdef DAP_OS_WINDOWS +#include <fcntl.h> +#define pipe(pfds) _pipe(pfds, 4096, _O_BINARY) +#endif #ifdef __MACH__ #include <dispatch/dispatch.h> #endif diff --git a/dap-sdk/core/src/dap_common.c b/dap-sdk/core/src/dap_common.c index f5565971c8..1be7ab9cf7 100755 --- a/dap-sdk/core/src/dap_common.c +++ b/dap-sdk/core/src/dap_common.c @@ -55,8 +55,6 @@ #define popen _popen #define pclose _pclose - #define pipe(pfds) _pipe(pfds, 4096, 0x8000) - #endif #include "dap_common.h" diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/net/core/dap_events_socket.c index 1985ba9985..b711ceae5b 100644 --- a/dap-sdk/net/core/dap_events_socket.c +++ b/dap-sdk/net/core/dap_events_socket.c @@ -32,7 +32,6 @@ #include <sys/epoll.h> #include <sys/select.h> #include <unistd.h> -#include <fcntl.h> #else #include <winsock2.h> #include <windows.h> @@ -41,6 +40,7 @@ #include <io.h> #include "wepoll.h" #endif +#include <fcntl.h> #include <pthread.h> #include "dap_common.h" diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/net/core/dap_timerfd.c index 51be755a2c..a74724f230 100644 --- a/dap-sdk/net/core/dap_timerfd.c +++ b/dap-sdk/net/core/dap_timerfd.c @@ -20,17 +20,19 @@ You should have received a copy of the GNU General Public License along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ -#ifdef DAP_OS_UNIX + #include <stdint.h> #include <stdbool.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <sys/time.h> -#include <sys/timerfd.h> #include <inttypes.h> +#ifdef DAP_OS_WINDOWS +#include <winsock2.h> +#endif + #include "dap_common.h" #include "dap_events.h" #include "dap_worker.h" @@ -62,6 +64,15 @@ dap_timerfd_t* dap_timerfd_start(uint64_t a_timeout_ms, dap_timerfd_callback_t a return dap_timerfd_start_on_worker(dap_events_worker_get_auto(), a_timeout_ms, a_callback, a_callback_arg, a_repeated); } +#ifdef DAP_OS_WINDOWS +void __stdcall TimerAPCb(void* arg, DWORD low, DWORD high) { // Timer high value. + UNREFERENCED_PARAMETER(low) + UNREFERENCED_PARAMETER(high) + dap_timerfd_t *l_timerfd = (dap_timerfd_t *)arg; + write(l_timerfd->tfd2, 0, sizeof(void*)); +} +#endif + /** * @brief dap_timerfd_start_on_worker * @param a_worker @@ -73,10 +84,13 @@ dap_timerfd_t* dap_timerfd_start(uint64_t a_timeout_ms, dap_timerfd_callback_t a dap_timerfd_t* dap_timerfd_start_on_worker(dap_worker_t * a_worker, uint64_t a_timeout_ms, dap_timerfd_callback_t a_callback, void *a_callback_arg, bool a_repeated) { + dap_timerfd_t *l_timerfd = DAP_NEW(dap_timerfd_t); +#if defined DAP_OS_UNIX struct itimerspec l_ts; int l_tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if(l_tfd == -1) { log_it(L_WARNING, "dap_timerfd_start() failed: timerfd_create() errno=%d\n", errno); + DAP_DELETE(l_timerfd); return NULL; } // repeat never @@ -88,11 +102,33 @@ dap_timerfd_t* dap_timerfd_start_on_worker(dap_worker_t * a_worker, uint64_t a_t if(timerfd_settime(l_tfd, 0, &l_ts, NULL) < 0) { log_it(L_WARNING, "dap_timerfd_start() failed: timerfd_settime() errno=%d\n", errno); close(l_tfd); + DAP_DELETE(l_timerfd); return NULL; } - - // create dap_timerfd_t structure - dap_timerfd_t *l_timerfd = DAP_NEW(dap_timerfd_t); +#elif defined DAP_OS_WINDOWS + HANDLE l_th = CreateWaitableTimer(NULL, true, NULL); + if (!l_th) { + log_it(L_CRITICAL, "Waitable timer not created, error %d", GetLastError()); + DAP_DELETE(l_timerfd); + return NULL; + } + int l_pipe[2]; + if (pipe(l_pipe) < 0) { + log_it(L_ERROR, "Can't create pipe, error: %d", errno); + DAP_DELETE(l_timerfd); + return NULL; + } + unsigned long l_mode = 0; + int l_tfd = l_pipe[0]; + LARGE_INTEGER l_due_time; + l_due_time.QuadPart = (long long)a_timeout_ms * _MSEC; + if (!SetWaitableTimer(l_th, &l_due_time, 0, TimerAPCb, l_timerfd, false)) { + log_it(L_CRITICAL, "Waitable timer not set, error %d", GetLastError()); + CloseHandle(l_th); + DAP_DELETE(l_timerfd); + return NULL; + } +#endif // create events_socket for timer file descriptor dap_events_socket_callbacks_t l_s_callbacks; @@ -105,14 +141,20 @@ dap_timerfd_t* dap_timerfd_start_on_worker(dap_worker_t * a_worker, uint64_t a_t l_events_socket->_inheritor = l_timerfd; // fill out dap_timerfd_t structure - l_timerfd->timeout_ms = a_timeout_ms; - l_timerfd->tfd = l_tfd; - l_timerfd->events_socket = l_events_socket; - l_timerfd->callback = a_callback; - l_timerfd->callback_arg = a_callback_arg; - l_timerfd->repeated = a_repeated; + l_timerfd->timeout_ms = a_timeout_ms; + l_timerfd->tfd = l_tfd; + l_timerfd->events_socket = l_events_socket; + l_timerfd->callback = a_callback; + l_timerfd->callback_arg = a_callback_arg; + l_timerfd->repeated = a_repeated; +#ifdef DAP_OS_WINDOWS + l_timerfd->th = l_th; + l_timerfd->tfd2 = l_pipe[1]; + ioctlsocket(l_pipe[0], FIONBIO, &l_mode); + l_mode = 0; + ioctlsocket(l_pipe[1], FIONBIO, &l_mode); +#endif dap_worker_add_events_socket(l_events_socket, a_worker); - return l_timerfd; } @@ -122,13 +164,11 @@ dap_timerfd_t* dap_timerfd_start_on_worker(dap_worker_t * a_worker, uint64_t a_t */ static void s_es_callback_timer(struct dap_events_socket *a_event_sock) { - uint64_t l_ptiu64; dap_timerfd_t *l_timerfd = a_event_sock->_inheritor; - // run user's callback if(l_timerfd->callback) l_timerfd->callback(l_timerfd->callback_arg); if (l_timerfd->repeated) { - //printf("\nread() returned %d, %d\n", l_ptiu64, l_read_ret); +#if defined DAP_OS_UNIX struct itimerspec l_ts; // repeat never l_ts.it_interval.tv_sec = 0; @@ -139,8 +179,19 @@ static void s_es_callback_timer(struct dap_events_socket *a_event_sock) if(timerfd_settime(l_timerfd->tfd, 0, &l_ts, NULL) < 0) { log_it(L_WARNING, "callback_timerfd_read() failed: timerfd_settime() errno=%d\n", errno); } +#elif defined DAP_OS_WINDOWS + LARGE_INTEGER l_due_time; + l_due_time.QuadPart = (long long)l_timerfd->timeout_ms * _MSEC; + if (!SetWaitableTimer(l_timerfd->th, &l_due_time, 0, TimerAPCb, l_timerfd, false)) { + log_it(L_CRITICAL, "Waitable timer not reset, error %d", GetLastError()); + CloseHandle(l_timerfd->th); + } +#endif dap_events_socket_set_readable_unsafe(a_event_sock, true); } else { +#if defined DAP_OS_WINDOWS + CloseHandle(l_timerfd->th); +#endif dap_events_socket_remove_and_delete_unsafe(l_timerfd->events_socket, false); } } @@ -154,6 +205,3 @@ void dap_timerfd_delete(dap_timerfd_t *l_timerfd) { dap_events_socket_remove_and_delete_mt(l_timerfd->events_socket->worker, l_timerfd->events_socket); } -#else -#error "No dap_timerfd realization for your platform" -#endif diff --git a/dap-sdk/net/core/include/dap_timerfd.h b/dap-sdk/net/core/include/dap_timerfd.h index 0f600fe557..c8c524b3a2 100644 --- a/dap-sdk/net/core/include/dap_timerfd.h +++ b/dap-sdk/net/core/include/dap_timerfd.h @@ -27,8 +27,12 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> +#if defined DAP_OS_UNIX #include <sys/time.h> #include <sys/timerfd.h> +#elif defined DAP_OS_WINDOWS +#define _MSEC -10000 +#endif #include <inttypes.h> #include "dap_common.h" @@ -43,6 +47,10 @@ typedef struct dap_timerfd { dap_timerfd_callback_t callback; void *callback_arg; bool repeated; +#ifdef DAP_OS_WINDOWS + HANDLE th; + int tfd2; +#endif } dap_timerfd_t; int dap_timerfd_init(); -- GitLab