From 4e8c3dce055c376982c446e62c78ce7d99410a11 Mon Sep 17 00:00:00 2001
From: Dmitriy Gerasimov <naeper@demlabs.net>
Date: Wed, 10 Feb 2021 20:27:23 +0700
Subject: [PATCH] [+] BSD timers

---
 CMakeLists.txt                               |  1 -
 cmake/OS_Detection.cmake                     |  4 +-
 dap-sdk/net/client/dap_client_http.c         |  1 +
 dap-sdk/net/core/dap_timerfd.c               | 67 +++++++++++++-------
 dap-sdk/net/core/dap_worker.c                | 15 ++++-
 dap-sdk/net/core/include/dap_events_socket.h |  1 -
 dap-sdk/net/core/include/dap_timerfd.h       |  2 +-
 7 files changed, 61 insertions(+), 30 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index eab8fd3789..08864a207f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,6 @@ if (ANDROID)
     add_subdirectory(3rdparty/libmagic)
     add_subdirectory(3rdparty/json-c)
     include_directories(cellframe-sdk/3rdparty/)
-
 endif()
 add_subdirectory(modules/)
 
diff --git a/cmake/OS_Detection.cmake b/cmake/OS_Detection.cmake
index fe97e43b02..fa5457b717 100644
--- a/cmake/OS_Detection.cmake
+++ b/cmake/OS_Detection.cmake
@@ -69,11 +69,11 @@ if(UNIX)
     endif()
     if (BSD)
         if(DAP_DEBUG)
-	  set(_CCOPT "-DDAP_DEBUG -Wall -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unused-function -Wno-implicit-fallthrough -Wno-unused-variable -Wno-unused-parameter -pg -g3 -ggdb -fno-eliminate-unused-debug-symbols -fno-strict-aliasing")
+	  set(_CCOPT "-I/usr/local/include -DDAP_DEBUG -Wall -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unused-function -Wno-implicit-fallthrough -Wno-unused-variable -Wno-unused-parameter -pg -g3 -ggdb -fno-eliminate-unused-debug-symbols -fno-strict-aliasing")
           set(_LOPT "-pg")
 	  SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -pg")
         else()
-	    set(_CCOPT "-Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unused-function -Wno-implicit-fallthrough -Wno-unused-variable -Wno-unused-parameter -O3 -fPIC -fno-strict-aliasing -fno-ident -ffast-math -ftree-vectorize -fno-asynchronous-unwind-tables -ffunction-sections -std=gnu11")
+	    set(_CCOPT "-I/usr/local/include -Wno-deprecated-declarations -Wno-unused-local-typedefs -Wno-unused-function -Wno-implicit-fallthrough -Wno-unused-variable -Wno-unused-parameter -O3 -fPIC -fno-strict-aliasing -fno-ident -ffast-math -ftree-vectorize -fno-asynchronous-unwind-tables -ffunction-sections -std=gnu11")
         endif()
     endif()
 
diff --git a/dap-sdk/net/client/dap_client_http.c b/dap-sdk/net/client/dap_client_http.c
index 4b95858769..e47609b4fb 100644
--- a/dap-sdk/net/client/dap_client_http.c
+++ b/dap-sdk/net/client/dap_client_http.c
@@ -22,6 +22,7 @@
 
 #include <unistd.h>
 #include <errno.h>
+#include <fcntl.h>
 
 #include "dap_common.h"
 #include "dap_strfuncs.h"
diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/net/core/dap_timerfd.c
index 1bbc56e3c1..f92a4af3a8 100644
--- a/dap-sdk/net/core/dap_timerfd.c
+++ b/dap-sdk/net/core/dap_timerfd.c
@@ -1,8 +1,9 @@
 /*
  * Authors:
  * Alexander Lysikov <alexander.lysikov@demlabs.net>
+ * Dmitriy Gerasimov <dmitriy.gerasimov@demlabs.net>
  * DeM Labs Ltd.   https://demlabs.net
- * Copyright  (c) 2020
+ * Copyright  (c) 2021
  * All rights reserved.
 
  This file is part of DAP SDK the open source project
@@ -114,7 +115,24 @@ dap_timerfd_t* dap_timerfd_start_on_proc_thread(dap_proc_thread_t * a_proc_threa
 dap_timerfd_t* dap_timerfd_create(uint64_t a_timeout_ms, dap_timerfd_callback_t a_callback, void *a_callback_arg)
 {
     dap_timerfd_t *l_timerfd = DAP_NEW(dap_timerfd_t);
-#if defined DAP_OS_UNIX
+    // create events_socket for timer file descriptor
+    dap_events_socket_callbacks_t l_s_callbacks;
+    memset(&l_s_callbacks,0,sizeof (l_s_callbacks));
+    l_s_callbacks.timer_callback = s_es_callback_timer;
+
+    dap_events_socket_t * l_events_socket = dap_events_socket_wrap_no_add(dap_events_get_default(), -1, &l_s_callbacks);
+    l_events_socket->type = DESCRIPTOR_TYPE_TIMER;
+
+    // pass l_timerfd to events_socket
+    l_events_socket->_inheritor = l_timerfd;
+
+    // fill out dap_timerfd_t structure
+    l_timerfd->timeout_ms       = a_timeout_ms;
+    l_timerfd->callback         = a_callback;
+    l_timerfd->callback_arg     = a_callback_arg;
+    l_timerfd->events_socket    = l_events_socket;
+    
+#if defined DAP_OS_LINUX
     struct itimerspec l_ts;
     int l_tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
     if(l_tfd == -1) {
@@ -134,7 +152,14 @@ dap_timerfd_t* dap_timerfd_create(uint64_t a_timeout_ms, dap_timerfd_callback_t
         DAP_DELETE(l_timerfd);
         return NULL;
     }
-#elif defined DAP_OS_WINDOWS
+    l_events_socket->socket = l_tfd;
+#elif defined (DAP_OS_BSD)
+    l_events_socket->kqueue_base_flags = EV_ADD | EV_ONESHOT | EV_DISPATCH;
+    l_events_socket->kqueue_base_filter = EVFILT_TIMER;
+    l_events_socket->kqueue_base_fflags = NOTE_MSECONDS;
+    l_events_socket->kqueue_data =(int64_t) a_timeout_ms;
+    l_events_socket->socket = rand();
+#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());
@@ -174,24 +199,12 @@ dap_timerfd_t* dap_timerfd_create(uint64_t a_timeout_ms, dap_timerfd_callback_t
         DAP_DELETE(l_timerfd);
         return NULL;
     }
+    l_events_socket->socket = l_tfd;
 #endif
-
-    // create events_socket for timer file descriptor
-    dap_events_socket_callbacks_t l_s_callbacks;
-    memset(&l_s_callbacks,0,sizeof (l_s_callbacks));
-    l_s_callbacks.timer_callback = s_es_callback_timer;
-
-    dap_events_socket_t * l_events_socket = dap_events_socket_wrap_no_add(dap_events_get_default(), l_tfd, &l_s_callbacks);
-    l_events_socket->type = DESCRIPTOR_TYPE_TIMER;
-    // pass l_timerfd to events_socket
-    l_events_socket->_inheritor = l_timerfd;
-
-    // fill out dap_timerfd_t structure
-    l_timerfd->timeout_ms       = a_timeout_ms;
+    
+#if defined (DAP_OS_LINUX) || defined (DAP_OS_WINDOWS)    
     l_timerfd->tfd              = l_tfd;
-    l_timerfd->events_socket    = l_events_socket;
-    l_timerfd->callback         = a_callback;
-    l_timerfd->callback_arg     = a_callback_arg;
+#endif
 #ifdef DAP_OS_WINDOWS
     l_timerfd->th               = l_th;
 #endif
@@ -208,7 +221,7 @@ static void s_es_callback_timer(struct dap_events_socket *a_event_sock)
     // run user's callback
     if(l_timerfd->callback && l_timerfd->callback(l_timerfd->callback_arg)) {
         //printf("\nread() returned %d, %d\n", l_ptiu64, l_read_ret);
-#if defined DAP_OS_UNIX
+#if defined DAP_OS_LINUX
         struct itimerspec l_ts;
         // repeat never
         l_ts.it_interval.tv_sec = 0;
@@ -219,20 +232,26 @@ 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
+#elif defined (DAP_OS_BSD)
+	struct kevent * l_event = &a_event_sock->kqueue_event;
+	EV_SET(l_event, 0, a_event_sock->kqueue_base_filter, a_event_sock->kqueue_base_flags,a_event_sock->kqueue_base_fflags,a_event_sock->kqueue_data,a_event_sock);
+	kevent(a_event_sock->worker->kqueue_fd,l_event,1,NULL,0,NULL);
+#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);
         }
+#else
+#error "No timer callback realization for your platform"        
 #endif
         dap_events_socket_set_readable_unsafe(a_event_sock, true);
     } else {
-#ifndef DAP_OS_WINDOWS
+#if defined(DAP_OS_LINUX)
         close(l_timerfd->tfd);
-#else
-        closesocket(l_timerfd->tfd);
+#elif defined(DAP_OS_WINDOWS)
+    	closesocket(l_timerfd->tfd);
         CloseHandle(l_timerfd->th);
 #endif
         l_timerfd->events_socket->flags |= DAP_SOCK_SIGNAL_CLOSE;
diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/net/core/dap_worker.c
index b652743e72..b1f3a4f03a 100644
--- a/dap-sdk/net/core/dap_worker.c
+++ b/dap-sdk/net/core/dap_worker.c
@@ -231,7 +231,7 @@ void *dap_worker_thread(void *arg)
             }
             if(s_debug_reactor) {
                 log_it(L_DEBUG, "Worker #%u esocket %p type %d fd=%d flags=0x%0X (%s:%s:%s:%s:%s:%s:%s:%s)", l_worker->id, l_cur, l_cur->type, l_cur->socket,
-                    l_cur_events, l_flag_read?"read":"", l_flag_write?"write":"", l_flag_error?"error":"",
+                    l_cur_flags, l_flag_read?"read":"", l_flag_write?"write":"", l_flag_error?"error":"",
                     l_flag_hup?"hup":"", l_flag_rdhup?"rdhup":"", l_flag_msg?"msg":"", l_flag_nval?"nval":"", l_flag_pri?"pri":"");
             }
 
@@ -614,6 +614,19 @@ void *dap_worker_thread(void *arg)
                                 l_errno = errno;
                                 if (l_bytes_sent == -1 && l_errno == EINVAL) // To make compatible with other
                                     l_errno = EAGAIN;                        // non-blocking sockets
+#elif defined (DAP_EVENTS_CAPS_KQUEUE)                                    
+				struct kevent* l_event=&l_cur->kqueue_event;
+				void * l_ptr;
+				memcpy(l_ptr,l_cur->buf_out,sizeof(l_ptr) );
+				EV_SET(l_event,(uintptr_t) l_ptr, l_cur->kqueue_base_filter,l_cur->kqueue_base_flags, l_cur->kqueue_base_fflags,l_cur->kqueue_data, l_cur);
+				int l_n = kevent(l_worker->kqueue_fd,l_event,1,NULL,0,NULL);
+				if (l_n == 1)
+				    l_bytes_sent = sizeof(l_ptr);
+				else{
+				    l_errno = errno;
+				    log_it(L_WARNING,"queue ptr send error: kevent %p errno: %d", l_ptr, l_errno);
+				}
+                                    
 #else
 #error "Not implemented dap_events_socket_queue_ptr_send() for this platform"
 #endif
diff --git a/dap-sdk/net/core/include/dap_events_socket.h b/dap-sdk/net/core/include/dap_events_socket.h
index 1c198e3e24..0ed09f26ec 100644
--- a/dap-sdk/net/core/include/dap_events_socket.h
+++ b/dap-sdk/net/core/include/dap_events_socket.h
@@ -246,7 +246,6 @@ typedef struct dap_events_socket {
     unsigned short kqueue_base_flags;
     unsigned int kqueue_base_fflags;
     int64_t kqueue_data;
-    uint64_t kqueue_ext[4];
 #endif
 
     dap_events_socket_callbacks_t callbacks;
diff --git a/dap-sdk/net/core/include/dap_timerfd.h b/dap-sdk/net/core/include/dap_timerfd.h
index 0bf5dff9eb..700e5a2bc3 100644
--- a/dap-sdk/net/core/include/dap_timerfd.h
+++ b/dap-sdk/net/core/include/dap_timerfd.h
@@ -50,7 +50,7 @@ typedef struct dap_timerfd {
 #ifdef DAP_OS_WINDOWS
 	SOCKET tfd;
     u_short port;
-#else
+#elif defined(DAP_OS_LINUX)
     int tfd; //timer file descriptor
 #endif
     dap_events_socket_t *events_socket;
-- 
GitLab