diff --git a/CMakeLists.txt b/CMakeLists.txt
index e0a037830865a3f790808a31a24ecc48b886f841..a8b1295351b04566809b680cf7ecd707c94c4b62 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,7 +51,7 @@ if (CELLFRAME_MODULES MATCHES "srv-stake")
 endif()
 
 if (CELLFRAME_MODULES MATCHES "core")
-    SET(DAPSDK_MODULES "${DAPSDK_MODULES} core crypto")
+    SET(DAPSDK_MODULES "${DAPSDK_MODULES} core crypto io")
 endif()
 
 
@@ -61,7 +61,7 @@ endif()
 
 if (CELLFRAME_MODULES MATCHES "dap-sdk-net-client")
     set(DAPSDK_MODULES "core crypto network-core network-client network-server")
-    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_core dap_crypto dap_server_core dap_server dap_client m pthread)
+    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_core dap_crypto dap_io dap_server dap_client m pthread)
     if (SUPPORT_PYTHON_PLUGINS)
         set(CELLFRAME_MODULES "${CELLFRAME_MODULES} core chains network cs-none srv-")
     endif()
@@ -129,7 +129,7 @@ endif()
 # Networking
 if (CELLFRAME_MODULES MATCHES "network")
     message("[+] Module 'network'")
-    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_server_core dap_json_rpc dap_enc_server dap_notify_srv dap_http_server dap_session
+    set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_io dap_json_rpc dap_enc_server dap_notify_srv dap_http_server dap_session
         dap_stream dap_stream_ch dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain_net dap_chain_net_srv dap_stream_ch_chain_voting dap_chain_mempool magic)
 endif()
 
diff --git a/dap-sdk/CMakeLists.txt b/dap-sdk/CMakeLists.txt
index 9a6f3fa6394bd90cbc3d3d93c2aae300b843a209..0781b5dec7acebc17ae9a3b356220bb8efc7f688 100644
--- a/dap-sdk/CMakeLists.txt
+++ b/dap-sdk/CMakeLists.txt
@@ -14,13 +14,18 @@ if (DAPSDK_MODULES MATCHES "crypto")
     add_subdirectory(crypto)
 endif()
 
+# I/O subsystem
+if (DAPSDK_MODULES MATCHES "io")
+    add_subdirectory(io)
+endif()
+
 # Networking core
 if (DAPSDK_MODULES MATCHES "network-core")
-    add_subdirectory(net/core)
     add_subdirectory(net/stream)
 endif()
 
 if (DAPSDK_MODULES MATCHES "network-pure")
+    add_subdirectory(io)
     add_subdirectory(net/core)
 endif()
 
diff --git a/dap-sdk/core/include/dap_strfuncs.h b/dap-sdk/core/include/dap_strfuncs.h
index c638d9260dcd617f4d3e33d5ccd6f5f0d541cfe3..a14b12dc5cc5004caa3fde658da78503a15a8f7b 100755
--- a/dap-sdk/core/include/dap_strfuncs.h
+++ b/dap-sdk/core/include/dap_strfuncs.h
@@ -46,6 +46,7 @@ char *strptime( char *buff, const char *fmt, struct tm *tm );
 
 bool dap_isstralnum(const char *c);
 size_t dap_strlen(const char *a_str);
+char* dap_strcat2(const char* s1, const char* s2);
 // compare a_str1 and a_str2
 int dap_strcmp(const char *a_str1, const char *a_str2);
 // compare a_n characters of a_str1 and a_str2
diff --git a/dap-sdk/core/src/dap_strfuncs.c b/dap-sdk/core/src/dap_strfuncs.c
index f960159e161d38242545a38c5923262a62676c45..a0e88234b22cb4d9f6754ff61a3b56fc3963cac0 100755
--- a/dap-sdk/core/src/dap_strfuncs.c
+++ b/dap-sdk/core/src/dap_strfuncs.c
@@ -33,6 +33,41 @@ bool dap_isstralnum(const char *c)
     return true;
 }
 
+/**
+ * @brief strcat two strings with new char array in result
+ * 
+ * @param s1 preallocated buffer with char string
+ * @param s2 char string
+ * @return char* 
+ */
+char* dap_strcat2(const char* s1, const char* s2)
+{
+  size_t size1 = 0;
+  size_t size2 = 0;
+  if (!s1)
+    size1 = 0;
+  else
+    size1 = strlen(s1);
+  if (!s2)
+    size2 = 0;
+  else
+    size2 = strlen(s2);
+    
+  char* result = malloc(size1 + size2 + 1);
+
+  if(result == NULL) 
+  {
+    exit(EXIT_FAILURE);
+  }
+
+  memcpy(result, s1, size1);
+  memcpy(result+size1, s2, size2);
+  free((void*)s1);
+  result[size1 + size2] = '\0';
+  return result;
+}
+
+
 
 /**
  * @brief s_strdigit
diff --git a/dap-sdk/net/core/CMakeLists.txt b/dap-sdk/io/CMakeLists.txt
similarity index 68%
rename from dap-sdk/net/core/CMakeLists.txt
rename to dap-sdk/io/CMakeLists.txt
index ca3fe8666b0f24b9575ffa8e9454e9e720e8bcfd..fc87bf0605419e5222abfae71c2cbc18dffcfa2e 100644
--- a/dap-sdk/net/core/CMakeLists.txt
+++ b/dap-sdk/io/CMakeLists.txt
@@ -1,23 +1,23 @@
 cmake_minimum_required(VERSION 3.10)
 
-project (dap_server_core C)
+project (dap_io C)
 set(CMAKE_C_STANDARD 11)
 
 add_definitions ("-D_GNU_SOURCE")
 
 if(WIN32)
-    file(GLOB DAP_SERVER_CORE_SOURCES *.c ../../../3rdparty/wepoll/*.c)
-    file(GLOB DAP_SERVER_CORE_HEADERS include/*.h ../../../3rdparty/wepoll/*.h)
+    file(GLOB DAP_IO_SOURCES *.c ../../../3rdparty/wepoll/*.c)
+    file(GLOB DAP_IO_HEADERS include/*.h ../../../3rdparty/wepoll/*.h)
 else()
-    file(GLOB DAP_SERVER_CORE_SOURCES *.c)
-    file(GLOB DAP_SERVER_CORE_HEADERS include/*.h)
+    file(GLOB DAP_IO_SOURCES *.c)
+    file(GLOB DAP_IO_HEADERS include/*.h)
 endif()
 
 if(WIN32)
   include_directories(../../../modules/net/win32)
 endif()
 
-add_library(${PROJECT_NAME} STATIC ${DAP_SERVER_CORE_HEADERS} ${DAP_SERVER_CORE_SOURCES})
+add_library(${PROJECT_NAME} STATIC ${DAP_IO_HEADERS} ${DAP_IO_SOURCES})
 
 if(DAPSDK_MODULES MATCHES "ssl-support")
   target_link_libraries(${PROJECT_NAME} dap_core dap_crypto wolfssl)
@@ -40,7 +40,7 @@ if (WIN32)
     target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/wepoll)
 endif()
 
-if (${BUILD_DAP_SERVER_CORE_TESTS} MATCHES ON)
+if (${BUILD_DAP_IO_TESTS} MATCHES ON)
     enable_testing()
     add_subdirectory(test)
 endif()
diff --git a/dap-sdk/net/core/dap_worker.c b/dap-sdk/io/dap_context.c
similarity index 61%
rename from dap-sdk/net/core/dap_worker.c
rename to dap-sdk/io/dap_context.c
index e25a00b357dc4720c8db982e7656d8b3b38fe8c3..3c7b7358469a9ddd8d53398420cb104941a08068 100644
--- a/dap-sdk/net/core/dap_worker.c
+++ b/dap-sdk/io/dap_context.c
@@ -2,7 +2,7 @@
  * Authors:
  * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
  * DeM Labs Ltd.   https://demlabs.net
- * Copyright  (c) 2017
+ * Copyright  (c) 2022
  * All rights reserved.
 
  This file is part of DAP SDK the open source project
@@ -20,9 +20,14 @@
     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/>.
 */
-#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
 #include <errno.h>
-#include <unistd.h>
+#include <stdatomic.h>
+
 #if ! defined (_GNU_SOURCE)
 #define _GNU_SOURCE         /* See feature_test_macros(7) */
 #endif
@@ -36,6 +41,28 @@
 #include <ws2tcpip.h>
 #endif
 
+#if defined (DAP_OS_LINUX)
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#elif defined (DAP_OS_BSD)
+#include <sys/types.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+
+#elif defined (DAP_OS_WINDOWS)
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <io.h>
+
+#endif
+
 #ifdef DAP_OS_DARWIN
 #define NOTE_READ NOTE_LOWAT
 
@@ -45,43 +72,27 @@
 
 #endif
 
-#include "dap_common.h"
-#include "dap_config.h"
-#include "dap_math_ops.h"
-#include "dap_worker.h"
-#include "dap_timerfd.h"
-#include "dap_events.h"
-#include "dap_enc_base64.h"
-#include "dap_proc_queue.h"
-
-#ifndef DAP_NET_CLIENT_NO_SSL
-#include <wolfssl/options.h>
-#include "wolfssl/ssl.h"
+#if defined (DAP_EVENTS_CAPS_QUEUE_MQUEUE)
+#include <sys/time.h>
+#include <sys/resource.h>
 #endif
 
-#define LOG_TAG "dap_worker"
+#define LOG_TAG "dap_context"
 
-static time_t s_connection_timeout = 60;    // seconds
+#include "dap_common.h"
+#include "dap_uuid.h"
+#include "dap_context.h"
+#include "dap_worker.h"
+#include "dap_events_socket.h"
+pthread_key_t g_dap_context_pth_key;
 
-static bool s_socket_all_check_activity( void * a_arg);
-static void s_queue_add_es_callback( dap_events_socket_t * a_es, void * a_arg);
-static void s_queue_delete_es_callback( dap_events_socket_t * a_es, void * a_arg);
-static void s_queue_es_reassign_callback( dap_events_socket_t * a_es, void * a_arg);
-static void s_queue_callback_callback( dap_events_socket_t * a_es, void * a_arg);
-static void s_queue_es_io_callback( dap_events_socket_t * a_es, void * a_arg);
-static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags);
 
 /**
- * @brief dap_worker_init
- * @param a_threads_count
- * @param conn_timeout
+ * @brief dap_context_init
  * @return
  */
-int dap_worker_init( size_t a_conn_timeout )
+int dap_context_init()
 {
-    if ( a_conn_timeout )
-      s_connection_timeout = a_conn_timeout;
-
 #ifdef DAP_OS_UNIX
     struct rlimit l_fdlimit;
     if (getrlimit(RLIMIT_NOFILE, &l_fdlimit))
@@ -96,101 +107,75 @@ int dap_worker_init( size_t a_conn_timeout )
     return 0;
 }
 
-void dap_worker_deinit( )
+/**
+ * @brief dap_context_new
+ * @return
+ */
+dap_context_t * dap_context_new()
 {
+   dap_context_t * l_context = DAP_NEW_Z(dap_context_t);
+   static uint32_t s_context_id_max = 0;
+   l_context->id = s_context_id_max;
+   s_context_id_max++;
+   return l_context;
 }
 
 /**
- * @brief dap_worker_thread
- * @param arg
+ * @brief dap_context_thread_init
+ * @param a_context
  * @return
  */
-void *dap_worker_thread(void *arg)
+int dap_context_thread_init(dap_context_t * a_context)
 {
-    dap_events_socket_t *l_cur;
-    dap_worker_t *l_worker = (dap_worker_t *) arg;
-    uint32_t l_tn = l_worker->id;
-    int l_errno = 0, l_selected_sockets;
-    socklen_t l_error_len = sizeof(l_errno);
-    char l_error_buf[128] = {0};
-    ssize_t l_bytes_sent = 0, l_bytes_read = 0, l_sockets_max;
-    const struct sched_param l_shed_params = {0};
-
-
-    dap_cpu_assign_thread_on(l_worker->id);
-    pthread_setspecific(l_worker->events->pth_key_worker, l_worker);
+    pthread_setspecific(g_dap_context_pth_key, a_context);
 
-#ifdef DAP_OS_WINDOWS
-    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL))
-        log_it(L_ERROR, "Couldn'r set thread priority, err: %lu", GetLastError());
-#else
-    pthread_setschedparam(pthread_self(),SCHED_FIFO ,&l_shed_params);
-#endif
+#if defined(DAP_EVENTS_CAPS_KQUEUE)
+    a_context->kqueue_fd = kqueue();
 
-#ifdef DAP_EVENTS_CAPS_EPOLL
-    struct epoll_event l_epoll_events[ DAP_EVENTS_SOCKET_MAX]= {{0}};
-    log_it(L_INFO, "Worker #%d started with epoll fd %"DAP_FORMAT_HANDLE" and assigned to dedicated CPU unit", l_worker->id, l_worker->epoll_fd);
-#elif defined(DAP_EVENTS_CAPS_KQUEUE)
-    l_worker->kqueue_fd = kqueue();
-
-    if (l_worker->kqueue_fd == -1 ){
-    int l_errno = errno;
-    char l_errbuf[255];
-    strerror_r(l_errno,l_errbuf,sizeof(l_errbuf));
-    log_it (L_CRITICAL,"Can't create kqueue(): '%s' code %d",l_errbuf,l_errno);
-    pthread_cond_broadcast(&l_worker->started_cond);
-    return NULL;
+    if (a_context->kqueue_fd == -1 ){
+        int l_errno = errno;
+        char l_errbuf[255];
+        strerror_r(l_errno,l_errbuf,sizeof(l_errbuf));
+        log_it (L_CRITICAL,"Can't create kqueue(): '%s' code %d",l_errbuf,l_errno);
+        return -1;
     }
 
-    l_worker->kqueue_events_selected_count_max = 100;
-    l_worker->kqueue_events_count_max = DAP_EVENTS_SOCKET_MAX;
-    l_worker->kqueue_events_selected = DAP_NEW_Z_SIZE(struct kevent, l_worker->kqueue_events_selected_count_max *sizeof(struct kevent));
+    a_context->kqueue_events_selected_count_max = 100;
+    a_context->kqueue_events_count_max = DAP_EVENTS_SOCKET_MAX;
+    a_context->kqueue_events_selected = DAP_NEW_Z_SIZE(struct kevent, a_context->kqueue_events_selected_count_max *sizeof(struct kevent));
 #elif defined(DAP_EVENTS_CAPS_POLL)
-    l_worker->poll_count_max = DAP_EVENTS_SOCKET_MAX;
-    l_worker->poll = DAP_NEW_Z_SIZE(struct pollfd,l_worker->poll_count_max*sizeof (struct pollfd));
-    l_worker->poll_esocket = DAP_NEW_Z_SIZE(dap_events_socket_t*,l_worker->poll_count_max*sizeof (dap_events_socket_t*));
+    a_context->poll_count_max = DAP_EVENTS_SOCKET_MAX;
+    a_context->poll = DAP_NEW_Z_SIZE(struct pollfd,a_context->poll_count_max*sizeof (struct pollfd));
+    a_context->poll_esocket = DAP_NEW_Z_SIZE(dap_events_socket_t*,a_context->poll_count_max*sizeof (dap_events_socket_t*));
 #else
 #error "Unimplemented socket array for this platform"
 #endif
+    return 0;
+}
 
-    l_worker->queue_es_new_input      = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
-    l_worker->queue_es_delete_input   = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
-    l_worker->queue_es_io_input       = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
-    l_worker->queue_es_reassign_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
-
-
-    l_worker->queue_es_new      = dap_events_socket_create_type_queue_ptr_unsafe(l_worker, s_queue_add_es_callback);
-    l_worker->queue_es_delete   = dap_events_socket_create_type_queue_ptr_unsafe(l_worker, s_queue_delete_es_callback);
-    l_worker->queue_es_io       = dap_events_socket_create_type_queue_ptr_unsafe(l_worker, s_queue_es_io_callback);
-    l_worker->queue_es_reassign = dap_events_socket_create_type_queue_ptr_unsafe(l_worker, s_queue_es_reassign_callback );
-
-
-    for( size_t n = 0; n < dap_events_worker_get_count(); n++) {
-        l_worker->queue_es_new_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_new);
-        l_worker->queue_es_delete_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_delete);
-        l_worker->queue_es_io_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_io);
-        l_worker->queue_es_reassign_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_reassign);
-    }
-
-    l_worker->queue_callback    = dap_events_socket_create_type_queue_ptr_unsafe(l_worker, s_queue_callback_callback);
-    l_worker->event_exit        = dap_events_socket_create_type_event_unsafe(l_worker, s_event_exit_callback);
+/**
+ * @brief dap_context_thread_loop
+ * @param a_context
+ * @return
+ */
+int dap_context_thread_loop(dap_context_t * a_context)
+{
+    int l_errno = 0, l_selected_sockets = 0;
+    dap_events_socket_t *l_cur = NULL;
 
-    l_worker->timer_check_activity = dap_timerfd_create(s_connection_timeout * 1000 / 2,
-                                                        s_socket_all_check_activity, l_worker);
-    dap_worker_add_events_socket_unsafe(  l_worker->timer_check_activity->events_socket, l_worker);
-    pthread_mutex_lock(&l_worker->started_mutex);
-    pthread_cond_broadcast(&l_worker->started_cond);
-    pthread_mutex_unlock(&l_worker->started_mutex);
+    socklen_t l_error_len = sizeof(l_errno);
+    char l_error_buf[128] = {0};
+    ssize_t l_bytes_sent = 0, l_bytes_read = 0, l_sockets_max;
 
-    while (1) {
+    do {
 #ifdef DAP_EVENTS_CAPS_EPOLL
-        l_selected_sockets = epoll_wait(l_worker->epoll_fd, l_epoll_events, DAP_EVENTS_SOCKET_MAX, -1);
+        l_selected_sockets = epoll_wait(a_context->epoll_fd, l_epoll_events, DAP_EVENTS_SOCKET_MAX, -1);
         l_sockets_max = l_selected_sockets;
 #elif defined(DAP_EVENTS_CAPS_POLL)
-        l_selected_sockets = poll(l_worker->poll, l_worker->poll_count, -1);
-        l_sockets_max = l_worker->poll_count;
+        l_selected_sockets = poll(a_context->poll, a_context->poll_count, -1);
+        l_sockets_max = a_context->poll_count;
 #elif defined(DAP_EVENTS_CAPS_KQUEUE)
-        l_selected_sockets = kevent(l_worker->kqueue_fd,NULL,0,l_worker->kqueue_events_selected,l_worker->kqueue_events_selected_count_max,
+        l_selected_sockets = kevent(a_context->kqueue_fd,NULL,0,a_context->kqueue_events_selected,a_context->kqueue_events_selected_count_max,
                                                         NULL);
         l_sockets_max = l_selected_sockets;
 #else
@@ -200,10 +185,10 @@ void *dap_worker_thread(void *arg)
             if( errno == EINTR)
                 continue;
 #ifdef DAP_OS_WINDOWS
-            log_it(L_ERROR, "Worker thread %d got errno %d", l_worker->id, WSAGetLastError());
+            log_it(L_ERROR, "Context thread %d got errno %d", a_context->id, WSAGetLastError());
 #else
             strerror_r(l_errno, l_error_buf, sizeof (l_error_buf) - 1);
-            log_it(L_ERROR, "Worker thread %d got errno:\"%s\" (%d)", l_worker->id, l_error_buf, l_errno);
+            log_it(L_ERROR, "Context thread %d got errno:\"%s\" (%d)", a_context->id, l_error_buf, l_errno);
             assert(l_errno);
 #endif
             break;
@@ -225,9 +210,9 @@ void *dap_worker_thread(void *arg)
             l_flag_nval     = false;
             l_flag_msg = false;
 #elif defined ( DAP_EVENTS_CAPS_POLL)
-            short l_cur_flags =l_worker->poll[n].revents;
+            short l_cur_flags =a_context->poll[n].revents;
 
-            if (l_worker->poll[n].fd == -1) // If it was deleted on previous iterations
+            if (a_context->poll[n].fd == -1) // If it was deleted on previous iterations
                 continue;
 
             if (!l_cur_flags) // No events for this socket
@@ -241,11 +226,11 @@ void *dap_worker_thread(void *arg)
             l_flag_nval = l_cur_flags & POLLNVAL;
             l_flag_pri = l_cur_flags & POLLPRI;
             l_flag_msg = l_cur_flags & POLLMSG;
-            l_cur = l_worker->poll_esocket[n];
-            //log_it(L_DEBUG, "flags: returned events 0x%0X requested events 0x%0X",l_worker->poll[n].revents,l_worker->poll[n].events );
+            l_cur = a_context->poll_esocket[n];
+            //log_it(L_DEBUG, "flags: returned events 0x%0X requested events 0x%0X",a_context->poll[n].revents,a_context->poll[n].events );
 #elif defined (DAP_EVENTS_CAPS_KQUEUE)
         l_flag_hup=l_flag_rdhup=l_flag_read=l_flag_write=l_flag_error=l_flag_nval=l_flag_msg =l_flag_pri = false;
-        struct kevent * l_kevent_selected = &l_worker->kqueue_events_selected[n];
+        struct kevent * l_kevent_selected = &a_context->kqueue_events_selected[n];
         if ( l_kevent_selected->filter == EVFILT_USER){ // If we have USER event it sends little different pointer
             dap_events_socket_w_data_t * l_es_w_data = (dap_events_socket_w_data_t *) l_kevent_selected->udata;
             //if(g_debug_reactor)
@@ -273,7 +258,9 @@ void *dap_worker_thread(void *arg)
                 case EVFILT_READ: l_flag_read = true; break;
                 case EVFILT_WRITE: l_flag_write = true; break;
                 case EVFILT_EXCEPT : l_flag_rdhup = true; break;
-                default: log_it(L_CRITICAL,"Unknown filter type in polling, exit thread"); return NULL;
+                default:
+                    log_it(L_CRITICAL,"Unknown filter type in polling, exit thread");
+                    return -1;
             }
             if (l_kevent_selected->flags & EV_EOF)
                 l_flag_rdhup = true;
@@ -296,13 +283,13 @@ void *dap_worker_thread(void *arg)
 #else
 #error "Unimplemented fetch esocket after poll"
 #endif
-            if(!l_cur || (l_cur->worker && l_cur->worker != l_worker)) {
+            if(!l_cur || (l_cur->context && l_cur->context != a_context)) {
                 log_it(L_WARNING, "dap_events_socket was destroyed earlier");
                 continue;
             }
             if(g_debug_reactor) {
-                log_it(L_DEBUG, "--Worker #%u esocket %p uuid 0x%016"DAP_UINT64_FORMAT_x" type %d fd=%"DAP_FORMAT_SOCKET" flags=0x%0X (%s:%s:%s:%s:%s:%s:%s:%s)--",
-                       l_worker->id, l_cur, l_cur->uuid, l_cur->type, l_cur->socket,
+                log_it(L_DEBUG, "--Context #%u esocket %p uuid 0x%016"DAP_UINT64_FORMAT_x" type %d fd=%"DAP_FORMAT_SOCKET" flags=0x%0X (%s:%s:%s:%s:%s:%s:%s:%s)--",
+                       a_context->id, l_cur, l_cur->uuid, l_cur->type, l_cur->socket,
                     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":"");
@@ -523,7 +510,7 @@ void *dap_worker_thread(void *arg)
                             log_it(L_DEBUG, "Received %zd bytes for fd %d ", l_bytes_read, l_cur->fd);
                         if(l_cur->callbacks.read_callback){
                             l_cur->callbacks.read_callback(l_cur, NULL); // Call callback to process read event. At the end of callback buf_in_size should be zero if everything was read well
-                            if (l_cur->worker == NULL ){ // esocket was unassigned in callback, we don't need any ops with it now,
+                            if (l_cur->context == NULL ){ // esocket was unassigned in callback, we don't need any ops with it now,
                                                          // continue to poll another esockets
                                 continue;
                             }
@@ -606,7 +593,7 @@ void *dap_worker_thread(void *arg)
                         l_cur->flags ^= DAP_SOCK_CONNECTING;
                         if (l_cur->callbacks.connected_callback)
                             l_cur->callbacks.connected_callback(l_cur);
-                        dap_events_socket_worker_poll_update_unsafe(l_cur);
+                        dap_context_poll_update(l_cur);
                     }
 #endif
                 } else {
@@ -627,7 +614,7 @@ void *dap_worker_thread(void *arg)
                         l_cur->flags ^= DAP_SOCK_CONNECTING;
                         if (l_cur->callbacks.connected_callback)
                             l_cur->callbacks.connected_callback(l_cur);
-                        dap_events_socket_worker_poll_update_unsafe(l_cur);
+                        dap_context_poll_update(l_cur);
                     }
                 }
             }
@@ -652,7 +639,7 @@ void *dap_worker_thread(void *arg)
                 if (l_cur->callbacks.write_callback)
                     l_cur->callbacks.write_callback(l_cur, NULL);           /* Call callback to process write event */
 
-                if ( l_cur->worker && l_flag_write ){ // esocket wasn't unassigned in callback, we need some other ops with it
+                if ( l_cur->context && l_flag_write ){ // esocket wasn't unassigned in callback, we need some other ops with it
                         switch (l_cur->type){
                             case DESCRIPTOR_TYPE_SOCKET_CLIENT: {
                                 l_bytes_sent = send(l_cur->socket, (const char *)l_cur->buf_out,
@@ -736,7 +723,7 @@ void *dap_worker_thread(void *arg)
                                     l_es_w_data->esocket = l_cur;
                                     memcpy(&l_es_w_data->ptr, l_cur->buf_out,sizeof(l_cur));
                                     EV_SET(l_event,l_cur->socket, l_cur->kqueue_base_filter,l_cur->kqueue_base_flags, l_cur->kqueue_base_fflags,l_cur->kqueue_data, l_es_w_data);
-                                    int l_n = kevent(l_worker->kqueue_fd,l_event,1,NULL,0,NULL);
+                                    int l_n = kevent(a_context->kqueue_fd,l_event,1,NULL,0,NULL);
                                     if (l_n == 1){
                                         l_bytes_sent = sizeof(l_cur);
                                     }else{
@@ -818,18 +805,18 @@ void *dap_worker_thread(void *arg)
             {
                 if (l_cur->buf_out_size == 0) {
                     if(g_debug_reactor)
-                        log_it(L_INFO, "Process signal to close %s sock %"DAP_FORMAT_SOCKET" (ptr 0x%p uuid 0x%016"DAP_UINT64_FORMAT_x") type %d [thread %u]",
+                        log_it(L_INFO, "Process signal to close %s sock %"DAP_FORMAT_SOCKET" (ptr 0x%p uuid 0x%016"DAP_UINT64_FORMAT_x") type %d [context #%u]",
                            l_cur->remote_addr_str ? l_cur->remote_addr_str : "", l_cur->socket, l_cur, l_cur->uuid,
-                               l_cur->type, l_tn);
+                               l_cur->type, a_context->id);
 
                     for (ssize_t nn = n + 1; nn < l_sockets_max; nn++) { // Check for current selection if it has event duplication
                         dap_events_socket_t *l_es_selected = NULL;
 #ifdef DAP_EVENTS_CAPS_EPOLL
                         l_es_selected = (dap_events_socket_t *) l_epoll_events[nn].data.ptr;
 #elif defined ( DAP_EVENTS_CAPS_POLL)
-                        l_es_selected = l_worker->poll_esocket[nn];
+                        l_es_selected = a_context->poll_esocket[nn];
 #elif defined (DAP_EVENTS_CAPS_KQUEUE)
-                        struct kevent * l_kevent_selected = &l_worker->kqueue_events_selected[n];
+                        struct kevent * l_kevent_selected = &a_context->kqueue_events_selected[n];
                         if ( l_kevent_selected->filter == EVFILT_USER){ // If we have USER event it sends little different pointer
                             dap_events_socket_w_data_t * l_es_w_data = (dap_events_socket_w_data_t *) l_kevent_selected->udata;
                             l_es_selected = l_es_w_data->esocket;
@@ -851,21 +838,16 @@ void *dap_worker_thread(void *arg)
                     //dap_events_socket_remove_and_delete_unsafe( l_cur, false);
                     dap_events_remove_and_delete_socket_unsafe(dap_events_get_default(), l_cur, false);
 #ifdef DAP_EVENTS_CAPS_KQUEUE
-                    l_worker->kqueue_events_count--;
+                    a_context->kqueue_events_count--;
 #endif
                 } else if (l_cur->buf_out_size ) {
                     if(g_debug_reactor)
-                        log_it(L_INFO, "Got signal to close %s sock %"DAP_FORMAT_SOCKET" [thread %u] type %d but buffer is not empty(%zu)",
-                           l_cur->remote_addr_str ? l_cur->remote_addr_str : "", l_cur->socket, l_cur->type, l_tn,
+                        log_it(L_INFO, "Got signal to close %s sock %"DAP_FORMAT_SOCKET" [context #%u] type %d but buffer is not empty(%zu)",
+                           l_cur->remote_addr_str ? l_cur->remote_addr_str : "", l_cur->socket, l_cur->type, a_context->id,
                            l_cur->buf_out_size);
                 }
             }
 
-            if( l_worker->signal_exit){
-                log_it(L_ATT,"Worker :%u finished", l_worker->id);
-                return NULL;
-            }
-
         }
 #ifdef DAP_EVENTS_CAPS_POLL
         /***********************************************************/
@@ -873,313 +855,155 @@ void *dap_worker_thread(void *arg)
         /* to squeeze together the array and decrement the number  */
         /* of file descriptors.                                    */
         /***********************************************************/
-        if ( l_worker->poll_compress){
-            l_worker->poll_compress = false;
-            for (size_t i = 0; i < l_worker->poll_count ; i++)  {
-                if ( l_worker->poll[i].fd == -1){
-                    if( l_worker->poll_count){
-                        for(size_t j = i; j < l_worker->poll_count-1; j++){
-                             l_worker->poll[j].fd = l_worker->poll[j+1].fd;
-                             l_worker->poll[j].events = l_worker->poll[j+1].events;
-                             l_worker->poll[j].revents = l_worker->poll[j+1].revents;
-                             l_worker->poll_esocket[j] = l_worker->poll_esocket[j+1];
-                             if(l_worker->poll_esocket[j])
-                                 l_worker->poll_esocket[j]->poll_index = j;
+        if ( a_context->poll_compress){
+            a_context->poll_compress = false;
+            for (size_t i = 0; i < a_context->poll_count ; i++)  {
+                if ( a_context->poll[i].fd == -1){
+                    if( a_context->poll_count){
+                        for(size_t j = i; j < a_context->poll_count-1; j++){
+                             a_context->poll[j].fd = a_context->poll[j+1].fd;
+                             a_context->poll[j].events = a_context->poll[j+1].events;
+                             a_context->poll[j].revents = a_context->poll[j+1].revents;
+                             a_context->poll_esocket[j] = a_context->poll_esocket[j+1];
+                             if(a_context->poll_esocket[j])
+                                 a_context->poll_esocket[j]->poll_index = j;
                         }
                     }
                     i--;
-                    l_worker->poll_count--;
+                    a_context->poll_count--;
                 }
             }
         }
 #endif
-    } // while
-    log_it(L_NOTICE,"Exiting thread #%u", l_worker->id);
-    return NULL;
-}
-
-/**
- * @brief s_new_es_callback
- * @param a_es
- * @param a_arg
- */
-static void s_queue_add_es_callback( dap_events_socket_t * a_es, void * a_arg)
-{
-    dap_worker_t * l_worker = a_es->worker;
-    dap_events_socket_t * l_es_new =(dap_events_socket_t *) a_arg;
-    if (!l_es_new){
-        log_it(L_ERROR,"NULL esocket accepted to add on worker #%u", l_worker->id);
-        return;
-    }
-
-    if(g_debug_reactor)
-        log_it(L_NOTICE, "Received event socket %p (ident %"DAP_FORMAT_SOCKET" type %d) to add on worker", l_es_new, l_es_new->socket, l_es_new->type);
-
-    switch( l_es_new->type){
-        case DESCRIPTOR_TYPE_SOCKET_UDP: break;
-        case DESCRIPTOR_TYPE_SOCKET_CLIENT: break;
-        default:{}
-    }
-
-#ifdef DAP_EVENTS_CAPS_KQUEUE
-    if(l_es_new->socket!=0 && l_es_new->socket != -1 &&
-            l_es_new->type != DESCRIPTOR_TYPE_EVENT &&
-        l_es_new->type != DESCRIPTOR_TYPE_QUEUE &&
-        l_es_new->type != DESCRIPTOR_TYPE_TIMER
-            )
-#else
-    if(l_es_new->socket!=0 && l_es_new->socket != INVALID_SOCKET)
-
-#endif
-    if(dap_worker_esocket_find_uuid( l_worker, l_es_new->uuid)){
-        // Socket already present in worker, it's OK
-        return;
-    }
-
-    switch( l_es_new->type){
-
-        case DESCRIPTOR_TYPE_SOCKET_UDP:
-        case DESCRIPTOR_TYPE_SOCKET_CLIENT:
-        case DESCRIPTOR_TYPE_SOCKET_LISTENING:{
-
-#ifdef DAP_OS_UNIX
-#if defined (SO_INCOMING_CPU)
-            int l_cpu = l_worker->id;
-            setsockopt(l_es_new->socket , SOL_SOCKET, SO_INCOMING_CPU, &l_cpu, sizeof(l_cpu));
-#endif
-#endif
-        } break;
-        default: {}
-    }
-
-    l_es_new->worker = l_worker;
-    l_es_new->last_time_active = time(NULL);
-    // We need to differ new and reassigned esockets. If its new - is_initialized is false
-    if ( ! l_es_new->is_initalized ){
-        if (l_es_new->callbacks.new_callback)
-            l_es_new->callbacks.new_callback(l_es_new, NULL);
-        l_es_new->is_initalized = true;
-    }
-
-    int l_ret = dap_worker_add_events_socket_unsafe(l_es_new,l_worker);
-    if (  l_ret != 0 ){
-        log_it(L_CRITICAL,"Can't add event socket's handler to worker i/o poll mechanism with error %d", errno);
-    }else{
-        // Add in worker
-        l_es_new->me = l_es_new;
-        if (l_es_new->socket!=0 && l_es_new->socket != INVALID_SOCKET){
-            pthread_rwlock_wrlock(&l_worker->esocket_rwlock);
-            HASH_ADD(hh_worker, l_worker->esockets, uuid, sizeof(l_es_new->uuid), l_es_new );
-            l_worker->event_sockets_count++;
-            pthread_rwlock_unlock(&l_worker->esocket_rwlock);
-        }
-        //log_it(L_DEBUG, "Added socket %d on worker %u", l_es_new->socket, w->id);
-        if (l_es_new->callbacks.worker_assign_callback)
-            l_es_new->callbacks.worker_assign_callback(l_es_new, l_worker);
+    } while(!a_context->signal_exit);
 
-    }
+    log_it(L_ATT,"Context :%u finished", a_context->id);
+    return 0;
 }
 
-/**
- * @brief s_delete_es_callback
- * @param a_es
- * @param a_arg
- */
-static void s_queue_delete_es_callback( dap_events_socket_t * a_es, void * a_arg)
-{
-    assert(a_arg);
-    dap_events_socket_uuid_t * l_es_uuid_ptr = (dap_events_socket_uuid_t*) a_arg;
-    dap_events_socket_t * l_es;
-    if ( (l_es = dap_worker_esocket_find_uuid(a_es->worker,*l_es_uuid_ptr)) != NULL ){
-        //l_es->flags |= DAP_SOCK_SIGNAL_CLOSE; // Send signal to socket to kill
-        dap_events_socket_remove_and_delete_unsafe(l_es,false);
-    }else
-        log_it(L_INFO, "While we were sending the delete() message, esocket %"DAP_UINT64_FORMAT_U" has been disconnected ", *l_es_uuid_ptr);
-    DAP_DELETE(l_es_uuid_ptr);
-}
 
 /**
- * @brief s_reassign_es_callback
- * @param a_es
- * @param a_arg
+ * @brief dap_context_poll_update
+ * @param a_esocket
  */
-static void s_queue_es_reassign_callback( dap_events_socket_t * a_es, void * a_arg)
+int dap_context_poll_update(dap_events_socket_t * a_esocket)
 {
-    assert(a_es);
-    dap_worker_t * l_worker = a_es->worker;
-    assert(l_worker);
-    dap_worker_msg_reassign_t * l_msg = (dap_worker_msg_reassign_t*) a_arg;
-    assert(l_msg);
-    dap_events_socket_t * l_es_reassign;
-    if ( ( l_es_reassign = dap_worker_esocket_find_uuid(l_worker, l_msg->esocket_uuid))!= NULL ){
-        if( l_es_reassign->was_reassigned && l_es_reassign->flags & DAP_SOCK_REASSIGN_ONCE) {
-            log_it(L_INFO, "Reassgment request with DAP_SOCK_REASSIGN_ONCE allowed only once, declined reassigment from %u to %u",
-                   l_es_reassign->worker->id, l_msg->worker_new->id);
+    #if defined (DAP_EVENTS_CAPS_EPOLL)
+        int events = a_esocket->ev_base_flags | EPOLLERR;
 
-        }else{
-            dap_events_socket_reassign_between_workers_unsafe(l_es_reassign,l_msg->worker_new);
-        }
-    }else{
-        log_it(L_INFO, "While we were sending the reassign message, esocket %p has been disconnected", l_msg->esocket);
-    }
-    DAP_DELETE(l_msg);
-}
+        // Check & add
+        if( a_esocket->flags & DAP_SOCK_READY_TO_READ )
+            events |= EPOLLIN;
 
-/**
- * @brief s_queue_callback
- * @param a_es
- * @param a_arg
- */
-static void s_queue_callback_callback( dap_events_socket_t * a_es, void * a_arg)
-{
-    dap_worker_msg_callback_t * l_msg = (dap_worker_msg_callback_t *) a_arg;
-    assert(l_msg);
-    assert(l_msg->callback);
-    l_msg->callback(a_es->worker, l_msg->arg);
-    DAP_DELETE(l_msg);
-}
+        if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING )
+            events |= EPOLLOUT;
 
-/**
- * @brief s_event_exit_callback
- * @param a_es
- * @param a_flags
- */
-static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags)
-{
-    (void) a_flags;
-    a_es->worker->signal_exit = true;
-    if(g_debug_reactor)
-        log_it(L_DEBUG, "Worker :%u signaled to exit", a_es->worker->id);
-}
-
-/**
- * @brief s_pipe_data_out_read_callback
- * @param a_es
- * @param a_arg
- */
-static void s_queue_es_io_callback( dap_events_socket_t * a_es, void * a_arg)
-{
-    assert(a_es);
-    dap_worker_t * l_worker = a_es->worker;
-    dap_worker_msg_io_t * l_msg = a_arg;
-    assert(l_msg);
-    // Check if it was removed from the list
-    dap_events_socket_t *l_msg_es = dap_worker_esocket_find_uuid(l_worker, l_msg->esocket_uuid);
-    if ( l_msg_es == NULL){
-        log_it(L_INFO, "We got i/o message for esocket %"DAP_UINT64_FORMAT_U" thats now not in list. Lost %zu data", l_msg->esocket_uuid, l_msg->data_size);
-        DAP_DELETE(l_msg);
-        return;
-    }
+        a_esocket->ev.events = events;
 
-    if (l_msg->flags_set & DAP_SOCK_CONNECTING)
-        if (!  (l_msg_es->flags & DAP_SOCK_CONNECTING) ){
-            l_msg_es->flags |= DAP_SOCK_CONNECTING;
-            dap_events_socket_worker_poll_update_unsafe(l_msg_es);
+        if( a_esocket->context){
+            if ( epoll_ctl(a_esocket->context->epoll_fd, EPOLL_CTL_MOD, a_esocket->socket, &a_esocket->ev) ){
+#ifdef DAP_OS_WINDOWS
+                int l_errno = WSAGetLastError();
+#else
+                int l_errno = errno;
+#endif
+                char l_errbuf[128];
+                l_errbuf[0]=0;
+                strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
+                log_it(L_ERROR,"Can't update client socket state in the epoll_fd %"DAP_FORMAT_HANDLE": \"%s\" (%d)",
+                       a_esocket->context->epoll_fd, l_errbuf, l_errno);
+                return l_errno;
+            }
         }
-
-    if (l_msg->flags_set & DAP_SOCK_CONNECTING)
-        if (!  (l_msg_es->flags & DAP_SOCK_CONNECTING) ){
-            l_msg_es->flags ^= DAP_SOCK_CONNECTING;
-            dap_events_socket_worker_poll_update_unsafe(l_msg_es);
+    #elif defined (DAP_EVENTS_CAPS_POLL)
+        if( a_esocket->context && a_esocket->is_initalized){
+            if (a_esocket->poll_index < a_esocket->context->poll_count ){
+                struct pollfd * l_poll = &a_esocket->context->poll[a_esocket->poll_index];
+                l_poll->events = a_esocket->poll_base_flags | POLLERR ;
+                // Check & add
+                if( a_esocket->flags & DAP_SOCK_READY_TO_READ )
+                    l_poll->events |= POLLIN;
+                if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING )
+                    l_poll->events |= POLLOUT;
+            }else{
+                log_it(L_ERROR, "Wrong poll index when remove from context (unsafe): %u when total count %u", a_esocket->poll_index,
+                       a_esocket->context->poll_count);
+                return -666;
+            }
+        }
+    #elif defined (DAP_EVENTS_CAPS_KQUEUE)
+    if (a_esocket->socket != -1  ){ // Not everything we add in poll
+        struct kevent * l_event = &a_esocket->kqueue_event;
+        short l_filter  =a_esocket->kqueue_base_filter;
+        u_short l_flags =a_esocket->kqueue_base_flags;
+        u_int l_fflags =a_esocket->kqueue_base_fflags;
+
+        int l_kqueue_fd = a_esocket->context? a_esocket->context->kqueue_fd : -1;
+        if ( l_kqueue_fd == -1 ){
+            log_it(L_ERROR, "Esocket is not assigned with anything ,exit");
+            return -667;
         }
 
-    if (l_msg->flags_set & DAP_SOCK_READY_TO_READ)
-        dap_events_socket_set_readable_unsafe(l_msg_es, true);
-    if (l_msg->flags_unset & DAP_SOCK_READY_TO_READ)
-        dap_events_socket_set_readable_unsafe(l_msg_es, false);
-    if (l_msg->flags_set & DAP_SOCK_READY_TO_WRITE)
-        dap_events_socket_set_writable_unsafe(l_msg_es, true);
-    if (l_msg->flags_unset & DAP_SOCK_READY_TO_WRITE)
-        dap_events_socket_set_writable_unsafe(l_msg_es, false);
-    if (l_msg->data_size && l_msg->data) {
-        dap_events_socket_write_unsafe(l_msg_es, l_msg->data,l_msg->data_size);
-        DAP_DELETE(l_msg->data);
-    }
-    DAP_DELETE(l_msg);
-}
-
-/**
- * @brief s_socket_all_check_activity
- * @param a_arg
- */
-static bool s_socket_all_check_activity( void * a_arg)
-{
-    dap_worker_t *l_worker = (dap_worker_t*) a_arg;
-    assert(l_worker);
-    dap_events_socket_t *l_es = NULL, *tmp = NULL;
-    char l_curtimebuf[64];
-    time_t l_curtime= time(NULL);
-    //dap_ctime_r(&l_curtime, l_curtimebuf);
-    //log_it(L_DEBUG,"Check sockets activity on worker #%u at %s", l_worker->id, l_curtimebuf);
-    pthread_rwlock_rdlock(&l_worker->esocket_rwlock);
-    HASH_ITER(hh_worker, l_worker->esockets, l_es, tmp ) {
-        pthread_rwlock_unlock(&l_worker->esocket_rwlock);
-        if (l_es->type == DESCRIPTOR_TYPE_SOCKET_CLIENT){
-            if ( !(l_es->flags & DAP_SOCK_SIGNAL_CLOSE) &&
-                 (  l_curtime >=  (l_es->last_time_active + s_connection_timeout) ) && !l_es->no_close ) {
-                log_it( L_INFO, "Socket %"DAP_FORMAT_SOCKET" timeout (diff %"DAP_UINT64_FORMAT_U" ), closing...",
-                                l_es->socket, l_curtime -  (time_t)l_es->last_time_active - s_connection_timeout );
-                if (l_es->callbacks.error_callback) {
-                    l_es->callbacks.error_callback(l_es, ETIMEDOUT);
+        // Check & add
+        bool l_is_error=false;
+        int l_errno=0;
+        if (a_esocket->type == DESCRIPTOR_TYPE_EVENT ){
+            EV_SET(l_event, a_esocket->socket, EVFILT_USER,EV_ADD| EV_CLEAR ,0,0, &a_esocket->kqueue_event_catched_data );
+            if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
+                l_is_error = true;
+                l_errno = errno;
+            }
+        }else{
+            EV_SET(l_event, a_esocket->socket, l_filter,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
+            if( a_esocket->flags & DAP_SOCK_READY_TO_READ ){
+                EV_SET(l_event, a_esocket->socket, EVFILT_READ,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
+                if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1 ){
+                    l_is_error = true;
+                    l_errno = errno;
+                }
+            }
+            if( !l_is_error){
+                if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING ){
+                    EV_SET(l_event, a_esocket->socket, EVFILT_WRITE,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
+                    if(kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
+                        l_is_error = true;
+                        l_errno = errno;
+                    }
                 }
-                dap_events_socket_remove_and_delete_unsafe(l_es,false);
             }
         }
-        pthread_rwlock_rdlock(&l_worker->esocket_rwlock);
-    }
-    pthread_rwlock_unlock(&l_worker->esocket_rwlock);
-    return true;
-}
+        if (l_is_error && l_errno == EBADF){
+            log_it(L_ATT,"Poll update: socket %d (%p ) disconnected, rise CLOSE flag to remove from queue, lost %"DAP_UINT64_FORMAT_U":%" DAP_UINT64_FORMAT_U
+                         " bytes",a_esocket->socket,a_esocket,a_esocket->buf_in_size,a_esocket->buf_out_size);
+            a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
+            a_esocket->buf_in_size = a_esocket->buf_out_size = 0; // Reset everything from buffer, we close it now all
+        }else if ( l_is_error && l_errno != EINPROGRESS && l_errno != ENOENT){
+            char l_errbuf[128];
+            l_errbuf[0]=0;
+            strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
+            log_it(L_ERROR,"Can't update client socket state on kqueue fd %d: \"%s\" (%d)",
+                l_kqueue_fd, l_errbuf, l_errno);
+            return l_errno;
+        }
+     }
 
-/**
- * @brief sap_worker_add_events_socket
- * @param a_events_socket
- * @param a_worker
- */
-void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker)
-{
-/*
-#ifdef DAP_EVENTS_CAPS_KQUEUE
-    a_events_socket->worker = a_worker;
-    if(dap_worker_add_events_socket_unsafe(a_events_socket, a_worker)!=0)
-        a_events_socket->worker = NULL;
-
-#else*/
-    if(g_debug_reactor)
-        log_it(L_DEBUG,"Worker add esocket %"DAP_FORMAT_SOCKET, a_events_socket->socket);
-    int l_ret = dap_events_socket_queue_ptr_send( a_worker->queue_es_new, a_events_socket );
-    if(l_ret != 0 ){
-        char l_errbuf[128];
-        *l_errbuf = 0;
-        strerror_r(l_ret, l_errbuf, sizeof(l_errbuf));
-        log_it(L_ERROR, "Can't send pointer in queue: \"%s\"(code %d)", l_errbuf, l_ret);
-    }
-//#endif
+    #else
+    #error "Not defined dap_events_socket_set_writable_unsafe for your platform"
+    #endif
+    return 0;
 }
 
-/**
- * @brief dap_worker_add_events_socket_inter
- * @param a_es_input
- * @param a_events_socket
- */
-void dap_worker_add_events_socket_inter(dap_events_socket_t * a_es_input, dap_events_socket_t * a_events_socket)
-{
-    if( dap_events_socket_queue_ptr_send_to_input( a_es_input, a_events_socket ) != 0 ){
-        int l_errno = errno;
-        char l_errbuf[128];
-        *l_errbuf = 0;
-        strerror_r(l_errno,l_errbuf,sizeof (l_errbuf));
-        log_it(L_ERROR, "Cant send pointer to interthread queue input: \"%s\"(code %d)", l_errbuf, l_errno);
-    }
-}
 
 /**
- * @brief dap_worker_add_events_socket_unsafe
- * @param a_worker
+ * @brief dap_context_add_events_socket_unsafe
+ * @param IOa_context
  * @param a_esocket
  */
-int dap_worker_add_events_socket_unsafe( dap_events_socket_t * a_esocket, dap_worker_t * a_worker )
+int dap_context_add_esocket(dap_context_t * a_context, dap_events_socket_t * a_esocket )
 {
+    if(a_context == NULL || a_esocket == NULL)
+        return -1;
+
     if(g_debug_reactor){
         log_it(L_DEBUG,"Add event socket %p (socket %"DAP_FORMAT_SOCKET")", a_esocket, a_esocket->socket);
     }
@@ -1191,41 +1015,45 @@ int dap_worker_add_events_socket_unsafe( dap_events_socket_t * a_esocket, dap_wo
         if(a_esocket->flags & DAP_SOCK_READY_TO_WRITE )
             a_esocket->ev.events |= EPOLLOUT;
         a_esocket->ev.data.ptr = a_esocket;
-        return epoll_ctl(a_worker->epoll_fd, EPOLL_CTL_ADD, a_esocket->socket, &a_esocket->ev);
+        a_esocket->context = a_context;
+        return epoll_ctl(a_context->epoll_fd, EPOLL_CTL_ADD, a_esocket->socket, &a_esocket->ev);
 #elif defined (DAP_EVENTS_CAPS_POLL)
-    if (  a_worker->poll_count == a_worker->poll_count_max ){ // realloc
-        a_worker->poll_count_max *= 2;
-        log_it(L_WARNING, "Too many descriptors (%u), resizing array twice to %zu", a_worker->poll_count, a_worker->poll_count_max);
-        a_worker->poll =DAP_REALLOC(a_worker->poll, a_worker->poll_count_max * sizeof(*a_worker->poll));
-        a_worker->poll_esocket =DAP_REALLOC(a_worker->poll_esocket, a_worker->poll_count_max * sizeof(*a_worker->poll_esocket));
+    if (  a_context->poll_count == a_context->poll_count_max ){ // realloc
+        a_context->poll_count_max *= 2;
+        log_it(L_WARNING, "Too many descriptors (%u), resizing array twice to %zu", a_context->poll_count, a_context->poll_count_max);
+        a_context->poll =DAP_REALLOC(a_context->poll, a_context->poll_count_max * sizeof(*a_context->poll));
+        a_context->poll_esocket =DAP_REALLOC(a_context->poll_esocket, a_context->poll_count_max * sizeof(*a_context->poll_esocket));
     }
-    a_worker->poll[a_worker->poll_count].fd = a_esocket->socket;
-    a_esocket->poll_index = a_worker->poll_count;
-    a_worker->poll[a_worker->poll_count].events = a_esocket->poll_base_flags;
+    a_context->poll[a_context->poll_count].fd = a_esocket->socket;
+    a_esocket->poll_index = a_context->poll_count;
+    a_context->poll[a_context->poll_count].events = a_esocket->poll_base_flags;
     if( a_esocket->flags & DAP_SOCK_READY_TO_READ )
-        a_worker->poll[a_worker->poll_count].events |= POLLIN;
+        a_context->poll[a_context->poll_count].events |= POLLIN;
     if( (a_esocket->flags & DAP_SOCK_READY_TO_WRITE) || (a_esocket->flags & DAP_SOCK_CONNECTING) )
-        a_worker->poll[a_worker->poll_count].events |= POLLOUT;
+        a_context->poll[a_context->poll_count].events |= POLLOUT;
 
 
-    a_worker->poll_esocket[a_worker->poll_count] = a_esocket;
-    a_worker->poll_count++;
+    a_context->poll_esocket[a_context->poll_count] = a_esocket;
+    a_context->poll_count++;
+    a_esocket->context = a_context;
     return 0;
 #elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    a_esocket->worker = a_worker;
     if ( a_esocket->type == DESCRIPTOR_TYPE_QUEUE ){
+        a_esocket->context = a_context;
         return 0;
     }
     if ( a_esocket->type == DESCRIPTOR_TYPE_EVENT && a_esocket->pipe_out){
+        a_esocket->context = a_context;
         return 0;
     }
     struct kevent l_event;
     u_short l_flags = a_esocket->kqueue_base_flags;
     u_int   l_fflags = a_esocket->kqueue_base_fflags;
     short l_filter = a_esocket->kqueue_base_filter;
-    int l_kqueue_fd =a_worker->kqueue_fd;
+    int l_kqueue_fd =a_context->kqueue_fd;
     if ( l_kqueue_fd == -1 ){
         log_it(L_ERROR, "Esocket is not assigned with anything ,exit");
+        return -1;
     }
     // Check & add
     bool l_is_error=false;
@@ -1277,48 +1105,427 @@ int dap_worker_add_events_socket_unsafe( dap_events_socket_t * a_esocket, dap_wo
         log_it(L_ERROR,"Can't update client socket state on kqueue fd %d: \"%s\" (%d)",
             a_esocket->socket, l_errbuf, l_errno);
         return l_errno;
-    }else
+    }else{
+        a_esocket->context = a_context;
         return 0;
-
+    }
 #else
-#error "Unimplemented new esocket on worker callback for current platform"
+#error "Unimplemented new esocket on context callback for current platform"
 #endif
 
 }
 
+
 /**
- * @brief dap_worker_exec_callback_on
+ * @brief dap_context_esocket_find_by_uuid
+ * @param a_context
+ * @param a_es_uuid
+ * @return
  */
-void dap_worker_exec_callback_on(dap_worker_t * a_worker, dap_worker_callback_t a_callback, void * a_arg)
+dap_events_socket_t *dap_context_esocket_find_by_uuid(dap_context_t * a_context, dap_events_socket_uuid_t a_es_uuid )
 {
-    dap_worker_msg_callback_t * l_msg = DAP_NEW_Z(dap_worker_msg_callback_t);
-    l_msg->callback = a_callback;
-    l_msg->arg = a_arg;
-    int l_ret=dap_events_socket_queue_ptr_send( a_worker->queue_callback,l_msg );
-    if(l_ret != 0 ){
-        char l_errbuf[128];
-        *l_errbuf = 0;
-        strerror_r(l_ret,l_errbuf,sizeof (l_errbuf));
-        log_it(L_ERROR, "Cant send pointer in queue: \"%s\"(code %d)", l_errbuf, l_ret);
+    if(a_context == NULL){
+        log_it(L_ERROR, "Worker is NULL, can't fund esocket by UUID");
+        return NULL;
     }
-
+    dap_events_socket_t * l_ret = NULL;
+    if(a_context->esockets ) {
+        //HASH_FIND_PTR( a_worker->context->esockets, &a_es_uuid,l_ret );
+        HASH_FIND(hh_worker, a_context->esockets, &a_es_uuid, sizeof(a_es_uuid), l_ret );
+    }
+    return l_ret;
 }
 
+/**
+ * @brief dap_context_create_esocket_queue
+ * @param a_context
+ * @param a_callback
+ * @return
+ */
+ dap_events_socket_t * dap_context_create_esocket_queue(dap_context_t * a_context, dap_events_socket_callback_queue_ptr_t a_callback)
+{
+    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t);
+    if(!l_es){
+        log_it(L_ERROR,"Can't allocate esocket!");
+        return NULL;
+    }
+
+    l_es->type = DESCRIPTOR_TYPE_QUEUE;
+    l_es->flags =  DAP_SOCK_QUEUE_PTR;
+    l_es->uuid = dap_uuid_generate_uint64();
+
+    l_es->callbacks.queue_ptr_callback = a_callback; // Arm event callback
+    l_es->buf_in_size_max = DAP_QUEUE_MAX_MSGS * sizeof(void*);
+    l_es->buf_in = DAP_NEW_Z_SIZE(byte_t,l_es->buf_in_size_max);
+    l_es->buf_out = NULL;
+
+#if defined(DAP_EVENTS_CAPS_EPOLL)
+    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
+#elif defined(DAP_EVENTS_CAPS_POLL)
+    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
+#elif defined(DAP_EVENTS_CAPS_KQUEUE)
+    l_es->kqueue_event_catched_data.esocket = l_es;
+    l_es->kqueue_base_flags =  EV_CLEAR;
+    l_es->kqueue_base_fflags = 0;
+    l_es->kqueue_base_filter = EVFILT_USER;
+    l_es->socket = arc4random();
+#else
+#error "Not defined s_create_type_queue_ptr for your platform"
+#endif
+
+
+#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2) || defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
+    int l_pipe[2];
+    l_errbuf[0]=0;
+#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2)
+    if( pipe2(l_pipe,O_DIRECT | O_NONBLOCK ) < 0 ){
+#elif defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
+    if( pipe(l_pipe) < 0 ){
+#endif
+        l_errno = errno;
+        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
+        switch (l_errno) {
+            case EINVAL: log_it(L_CRITICAL, "Too old linux version thats doesn't support O_DIRECT flag for pipes (%s)", l_errbuf); break;
+            default: log_it( L_ERROR, "Error detected, can't create pipe(): '%s' (%d)", l_errbuf, l_errno);
+        }
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+    //else
+     //   log_it(L_DEBUG, "Created one-way unnamed packet pipe %d->%d", l_pipe[0], l_pipe[1]);
+    l_es->fd = l_pipe[0];
+    l_es->fd2 = l_pipe[1];
+
+#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
+    // If we have no pipe2() we should set nonblock mode via fcntl
+    if (l_es->fd > 0 && l_es->fd2 > 0 ) {
+    int l_flags = fcntl(l_es->fd, F_GETFL, 0);
+    if (l_flags != -1){
+        l_flags |= O_NONBLOCK);
+        fcntl(l_es->fd, F_SETFL, l_flags) == 0);
+    }
+    l_flags = fcntl(l_es->fd2, F_GETFL, 0);
+    if (l_flags != -1){
+        l_flags |= O_NONBLOCK);
+        fcntl(l_es->fd2, F_SETFL, l_flags) == 0);
+    }
+    }
+#endif
+
+#if !defined (DAP_OS_ANDROID)
+    FILE* l_sys_max_pipe_size_fd = fopen("/proc/sys/fs/pipe-max-size", "r");
+    if (l_sys_max_pipe_size_fd) {
+        const int l_file_buf_size = 64;
+        char l_file_buf[l_file_buf_size];
+        memset(l_file_buf, 0, l_file_buf_size);
+        fread(l_file_buf, l_file_buf_size, 1, l_sys_max_pipe_size_fd);
+        uint64_t l_sys_max_pipe_size = strtoull(l_file_buf, 0, 10);
+        fcntl(l_pipe[0], F_SETPIPE_SZ, l_sys_max_pipe_size);
+        fclose(l_sys_max_pipe_size_fd);
+    }
+#endif
+
+#elif defined (DAP_EVENTS_CAPS_QUEUE_MQUEUE)
+    int  l_errno;
+    char l_errbuf[128] = {0}, l_mq_name[64] = {0};
+    struct mq_attr l_mq_attr;
+    static atomic_uint l_mq_last_number = 0;
+
+
+    l_mq_attr.mq_maxmsg = DAP_QUEUE_MAX_MSGS;                               // Don't think we need to hold more than 1024 messages
+    l_mq_attr.mq_msgsize = sizeof (void*);                                  // We send only pointer on memory (???!!!),
+                                                                            // so use it with shared memory if you do access from another process
+
+    l_es->mqd_id = atomic_fetch_add( &l_mq_last_number, 1);
+    snprintf(l_mq_name,sizeof (l_mq_name), "/%s-queue_ptr-%u", dap_get_appname(), l_es->mqd_id );
+    // if ( (l_errno = mq_unlink(l_mq_name)) )                                 /* Mark this MQ to be deleted as the process will be terminated */
+    //    log_it(L_DEBUG, "mq_unlink(%s)->%d", l_mq_name, l_errno);
+
+    if ( 0 >= (l_es->mqd = mq_open(l_mq_name, O_CREAT|O_RDWR |O_NONBLOCK, 0700, &l_mq_attr)) )
+    {
+        log_it(L_CRITICAL,"Can't create mqueue descriptor %s: \"%s\" code %d (%s)", l_mq_name, l_errbuf, errno,
+                           (strerror_r(errno, l_errbuf, sizeof (l_errbuf)), l_errbuf) );
+
+        DAP_DELETE(l_es->buf_in);
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+
+#elif defined DAP_EVENTS_CAPS_MSMQ
+    l_es->socket        = socket(AF_INET, SOCK_DGRAM, 0);
+
+    if (l_es->socket == INVALID_SOCKET) {
+        log_it(L_ERROR, "Error creating socket for TYPE_QUEUE: %d", WSAGetLastError());
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+
+    int buffsize = 1024;
+    setsockopt(l_es->socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
+
+    int reuse = 1;
+    if (setsockopt(l_es->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
+        log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket, err: %d", WSAGetLastError());
+
+    unsigned long l_mode = 1;
+    ioctlsocket(l_es->socket, FIONBIO, &l_mode);
+
+    int l_addr_len;
+    struct sockaddr_in l_addr;
+    l_addr.sin_family = AF_INET;
+    IN_ADDR _in_addr = { { .S_addr = htonl(INADDR_LOOPBACK) } };
+    l_addr.sin_addr = _in_addr;
+    l_addr.sin_port = 0; //l_es->socket  + 32768;
+    l_addr_len = sizeof(struct sockaddr_in);
+
+    if (bind(l_es->socket, (struct sockaddr*)&l_addr, sizeof(l_addr)) < 0) {
+        log_it(L_ERROR, "Bind error: %d", WSAGetLastError());
+    } else {
+        int dummy = 100;
+        getsockname(l_es->socket, (struct sockaddr*)&l_addr, &dummy);
+        l_es->port = l_addr.sin_port;
+        //log_it(L_DEBUG, "Bound to port %d", l_addr.sin_port);
+    }
+
+    MQQUEUEPROPS   l_qps;
+    MQPROPVARIANT  l_qp_var[1];
+    QUEUEPROPID    l_qp_id[1];
+    HRESULT        l_q_status[1];
+
+    WCHAR l_pathname[MQ_MAX_Q_NAME_LEN - 10] = { 0 };
+    static atomic_uint s_queue_num = 0;
+    int pos = 0;
+#ifdef DAP_BRAND
+    pos = _snwprintf_s(l_pathname, sizeof(l_pathname)/sizeof(l_pathname[0]), _TRUNCATE, L".\\PRIVATE$\\" DAP_BRAND "mq%d", l_es->mq_num = s_queue_num++);
+#else
+    pos = _snwprintf_s(l_pathname, sizeof(l_pathname)/sizeof(l_pathname[0]), _TRUNCATE, L".\\PRIVATE$\\%hs_esmq%d", dap_get_appname(), l_es->mq_num = s_queue_num++);
+#endif
+    if (pos < 0) {
+        log_it(L_ERROR, "Message queue path error");
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+    u_long l_p_id         = 0;
+    l_qp_id[l_p_id]       = PROPID_Q_PATHNAME;
+    l_qp_var[l_p_id].vt   = VT_LPWSTR;
+    l_qp_var[l_p_id].pwszVal = l_pathname;
+    l_p_id++;
+
+    l_qps.cProp     = l_p_id;
+    l_qps.aPropID   = l_qp_id;
+    l_qps.aPropVar  = l_qp_var;
+    l_qps.aStatus   = l_q_status;
+
+    WCHAR l_direct_name[MQ_MAX_Q_NAME_LEN]      = { 0 };
+    WCHAR l_format_name[sizeof(l_direct_name) - 10] = { 0 };
+    DWORD l_buflen = sizeof(l_format_name);
+    HRESULT hr = MQCreateQueue(NULL, &l_qps, l_format_name, &l_buflen);
+    if ((hr != MQ_OK) && (hr != MQ_ERROR_QUEUE_EXISTS) && (hr != MQ_INFORMATION_PROPERTY)) {
+        log_it(L_ERROR, "Can't create message queue for queue type, error: %ld", hr);
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+    _snwprintf_s(l_direct_name, sizeof(l_direct_name)/sizeof(l_direct_name[0]), _TRUNCATE, L"DIRECT=OS:%ls", l_pathname);
+
+    hr = MQOpenQueue(l_direct_name, MQ_SEND_ACCESS, MQ_DENY_NONE, &(l_es->mqh));
+    if (hr == MQ_ERROR_QUEUE_NOT_FOUND) {
+        log_it(L_INFO, "Queue still not created, wait a bit...");
+        Sleep(300);
+        hr = MQOpenQueue(l_direct_name, MQ_SEND_ACCESS, MQ_DENY_NONE, &(l_es->mqh));
+        if (hr != MQ_OK) {
+            log_it(L_ERROR, "Can't open message queue for queue type, error: %ld", hr);
+            DAP_DELETE(l_es);
+            MQDeleteQueue(l_format_name);
+            return NULL;
+        }
+    }
+    hr = MQOpenQueue(l_direct_name, MQ_RECEIVE_ACCESS, MQ_DENY_NONE, &(l_es->mqh_recv));
+    if (hr != MQ_OK) {
+        log_it(L_ERROR, "Can't open message queue for queue type, error: %ld", hr);
+        DAP_DELETE(l_es);
+        MQCloseQueue(l_es->mqh);
+        MQDeleteQueue(l_format_name);
+        return NULL;
+    }
+    hr = MQPurgeQueue(l_es->mqh_recv);
+    if (hr != MQ_OK) {
+        log_it(L_DEBUG, "Message queue %u NOT purged, possible data corruption, err %ld", l_es->mq_num, hr);
+    }
+#elif defined (DAP_EVENTS_CAPS_KQUEUE)
+    // We don't create descriptor for kqueue at all
+#else
+#error "Not implemented s_create_type_queue_ptr() on your platform"
+#endif
+
+    if ( a_context) {
+        if(dap_context_add_esocket(a_context, l_es)) {
+#ifdef DAP_OS_WINDOWS
+            errno = WSAGetLastError();
+#endif
+            log_it(L_ERROR, "Can't add esocket %"DAP_FORMAT_SOCKET" to polling, err %d", l_es->socket, errno);
+        }
+    }
+
+    return l_es;
+}
 
 /**
- * @brief dap_worker_add_events_socket
- * @param a_worker
- * @param a_events_socket
+ * @brief s_create_type_event
+ * @param a_context
+ * @param a_callback
+ * @return
  */
-dap_worker_t *dap_worker_add_events_socket_auto( dap_events_socket_t *a_es)
+dap_events_socket_t * dap_context_create_esocket_event(dap_context_t * a_context, dap_events_socket_callback_event_t a_callback)
 {
-//  struct epoll_event ev = {0};
-  dap_worker_t *l_worker = dap_events_worker_get_auto( );
+    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t); if (!l_es) return NULL;
+    l_es->buf_out_size_max = l_es->buf_in_size_max = 1;
+    l_es->buf_out = DAP_NEW_Z_SIZE(byte_t, l_es->buf_out_size_max);
+    l_es->type = DESCRIPTOR_TYPE_EVENT;
+    l_es->uuid = dap_uuid_generate_uint64();
+
+    l_es->callbacks.event_callback = a_callback; // Arm event callback
+#if defined(DAP_EVENTS_CAPS_EPOLL)
+    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
+#elif defined(DAP_EVENTS_CAPS_POLL)
+    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
+#elif defined(DAP_EVENTS_CAPS_KQUEUE)
+    l_es->kqueue_base_flags =  EV_CLEAR;
+    l_es->kqueue_base_filter = EVFILT_USER;
+    l_es->socket = arc4random();
+    l_es->kqueue_event_catched_data.esocket = l_es;
+#else
+#error "Not defined s_create_type_event for your platform"
+#endif
 
-  a_es->events = l_worker->events;
-  dap_worker_add_events_socket( a_es, l_worker);
-  return l_worker;
+#ifdef DAP_EVENTS_CAPS_EVENT_EVENTFD
+    if((l_es->fd = eventfd(0,EFD_NONBLOCK) ) < 0 ){
+        int l_errno = errno;
+        char l_errbuf[128];
+        l_errbuf[0]=0;
+        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
+        switch (l_errno) {
+            case EINVAL: log_it(L_CRITICAL, "An unsupported value was specified in flags: \"%s\" (%d)", l_errbuf, l_errno); break;
+            case EMFILE: log_it(L_CRITICAL, "The per-process limit on the number of open file descriptors has been reached: \"%s\" (%d)", l_errbuf, l_errno); break;
+            case ENFILE: log_it(L_CRITICAL, "The system-wide limit on the total number of open files has been reached: \"%s\" (%d)", l_errbuf, l_errno); break;
+            case ENODEV: log_it(L_CRITICAL, "Could not mount (internal) anonymous inode device: \"%s\" (%d)", l_errbuf, l_errno); break;
+            case ENOMEM: log_it(L_CRITICAL, "There was insufficient memory to create a new eventfd file descriptor: \"%s\" (%d)", l_errbuf, l_errno); break;
+            default: log_it( L_ERROR, "Error detected, can't create eventfd: '%s' (%d)", l_errbuf, l_errno);
+        }
+        DAP_DELETE(l_es);
+        return NULL;
+    }else {
+        l_es->fd2 = l_es->fd;
+        //log_it(L_DEBUG, "Created eventfd descriptor %d", l_es->fd );
+    }
+#elif defined DAP_OS_WINDOWS
+
+
+    l_es->socket        = socket(AF_INET, SOCK_DGRAM, 0);
+
+    if (l_es->socket == INVALID_SOCKET) {
+        log_it(L_ERROR, "Error creating socket for TYPE_QUEUE: %d", WSAGetLastError());
+        DAP_DELETE(l_es);
+        return NULL;
+    }
+
+    int buffsize = 1024;
+    setsockopt(l_es->socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
+
+    unsigned long l_mode = 1;
+    ioctlsocket(l_es->socket, FIONBIO, &l_mode);
+
+    int reuse = 1;
+    if (setsockopt(l_es->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
+        log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket, err: %d", WSAGetLastError());
+
+    int l_addr_len;
+    struct sockaddr_in l_addr;
+    l_addr.sin_family = AF_INET;
+    IN_ADDR _in_addr = { { .S_addr = htonl(INADDR_LOOPBACK) } };
+    l_addr.sin_addr = _in_addr;
+    l_addr.sin_port = 0; //l_es->socket + 32768;
+    l_addr_len = sizeof(struct sockaddr_in);
+
+    if (bind(l_es->socket, (struct sockaddr*)&l_addr, sizeof(l_addr)) < 0) {
+        log_it(L_ERROR, "Bind error: %d", WSAGetLastError());
+    } else {
+        int dummy = 100;
+        getsockname(l_es->socket, (struct sockaddr*)&l_addr, &dummy);
+        l_es->port = l_addr.sin_port;
+        //log_it(L_DEBUG, "Bound to port %d", l_addr.sin_port);
+    }
+#elif defined(DAP_EVENTS_CAPS_KQUEUE)
+    // nothing to do
+#else
+#error "Not defined dap_context_create_esocket_event() on your platform"
+#endif
+    if(a_context)
+        dap_context_add_esocket(a_context,l_es);
+    return l_es;
 }
 
 
+/**
+ * @brief dap_context_create_esocket_pipe
+ * @param a_context
+ * @param a_callback
+ * @param a_flags
+ * @return
+ */
+dap_events_socket_t * dap_context_create_esocket_pipe(dap_context_t * a_context, dap_events_socket_callback_t a_callback, uint32_t a_flags)
+{
+#ifdef DAP_OS_WINDOWS
+    UNUSED(a_w);
+    UNUSED(a_callback);
+    UNUSED(a_flags);
+    return NULL;
+#else
+    UNUSED(a_flags);
+    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t);
+    l_es->type = DESCRIPTOR_TYPE_PIPE;
+    l_es->uuid = dap_uuid_generate_uint64();
+    l_es->callbacks.read_callback = a_callback; // Arm event callback
+#if defined(DAP_EVENTS_CAPS_EPOLL)
+    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
+#elif defined(DAP_EVENTS_CAPS_POLL)
+    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
+#elif defined(DAP_EVENTS_CAPS_KQUEUE)
+    l_es->kqueue_event_catched_data.esocket = l_es;
+    l_es->kqueue_base_flags = EV_ENABLE | EV_CLEAR;
+    l_es->kqueue_base_fflags = NOTE_DELETE | NOTE_REVOKE ;
+#if !defined(DAP_OS_DARWIN)
+    l_es->kqueue_base_fflags |= NOTE_CLOSE | NOTE_CLOSE_WRITE ;
+#endif
+    l_es->kqueue_base_filter = EVFILT_VNODE;
+#else
+#error "Not defined s_create_type_pipe for your platform"
+#endif
+
+#if defined(DAP_EVENTS_CAPS_PIPE_POSIX)
+    int l_pipe[2];
+    int l_errno;
+    char l_errbuf[128];
+    l_errbuf[0]=0;
+    if( pipe(l_pipe) < 0 ){
+        l_errno = errno;
+        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
+        log_it( L_ERROR, "Error detected, can't create pipe(): '%s' (%d)", l_errbuf, l_errno);
+        DAP_DELETE(l_es);
+        return NULL;
+    }//else
+     //   log_it(L_DEBUG, "Created one-way unnamed bytestream pipe %d->%d", l_pipe[0], l_pipe[1]);
+    l_es->fd = l_pipe[0];
+    l_es->fd2 = l_pipe[1];
+#if defined DAP_OS_UNIX
+    fcntl( l_pipe[0], F_SETFL, O_NONBLOCK);
+    fcntl( l_pipe[1], F_SETFL, O_NONBLOCK);
+    // this sort of fd doesn't suit ioctlsocket()...
+#endif
 
+#else
+#error "No defined s_create_type_pipe() for your platform"
+#endif
+    dap_context_add_esocket(a_context,l_es);
+    return l_es;
+#endif
+}
diff --git a/dap-sdk/net/core/dap_events.c b/dap-sdk/io/dap_events.c
similarity index 98%
rename from dap-sdk/net/core/dap_events.c
rename to dap-sdk/io/dap_events.c
index 25a4d7fbeaf6e2ac83d8f79f19b53d0244276edd..64f75ff883f7997c0b5106ba434b2715ae07bddb 100644
--- a/dap-sdk/net/core/dap_events.c
+++ b/dap-sdk/io/dap_events.c
@@ -93,6 +93,7 @@ typedef cpuset_t cpu_set_t; // Adopt BSD CPU setstructure to POSIX variant
 #include "dap_strfuncs.h"
 #include "dap_server.h"
 #include "dap_events.h"
+#include "dap_context.h"
 #include "dap_events_socket.h"
 #include "dap_proc_thread.h"
 #include "dap_config.h"
@@ -223,6 +224,12 @@ int dap_events_init( uint32_t a_threads_count, size_t a_conn_timeout )
     if ( !s_workers || !s_threads )
         return -1;
 
+    if(dap_context_init() != 0){
+        log_it( L_CRITICAL, "Can't init client submodule dap_context( )" );
+        goto err;
+
+    }
+
     dap_worker_init(a_conn_timeout);
     if ( dap_events_socket_init() != 0 ) {
         log_it( L_CRITICAL, "Can't init client submodule dap_events_socket_init( )" );
@@ -333,8 +340,8 @@ int dap_events_start( dap_events_t *a_events )
 
         l_worker->id = i;
         l_worker->events = a_events;
-        l_worker->esockets = NULL;
-        pthread_rwlock_init(&l_worker->esocket_rwlock,NULL);
+        l_worker->context = dap_context_new();
+        l_worker->context->worker = l_worker;
         pthread_mutex_init(& l_worker->started_mutex, NULL);
         pthread_cond_init( & l_worker->started_cond, NULL);
 
diff --git a/dap-sdk/net/core/dap_events_socket.c b/dap-sdk/io/dap_events_socket.c
similarity index 69%
rename from dap-sdk/net/core/dap_events_socket.c
rename to dap-sdk/io/dap_events_socket.c
index 7dc6f1fe619fa29244046321e9417134b129de1d..7ea684c7282c11731e7f0177963ae8cb6f5fbc96 100644
--- a/dap-sdk/net/core/dap_events_socket.c
+++ b/dap-sdk/io/dap_events_socket.c
@@ -85,6 +85,7 @@ typedef cpuset_t cpu_set_t; // Adopt BSD CPU setstructure to POSIX variant
 #include "dap_events.h"
 
 #include "dap_timerfd.h"
+#include "dap_context.h"
 #include "dap_events_socket.h"
 
 #define LOG_TAG "dap_events_socket"
@@ -192,7 +193,6 @@ dap_events_socket_t *dap_events_socket_wrap_no_add( dap_events_t *a_events,
         return NULL;
 
     l_ret->socket = a_sock;
-    l_ret->events = a_events;
     l_ret->uuid = dap_uuid_generate_uint64();
     if (a_callbacks)
         memcpy(&l_ret->callbacks, a_callbacks, sizeof(l_ret->callbacks) );
@@ -254,7 +254,7 @@ void dap_events_socket_assign_on_worker_inter(dap_events_socket_t * a_es_input,
  */
 void dap_events_socket_reassign_between_workers_unsafe(dap_events_socket_t * a_es, dap_worker_t * a_worker_new)
 {
-    dap_worker_t * l_worker = a_es->worker;
+    dap_worker_t * l_worker = a_es->context->worker;
     dap_events_socket_t * l_queue_input= l_worker->queue_es_new_input[a_worker_new->id];
     log_it(L_DEBUG, "Reassign between %u->%u workers: %p (%d)  ", l_worker->id, a_worker_new->id, a_es, a_es->fd );
 
@@ -288,71 +288,7 @@ void dap_events_socket_reassign_between_workers_mt(dap_worker_t * a_worker_old,
     }
 }
 
-/**
- * @brief s_create_type_pipe
- * @param a_w
- * @param a_callback
- * @param a_flags
- * @return
- */
-dap_events_socket_t * s_create_type_pipe(dap_worker_t * a_w, dap_events_socket_callback_t a_callback, uint32_t a_flags)
-{
-#ifdef DAP_OS_WINDOWS
-    UNUSED(a_w);
-    UNUSED(a_callback);
-    UNUSED(a_flags);
-    return NULL;
-#else
-    UNUSED(a_flags);
-    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t);
-    l_es->type = DESCRIPTOR_TYPE_PIPE;
-    l_es->worker = a_w;
-    l_es->events = a_w->events;
-    l_es->uuid = dap_uuid_generate_uint64();
-    l_es->callbacks.read_callback = a_callback; // Arm event callback
-#if defined(DAP_EVENTS_CAPS_EPOLL)
-    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
-#elif defined(DAP_EVENTS_CAPS_POLL)
-    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
-#elif defined(DAP_EVENTS_CAPS_KQUEUE)
-    l_es->kqueue_event_catched_data.esocket = l_es;
-    l_es->kqueue_base_flags = EV_ENABLE | EV_CLEAR;
-    l_es->kqueue_base_fflags = NOTE_DELETE | NOTE_REVOKE ;
-#if !defined(DAP_OS_DARWIN)
-    l_es->kqueue_base_fflags |= NOTE_CLOSE | NOTE_CLOSE_WRITE ;
-#endif
-    l_es->kqueue_base_filter = EVFILT_VNODE;
-#else
-#error "Not defined s_create_type_pipe for your platform"
-#endif
-
-#if defined(DAP_EVENTS_CAPS_PIPE_POSIX)
-    int l_pipe[2];
-    int l_errno;
-    char l_errbuf[128];
-    l_errbuf[0]=0;
-    if( pipe(l_pipe) < 0 ){
-        l_errno = errno;
-        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-        log_it( L_ERROR, "Error detected, can't create pipe(): '%s' (%d)", l_errbuf, l_errno);
-        DAP_DELETE(l_es);
-        return NULL;
-    }//else
-     //   log_it(L_DEBUG, "Created one-way unnamed bytestream pipe %d->%d", l_pipe[0], l_pipe[1]);
-    l_es->fd = l_pipe[0];
-    l_es->fd2 = l_pipe[1];
-#if defined DAP_OS_UNIX
-    fcntl( l_pipe[0], F_SETFL, O_NONBLOCK);
-    fcntl( l_pipe[1], F_SETFL, O_NONBLOCK);
-    // this sort of fd doesn't suit ioctlsocket()...
-#endif
 
-#else
-#error "No defined s_create_type_pipe() for your platform"
-#endif
-    return l_es;
-#endif
-}
 
 /**
  * @brief dap_events_socket_create_type_pipe_mt
@@ -363,7 +299,7 @@ dap_events_socket_t * s_create_type_pipe(dap_worker_t * a_w, dap_events_socket_c
  */
 dap_events_socket_t * dap_events_socket_create_type_pipe_mt(dap_worker_t * a_w, dap_events_socket_callback_t a_callback, uint32_t a_flags)
 {
-    dap_events_socket_t * l_es = s_create_type_pipe(a_w, a_callback, a_flags);
+    dap_events_socket_t * l_es = dap_context_create_esocket_pipe(NULL, a_callback, a_flags);
     dap_worker_add_events_socket_unsafe(l_es,a_w);
     return  l_es;
 }
@@ -433,7 +369,7 @@ dap_events_socket_t * dap_events_socket_create(dap_events_desc_type_t a_type, da
  */
 dap_events_socket_t * dap_events_socket_create_type_pipe_unsafe(dap_worker_t * a_w, dap_events_socket_callback_t a_callback, uint32_t a_flags)
 {
-    dap_events_socket_t * l_es = s_create_type_pipe(a_w, a_callback, a_flags);
+    dap_events_socket_t * l_es = dap_context_create_esocket_pipe(NULL, a_callback, a_flags);
     dap_worker_add_events_socket_unsafe(l_es,a_w);
     return  l_es;
 }
@@ -470,7 +406,6 @@ dap_events_socket_t * dap_events_socket_queue_ptr_create_input(dap_events_socket
     l_es->buf_in_size_max = DAP_QUEUE_MAX_MSGS * sizeof(void*);
     l_es->buf_in       = DAP_NEW_Z_SIZE(byte_t,l_es->buf_in_size_max );
     //l_es->buf_out_size  = 8 * sizeof(void*);
-    l_es->events = a_es->events;
     l_es->uuid = dap_uuid_generate_uint64();
 #if defined(DAP_EVENTS_CAPS_EPOLL)
     l_es->ev_base_flags = EPOLLERR | EPOLLRDHUP | EPOLLHUP;
@@ -566,232 +501,6 @@ dap_events_socket_t * dap_events_socket_queue_ptr_create_input(dap_events_socket
     return l_es;
 }
 
-/**
- * @brief s_create_type_queue
- * @param a_w
- * @param a_flags
- * @return
- */
-dap_events_socket_t * s_create_type_queue_ptr(dap_worker_t * a_w, dap_events_socket_callback_queue_ptr_t a_callback)
-{
-    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t);
-    if(!l_es){
-        log_it(L_ERROR,"Can't allocate esocket!");
-        return NULL;
-    }
-
-    l_es->type = DESCRIPTOR_TYPE_QUEUE;
-    l_es->flags =  DAP_SOCK_QUEUE_PTR;
-    l_es->uuid = dap_uuid_generate_uint64();
-    if (a_w){
-        l_es->events = a_w->events;
-        l_es->worker = a_w;
-    }
-
-    l_es->callbacks.queue_ptr_callback = a_callback; // Arm event callback
-    l_es->buf_in_size_max = DAP_QUEUE_MAX_MSGS * sizeof(void*);
-    l_es->buf_in = DAP_NEW_Z_SIZE(byte_t,l_es->buf_in_size_max);
-    l_es->buf_out = NULL;
-
-#if defined(DAP_EVENTS_CAPS_EPOLL)
-    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
-#elif defined(DAP_EVENTS_CAPS_POLL)
-    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
-#elif defined(DAP_EVENTS_CAPS_KQUEUE)
-    l_es->kqueue_event_catched_data.esocket = l_es;
-    l_es->kqueue_base_flags =  EV_CLEAR;
-    l_es->kqueue_base_fflags = 0;
-    l_es->kqueue_base_filter = EVFILT_USER;
-    l_es->socket = arc4random();
-#else
-#error "Not defined s_create_type_queue_ptr for your platform"
-#endif
-
-
-#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2) || defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
-    int l_pipe[2];
-    l_errbuf[0]=0;
-#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2)
-    if( pipe2(l_pipe,O_DIRECT | O_NONBLOCK ) < 0 ){
-#elif defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
-    if( pipe(l_pipe) < 0 ){
-#endif
-        l_errno = errno;
-        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-        switch (l_errno) {
-            case EINVAL: log_it(L_CRITICAL, "Too old linux version thats doesn't support O_DIRECT flag for pipes (%s)", l_errbuf); break;
-            default: log_it( L_ERROR, "Error detected, can't create pipe(): '%s' (%d)", l_errbuf, l_errno);
-        }
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-    //else
-     //   log_it(L_DEBUG, "Created one-way unnamed packet pipe %d->%d", l_pipe[0], l_pipe[1]);
-    l_es->fd = l_pipe[0];
-    l_es->fd2 = l_pipe[1];
-
-#if defined(DAP_EVENTS_CAPS_QUEUE_PIPE)
-    // If we have no pipe2() we should set nonblock mode via fcntl
-    if (l_es->fd > 0 && l_es->fd2 > 0 ) {
-    int l_flags = fcntl(l_es->fd, F_GETFL, 0);
-    if (l_flags != -1){
-        l_flags |= O_NONBLOCK);
-        fcntl(l_es->fd, F_SETFL, l_flags) == 0);
-    }
-    l_flags = fcntl(l_es->fd2, F_GETFL, 0);
-    if (l_flags != -1){
-        l_flags |= O_NONBLOCK);
-        fcntl(l_es->fd2, F_SETFL, l_flags) == 0);
-    }
-    }
-#endif
-
-#if !defined (DAP_OS_ANDROID)
-    FILE* l_sys_max_pipe_size_fd = fopen("/proc/sys/fs/pipe-max-size", "r");
-    if (l_sys_max_pipe_size_fd) {
-        const int l_file_buf_size = 64;
-        char l_file_buf[l_file_buf_size];
-        memset(l_file_buf, 0, l_file_buf_size);
-        fread(l_file_buf, l_file_buf_size, 1, l_sys_max_pipe_size_fd);
-        uint64_t l_sys_max_pipe_size = strtoull(l_file_buf, 0, 10);
-        fcntl(l_pipe[0], F_SETPIPE_SZ, l_sys_max_pipe_size);
-        fclose(l_sys_max_pipe_size_fd);
-    }
-#endif
-
-#elif defined (DAP_EVENTS_CAPS_QUEUE_MQUEUE)
-    int  l_errno;
-    char l_errbuf[128] = {0}, l_mq_name[64] = {0};
-    struct mq_attr l_mq_attr;
-    static atomic_uint l_mq_last_number = 0;
-
-
-    l_mq_attr.mq_maxmsg = DAP_QUEUE_MAX_MSGS;                               // Don't think we need to hold more than 1024 messages
-    l_mq_attr.mq_msgsize = sizeof (void*);                                  // We send only pointer on memory (???!!!),
-                                                                            // so use it with shared memory if you do access from another process
-
-    l_es->mqd_id = atomic_fetch_add( &l_mq_last_number, 1);
-    snprintf(l_mq_name,sizeof (l_mq_name), "/%s-queue_ptr-%u", dap_get_appname(), l_es->mqd_id );
-    // if ( (l_errno = mq_unlink(l_mq_name)) )                                 /* Mark this MQ to be deleted as the process will be terminated */
-    //    log_it(L_DEBUG, "mq_unlink(%s)->%d", l_mq_name, l_errno);
-
-    if ( 0 >= (l_es->mqd = mq_open(l_mq_name, O_CREAT|O_RDWR |O_NONBLOCK, 0700, &l_mq_attr)) )
-    {
-        log_it(L_CRITICAL,"Can't create mqueue descriptor %s: \"%s\" code %d (%s)", l_mq_name, l_errbuf, errno,
-                           (strerror_r(errno, l_errbuf, sizeof (l_errbuf)), l_errbuf) );
-
-        DAP_DELETE(l_es->buf_in);
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-
-#elif defined DAP_EVENTS_CAPS_MSMQ
-    l_es->socket        = socket(AF_INET, SOCK_DGRAM, 0);
-
-    if (l_es->socket == INVALID_SOCKET) {
-        log_it(L_ERROR, "Error creating socket for TYPE_QUEUE: %d", WSAGetLastError());
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-
-    int buffsize = 1024;
-    setsockopt(l_es->socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
-
-    int reuse = 1;
-    if (setsockopt(l_es->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
-        log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket, err: %d", WSAGetLastError());
-
-    unsigned long l_mode = 1;
-    ioctlsocket(l_es->socket, FIONBIO, &l_mode);
-
-    int l_addr_len;
-    struct sockaddr_in l_addr;
-    l_addr.sin_family = AF_INET;
-    IN_ADDR _in_addr = { { .S_addr = htonl(INADDR_LOOPBACK) } };
-    l_addr.sin_addr = _in_addr;
-    l_addr.sin_port = 0; //l_es->socket  + 32768;
-    l_addr_len = sizeof(struct sockaddr_in);
-
-    if (bind(l_es->socket, (struct sockaddr*)&l_addr, sizeof(l_addr)) < 0) {
-        log_it(L_ERROR, "Bind error: %d", WSAGetLastError());
-    } else {
-        int dummy = 100;
-        getsockname(l_es->socket, (struct sockaddr*)&l_addr, &dummy);
-        l_es->port = l_addr.sin_port;
-        //log_it(L_DEBUG, "Bound to port %d", l_addr.sin_port);
-    }
-
-    MQQUEUEPROPS   l_qps;
-    MQPROPVARIANT  l_qp_var[1];
-    QUEUEPROPID    l_qp_id[1];
-    HRESULT        l_q_status[1];
-
-    WCHAR l_pathname[MQ_MAX_Q_NAME_LEN - 10] = { 0 };
-    static atomic_uint s_queue_num = 0;
-    int pos = 0;
-#ifdef DAP_BRAND
-    pos = _snwprintf_s(l_pathname, sizeof(l_pathname)/sizeof(l_pathname[0]), _TRUNCATE, L".\\PRIVATE$\\" DAP_BRAND "mq%d", l_es->mq_num = s_queue_num++);
-#else
-    pos = _snwprintf_s(l_pathname, sizeof(l_pathname)/sizeof(l_pathname[0]), _TRUNCATE, L".\\PRIVATE$\\%hs_esmq%d", dap_get_appname(), l_es->mq_num = s_queue_num++);
-#endif
-    if (pos < 0) {
-        log_it(L_ERROR, "Message queue path error");
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-    u_long l_p_id         = 0;
-    l_qp_id[l_p_id]       = PROPID_Q_PATHNAME;
-    l_qp_var[l_p_id].vt   = VT_LPWSTR;
-    l_qp_var[l_p_id].pwszVal = l_pathname;
-    l_p_id++;
-
-    l_qps.cProp     = l_p_id;
-    l_qps.aPropID   = l_qp_id;
-    l_qps.aPropVar  = l_qp_var;
-    l_qps.aStatus   = l_q_status;
-
-    WCHAR l_direct_name[MQ_MAX_Q_NAME_LEN]      = { 0 };
-    WCHAR l_format_name[sizeof(l_direct_name) - 10] = { 0 };
-    DWORD l_buflen = sizeof(l_format_name);
-    HRESULT hr = MQCreateQueue(NULL, &l_qps, l_format_name, &l_buflen);
-    if ((hr != MQ_OK) && (hr != MQ_ERROR_QUEUE_EXISTS) && (hr != MQ_INFORMATION_PROPERTY)) {
-        log_it(L_ERROR, "Can't create message queue for queue type, error: %ld", hr);
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-    _snwprintf_s(l_direct_name, sizeof(l_direct_name)/sizeof(l_direct_name[0]), _TRUNCATE, L"DIRECT=OS:%ls", l_pathname);
-
-    hr = MQOpenQueue(l_direct_name, MQ_SEND_ACCESS, MQ_DENY_NONE, &(l_es->mqh));
-    if (hr == MQ_ERROR_QUEUE_NOT_FOUND) {
-        log_it(L_INFO, "Queue still not created, wait a bit...");
-        Sleep(300);
-        hr = MQOpenQueue(l_direct_name, MQ_SEND_ACCESS, MQ_DENY_NONE, &(l_es->mqh));
-        if (hr != MQ_OK) {
-            log_it(L_ERROR, "Can't open message queue for queue type, error: %ld", hr);
-            DAP_DELETE(l_es);
-            MQDeleteQueue(l_format_name);
-            return NULL;
-        }
-    }
-    hr = MQOpenQueue(l_direct_name, MQ_RECEIVE_ACCESS, MQ_DENY_NONE, &(l_es->mqh_recv));
-    if (hr != MQ_OK) {
-        log_it(L_ERROR, "Can't open message queue for queue type, error: %ld", hr);
-        DAP_DELETE(l_es);
-        MQCloseQueue(l_es->mqh);
-        MQDeleteQueue(l_format_name);
-        return NULL;
-    }
-    hr = MQPurgeQueue(l_es->mqh_recv);
-    if (hr != MQ_OK) {
-        log_it(L_DEBUG, "Message queue %u NOT purged, possible data corruption, err %ld", l_es->mq_num, hr);
-    }
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    // We don't create descriptor for kqueue at all
-#else
-#error "Not implemented s_create_type_queue_ptr() on your platform"
-#endif
-    return l_es;
-}
 
 /**
  * @brief dap_events_socket_create_type_queue_mt
@@ -802,7 +511,7 @@ dap_events_socket_t * s_create_type_queue_ptr(dap_worker_t * a_w, dap_events_soc
  */
 dap_events_socket_t * dap_events_socket_create_type_queue_ptr_mt(dap_worker_t * a_w, dap_events_socket_callback_queue_ptr_t a_callback)
 {
-    dap_events_socket_t * l_es = s_create_type_queue_ptr(a_w, a_callback);
+    dap_events_socket_t * l_es = dap_context_create_esocket_queue(NULL, a_callback);
     assert(l_es);
     // If no worker - don't assign
     if ( a_w)
@@ -811,28 +520,6 @@ dap_events_socket_t * dap_events_socket_create_type_queue_ptr_mt(dap_worker_t *
 }
 
 
-/**
- * @brief dap_events_socket_create_type_queue
- * @param a_w
- * @param a_callback
- * @return
- */
-dap_events_socket_t * dap_events_socket_create_type_queue_ptr_unsafe(dap_worker_t * a_w, dap_events_socket_callback_queue_ptr_t a_callback)
-{
-    dap_events_socket_t * l_es = s_create_type_queue_ptr(a_w, a_callback);
-    assert(l_es);
-    // If no worker - don't assign
-    if ( a_w) {
-        if(dap_worker_add_events_socket_unsafe(l_es,a_w)) {
-#ifdef DAP_OS_WINDOWS
-            errno = WSAGetLastError();
-#endif
-            log_it(L_ERROR, "Can't add esocket %"DAP_FORMAT_SOCKET" to polling, err %d", l_es->socket, errno);
-        }
-    }
-    return  l_es;
-}
-
 /**
  * @brief dap_events_socket_queue_proc_input
  * @param a_esocket
@@ -919,7 +606,7 @@ int dap_events_socket_queue_proc_input_unsafe(dap_events_socket_t * a_esocket)
         void * l_queue_ptr = a_esocket->kqueue_event_catched_data.data;
         size_t l_queue_ptr_size = a_esocket->kqueue_event_catched_data.size;
         if(g_debug_reactor)
-            log_it(L_INFO,"Queue received %z bytes on input", l_queue_ptr_size);
+            log_it(L_INFO,"Queue received %zd bytes on input", l_queue_ptr_size);
 
         a_esocket->callbacks.queue_callback(a_esocket, l_queue_ptr, l_queue_ptr_size);
 #else
@@ -933,101 +620,6 @@ int dap_events_socket_queue_proc_input_unsafe(dap_events_socket_t * a_esocket)
     return 0;
 }
 
-/**
- * @brief s_create_type_event
- * @param a_w
- * @param a_callback
- * @return
- */
-dap_events_socket_t * s_create_type_event(dap_worker_t * a_w, dap_events_socket_callback_event_t a_callback)
-{
-    dap_events_socket_t * l_es = DAP_NEW_Z(dap_events_socket_t); if (!l_es) return NULL;
-    l_es->buf_out_size_max = l_es->buf_in_size_max = 1;
-    l_es->buf_out = DAP_NEW_Z_SIZE(byte_t, l_es->buf_out_size_max);
-    l_es->type = DESCRIPTOR_TYPE_EVENT;
-    l_es->uuid = dap_uuid_generate_uint64();
-    if (a_w){
-        l_es->events = a_w->events;
-        l_es->worker = a_w;
-    }
-    l_es->callbacks.event_callback = a_callback; // Arm event callback
-#if defined(DAP_EVENTS_CAPS_EPOLL)
-    l_es->ev_base_flags = EPOLLIN | EPOLLERR | EPOLLRDHUP | EPOLLHUP;
-#elif defined(DAP_EVENTS_CAPS_POLL)
-    l_es->poll_base_flags = POLLIN | POLLERR | POLLRDHUP | POLLHUP;
-#elif defined(DAP_EVENTS_CAPS_KQUEUE)
-    l_es->kqueue_base_flags =  EV_CLEAR;
-    l_es->kqueue_base_filter = EVFILT_USER;
-    l_es->socket = arc4random();
-    l_es->kqueue_event_catched_data.esocket = l_es;
-#else
-#error "Not defined s_create_type_event for your platform"
-#endif
-
-#ifdef DAP_EVENTS_CAPS_EVENT_EVENTFD
-    if((l_es->fd = eventfd(0,EFD_NONBLOCK) ) < 0 ){
-        int l_errno = errno;
-        char l_errbuf[128];
-        l_errbuf[0]=0;
-        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-        switch (l_errno) {
-            case EINVAL: log_it(L_CRITICAL, "An unsupported value was specified in flags: \"%s\" (%d)", l_errbuf, l_errno); break;
-            case EMFILE: log_it(L_CRITICAL, "The per-process limit on the number of open file descriptors has been reached: \"%s\" (%d)", l_errbuf, l_errno); break;
-            case ENFILE: log_it(L_CRITICAL, "The system-wide limit on the total number of open files has been reached: \"%s\" (%d)", l_errbuf, l_errno); break;
-            case ENODEV: log_it(L_CRITICAL, "Could not mount (internal) anonymous inode device: \"%s\" (%d)", l_errbuf, l_errno); break;
-            case ENOMEM: log_it(L_CRITICAL, "There was insufficient memory to create a new eventfd file descriptor: \"%s\" (%d)", l_errbuf, l_errno); break;
-            default: log_it( L_ERROR, "Error detected, can't create eventfd: '%s' (%d)", l_errbuf, l_errno);
-        }
-        DAP_DELETE(l_es);
-        return NULL;
-    }else {
-        l_es->fd2 = l_es->fd;
-        //log_it(L_DEBUG, "Created eventfd descriptor %d", l_es->fd );
-    }
-#elif defined DAP_OS_WINDOWS
-
-
-    l_es->socket        = socket(AF_INET, SOCK_DGRAM, 0);
-
-    if (l_es->socket == INVALID_SOCKET) {
-        log_it(L_ERROR, "Error creating socket for TYPE_QUEUE: %d", WSAGetLastError());
-        DAP_DELETE(l_es);
-        return NULL;
-    }
-
-    int buffsize = 1024;
-    setsockopt(l_es->socket, SOL_SOCKET, SO_RCVBUF, (char *)&buffsize, sizeof(int));
-
-    unsigned long l_mode = 1;
-    ioctlsocket(l_es->socket, FIONBIO, &l_mode);
-
-    int reuse = 1;
-    if (setsockopt(l_es->socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0)
-        log_it(L_WARNING, "Can't set up REUSEADDR flag to the socket, err: %d", WSAGetLastError());
-
-    int l_addr_len;
-    struct sockaddr_in l_addr;
-    l_addr.sin_family = AF_INET;
-    IN_ADDR _in_addr = { { .S_addr = htonl(INADDR_LOOPBACK) } };
-    l_addr.sin_addr = _in_addr;
-    l_addr.sin_port = 0; //l_es->socket + 32768;
-    l_addr_len = sizeof(struct sockaddr_in);
-
-    if (bind(l_es->socket, (struct sockaddr*)&l_addr, sizeof(l_addr)) < 0) {
-        log_it(L_ERROR, "Bind error: %d", WSAGetLastError());
-    } else {
-        int dummy = 100;
-        getsockname(l_es->socket, (struct sockaddr*)&l_addr, &dummy);
-        l_es->port = l_addr.sin_port;
-        //log_it(L_DEBUG, "Bound to port %d", l_addr.sin_port);
-    }
-#elif defined(DAP_EVENTS_CAPS_KQUEUE)
-    // nothing to do
-#else
-#error "Not defined s_create_type_event() on your platform"
-#endif
-    return l_es;
-}
 
 /**
  * @brief dap_events_socket_create_type_event_mt
@@ -1037,7 +629,7 @@ dap_events_socket_t * s_create_type_event(dap_worker_t * a_w, dap_events_socket_
  */
 dap_events_socket_t * dap_events_socket_create_type_event_mt(dap_worker_t * a_w, dap_events_socket_callback_event_t a_callback)
 {
-    dap_events_socket_t * l_es = s_create_type_event(a_w, a_callback);
+    dap_events_socket_t * l_es = dap_context_create_esocket_event(NULL, a_callback);
     // If no worker - don't assign
     if ( a_w)
         dap_events_socket_assign_on_worker_mt(l_es,a_w);
@@ -1052,7 +644,8 @@ dap_events_socket_t * dap_events_socket_create_type_event_mt(dap_worker_t * a_w,
  */
 dap_events_socket_t * dap_events_socket_create_type_event_unsafe(dap_worker_t * a_w, dap_events_socket_callback_event_t a_callback)
 {
-    dap_events_socket_t * l_es = s_create_type_event(a_w, a_callback);
+
+    dap_events_socket_t * l_es = dap_context_create_esocket_event(NULL, a_callback);
     // If no worker - don't assign
     if ( a_w)
         dap_worker_add_events_socket_unsafe(l_es,a_w);
@@ -1236,10 +829,8 @@ int dap_events_socket_queue_ptr_send_to_input(dap_events_socket_t * a_es_input,
         l_es_w_data->esocket = l_es;
         l_es_w_data->ptr = a_arg;
         EV_SET(&l_event,a_es_input->socket+arc4random()  , EVFILT_USER,EV_ADD | EV_CLEAR | EV_ONESHOT, NOTE_FFCOPY | NOTE_TRIGGER ,0, l_es_w_data);
-        if(l_es->worker)
-            l_ret=kevent(l_es->worker->kqueue_fd,&l_event,1,NULL,0,NULL);
-        else if (l_es->proc_thread)
-            l_ret=kevent(l_es->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
+        if(l_es->context)
+            l_ret=kevent(l_es->context->kqueue_fd,&l_event,1,NULL,0,NULL);
         else
             l_ret=-100;
         if(l_ret != -1 ){
@@ -1274,7 +865,7 @@ int dap_events_socket_queue_ptr_send_to_input(dap_events_socket_t * a_es_input,
  */
 int dap_events_socket_queue_ptr_send( dap_events_socket_t *a_es, void *a_arg)
 {
-    int l_ret = -1024, l_errno;
+    int l_ret = -1024, l_errno=0;
 
     if (g_debug_reactor)
         log_it(L_DEBUG,"Sent ptr %p to esocket queue %p (%d)", a_arg, a_es, a_es? a_es->fd : -1);
@@ -1295,7 +886,7 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t *a_es, void *a_arg)
     if (l_errno == EINVAL || l_errno == EINTR || l_errno == ETIMEDOUT)
         l_errno = EAGAIN;
     if (l_ret == 0)
-        l_ret = sizeof (a_arg);
+        l_ret = 0;
     else if (l_ret > 0)
         l_ret = -l_ret;
 
@@ -1352,24 +943,18 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t *a_es, void *a_arg)
     EV_SET(&l_event,a_es->socket+arc4random()  , EVFILT_USER,EV_ADD | EV_CLEAR | EV_ONESHOT, NOTE_FFCOPY | NOTE_TRIGGER ,0, l_es_w_data);
     int l_n;
     if(a_es->pipe_out){ // If we have pipe out - we send events directly to the pipe out kqueue fd
-        if(a_es->pipe_out->worker){
+        if(a_es->pipe_out->context){
             if( g_debug_reactor) log_it(L_DEBUG, "Sent kevent() with ptr %p to pipe_out worker on esocket %d",a_arg,a_es);
-            l_n = kevent(a_es->pipe_out->worker->kqueue_fd,&l_event,1,NULL,0,NULL);
-        }else if (a_es->pipe_out->proc_thread){
-            l_n = kevent(a_es->pipe_out->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
-            if( g_debug_reactor) log_it(L_DEBUG, "Sent kevent() with ptr %p to pipe_out proc_thread on esocket %d",a_arg,a_es);
+            l_n = kevent(a_es->pipe_out->context->kqueue_fd,&l_event,1,NULL,0,NULL);
         }
         else {
             log_it(L_WARNING,"Trying to send pointer in pipe out queue thats not assigned to any worker or proc thread");
             l_n = 0;
             DAP_DELETE(l_es_w_data);
         }
-    }else if(a_es->worker){
-        l_n = kevent(a_es->worker->kqueue_fd,&l_event,1,NULL,0,NULL);
+    }else if(a_es->context){
+        l_n = kevent(a_es->context->kqueue_fd,&l_event,1,NULL,0,NULL);
         if( g_debug_reactor) log_it(L_DEBUG, "Sent kevent() with ptr %p to worker on esocket %d",a_arg,a_es);
-    }else if (a_es->proc_thread){
-        l_n = kevent(a_es->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
-        if( g_debug_reactor) log_it(L_DEBUG, "Sent kevent() with ptr %p to proc_thread on esocket %d",a_arg,a_es);
     }else {
         log_it(L_WARNING,"Trying to send pointer in queue thats not assigned to any worker or proc thread");
         l_n = 0;
@@ -1377,7 +962,7 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t *a_es, void *a_arg)
     }
 
     if(l_n != -1 ){
-        return sizeof(a_arg);
+        return 0;
     }else{
         l_errno = errno;
         log_it(L_ERROR,"Sending kevent error code %d", l_errno);
@@ -1438,19 +1023,15 @@ int dap_events_socket_event_signal( dap_events_socket_t * a_es, uint64_t a_value
     int l_n;
 
     if(a_es->pipe_out){ // If we have pipe out - we send events directly to the pipe out kqueue fd
-        if(a_es->pipe_out->worker)
-            l_n = kevent(a_es->pipe_out->worker->kqueue_fd,&l_event,1,NULL,0,NULL);
-        else if (a_es->pipe_out->proc_thread)
-            l_n = kevent(a_es->pipe_out->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
+        if(a_es->pipe_out->context)
+            l_n = kevent(a_es->pipe_out->context->kqueue_fd,&l_event,1,NULL,0,NULL);
         else {
             log_it(L_WARNING,"Trying to send pointer in pipe out queue thats not assigned to any worker or proc thread");
             l_n = -1;
         }
-    }else if(a_es->worker)
-        l_n = kevent(a_es->worker->kqueue_fd,&l_event,1,NULL,0,NULL);
-    else if (a_es->proc_thread)
-        l_n = kevent(a_es->proc_thread->kqueue_fd,&l_event,1,NULL,0,NULL);
-    else
+    }else if(a_es->context)
+        l_n = kevent(a_es->context->kqueue_fd,&l_event,1,NULL,0,NULL);
+     else
         l_n = -1;
 
     if(l_n == -1){
@@ -1467,12 +1048,12 @@ int dap_events_socket_event_signal( dap_events_socket_t * a_es, uint64_t a_value
  * @brief dap_events_socket_queue_on_remove_and_delete
  * @param a_es
  */
-void dap_events_socket_queue_on_remove_and_delete(dap_events_socket_t* a_es)
+void dap_events_socket_delete_mt(dap_worker_t * a_worker, dap_events_socket_uuid_t a_es_uuid)
 {
     dap_events_socket_uuid_t * l_es_uuid_ptr= DAP_NEW_Z(dap_events_socket_uuid_t);
-    *l_es_uuid_ptr = a_es->uuid;
+    *l_es_uuid_ptr = a_es_uuid;
 
-    int l_ret= dap_events_socket_queue_ptr_send( a_es->worker->queue_es_delete, l_es_uuid_ptr );
+    int l_ret= dap_events_socket_queue_ptr_send( a_worker->queue_es_delete, l_es_uuid_ptr );
     if( l_ret != 0 ){
         log_it(L_ERROR, "Queue send returned %d", l_ret);
         DAP_DELETE(l_es_uuid_ptr);
@@ -1498,7 +1079,6 @@ dap_events_socket_t * dap_events_socket_wrap2( dap_server_t *a_server, struct da
     dap_events_socket_t * l_es = DAP_NEW_Z( dap_events_socket_t ); if (!l_es) return NULL;
 
     l_es->socket = a_sock;
-    l_es->events = a_events;
     l_es->server = a_server;
     l_es->uuid = dap_uuid_generate_uint64();
     memcpy(&l_es->callbacks,a_callbacks, sizeof ( l_es->callbacks) );
@@ -1512,130 +1092,6 @@ dap_events_socket_t * dap_events_socket_wrap2( dap_server_t *a_server, struct da
     return l_es;
 }
 
-
-/**
- * @brief dap_worker_esocket_find_uuid
- * @param a_worker
- * @param a_es_uuid
- * @return
- */
-dap_events_socket_t *dap_worker_esocket_find_uuid(dap_worker_t * a_worker, dap_events_socket_uuid_t a_es_uuid )
-{
-    assert(a_worker);
-    dap_events_socket_t * l_ret = NULL;
-    if(a_worker->esockets ) {
-        pthread_rwlock_rdlock(&a_worker->esocket_rwlock);
-        //HASH_FIND_PTR( a_worker->esockets, &a_es_uuid,l_ret );
-        HASH_FIND(hh_worker, a_worker->esockets, &a_es_uuid, sizeof(a_es_uuid), l_ret );
-        pthread_rwlock_unlock(&a_worker->esocket_rwlock );
-    }
-    return l_ret;
-}
-
-void dap_events_socket_worker_poll_update_unsafe(dap_events_socket_t * a_esocket)
-{
-    #if defined (DAP_EVENTS_CAPS_EPOLL)
-        int events = a_esocket->ev_base_flags | EPOLLERR;
-
-        // Check & add
-        if( a_esocket->flags & DAP_SOCK_READY_TO_READ )
-            events |= EPOLLIN;
-
-        if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING )
-            events |= EPOLLOUT;
-
-        a_esocket->ev.events = events;
-
-        if( a_esocket->worker){
-            if ( epoll_ctl(a_esocket->worker->epoll_fd, EPOLL_CTL_MOD, a_esocket->socket, &a_esocket->ev) ){
-#ifdef DAP_OS_WINDOWS
-                int l_errno = WSAGetLastError();
-#else
-                int l_errno = errno;
-#endif
-                char l_errbuf[128];
-                l_errbuf[0]=0;
-                strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-                log_it(L_ERROR,"Can't update client socket state in the epoll_fd %"DAP_FORMAT_HANDLE": \"%s\" (%d)",
-                       a_esocket->worker->epoll_fd, l_errbuf, l_errno);
-            }
-        }
-    #elif defined (DAP_EVENTS_CAPS_POLL)
-        if( a_esocket->worker && a_esocket->is_initalized){
-            if (a_esocket->poll_index < a_esocket->worker->poll_count ){
-                struct pollfd * l_poll = &a_esocket->worker->poll[a_esocket->poll_index];
-                l_poll->events = a_esocket->poll_base_flags | POLLERR ;
-                // Check & add
-                if( a_esocket->flags & DAP_SOCK_READY_TO_READ )
-                    l_poll->events |= POLLIN;
-                if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING )
-                    l_poll->events |= POLLOUT;
-            }else{
-                log_it(L_ERROR, "Wrong poll index when remove from worker (unsafe): %u when total count %u", a_esocket->poll_index,
-                       a_esocket->worker->poll_count);
-            }
-        }
-    #elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    if (a_esocket->socket != -1  ){ // Not everything we add in poll
-        struct kevent * l_event = &a_esocket->kqueue_event;
-        short l_filter  =a_esocket->kqueue_base_filter;
-        u_short l_flags =a_esocket->kqueue_base_flags;
-        u_int l_fflags =a_esocket->kqueue_base_fflags;
-
-        int l_kqueue_fd = a_esocket->worker? a_esocket->worker->kqueue_fd :
-                          a_esocket->proc_thread ? a_esocket->proc_thread->kqueue_fd : -1;
-        if ( l_kqueue_fd == -1 ){
-            log_it(L_ERROR, "Esocket is not assigned with anything ,exit");
-        }
-
-        // Check & add
-        bool l_is_error=false;
-        int l_errno=0;
-        if (a_esocket->type == DESCRIPTOR_TYPE_EVENT ){
-            EV_SET(l_event, a_esocket->socket, EVFILT_USER,EV_ADD| EV_CLEAR ,0,0, &a_esocket->kqueue_event_catched_data );
-            if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
-                l_is_error = true;
-                l_errno = errno;
-            }
-        }else{
-            EV_SET(l_event, a_esocket->socket, l_filter,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-            if( a_esocket->flags & DAP_SOCK_READY_TO_READ ){
-                EV_SET(l_event, a_esocket->socket, EVFILT_READ,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-                if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1 ){
-                    l_is_error = true;
-                    l_errno = errno;
-                }
-            }
-            if( !l_is_error){
-                if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING ){
-                    EV_SET(l_event, a_esocket->socket, EVFILT_WRITE,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-                    if(kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) == -1){
-                        l_is_error = true;
-                        l_errno = errno;
-                    }
-                }
-            }
-        }
-        if (l_is_error && l_errno == EBADF){
-            log_it(L_ATT,"Poll update: socket %d (%p ) disconnected, rise CLOSE flag to remove from queue, lost %"DAP_UINT64_FORMAT_U":%" DAP_UINT64_FORMAT_U
-                         " bytes",a_esocket->socket,a_esocket,a_esocket->buf_in_size,a_esocket->buf_out_size);
-            a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
-            a_esocket->buf_in_size = a_esocket->buf_out_size = 0; // Reset everything from buffer, we close it now all
-        }else if ( l_is_error && l_errno != EINPROGRESS && l_errno != ENOENT){
-            char l_errbuf[128];
-            l_errbuf[0]=0;
-            strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-            log_it(L_ERROR,"Can't update client socket state on kqueue fd %d: \"%s\" (%d)",
-                l_kqueue_fd, l_errbuf, l_errno);
-        }
-     }
-
-    #else
-    #error "Not defined dap_events_socket_set_writable_unsafe for your platform"
-    #endif
-
-}
-
 /**
  * @brief dap_events_socket_ready_to_read
  * @param sc
@@ -1659,8 +1115,7 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *a_esocket, bool
         EV_SET(&l_event, a_esocket->socket, EVFILT_READ,
                a_esocket->kqueue_base_flags | l_op_flag,a_esocket->kqueue_base_fflags ,
                a_esocket->kqueue_data,a_esocket);
-        int l_kqueue_fd = a_esocket->worker? a_esocket->worker->kqueue_fd :
-                          a_esocket->proc_thread ? a_esocket->proc_thread->kqueue_fd : -1;
+        int l_kqueue_fd = a_esocket->context? a_esocket->context->kqueue_fd : -1;
         if( l_kqueue_fd>0 ){
             int l_kevent_ret = kevent(l_kqueue_fd,&l_event,1,NULL,0,NULL);
             int l_errno = errno;
@@ -1682,10 +1137,7 @@ void dap_events_socket_set_readable_unsafe( dap_events_socket_t *a_esocket, bool
     }else
         log_it(L_WARNING,"Trying to set readable/writable event, queue or timer thats you shouldnt do");
 #else
-    if( a_esocket->worker)
-        dap_events_socket_worker_poll_update_unsafe( a_esocket);
-    else if( a_esocket->proc_thread)
-        dap_proc_thread_esocket_update_poll_flags(a_esocket->proc_thread,a_esocket );
+    dap_context_poll_update(a_esocket);
 #endif
 
 }
@@ -1716,8 +1168,7 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *a_esocket, bool
         EV_SET(&l_event, a_esocket->socket, EVFILT_WRITE,
                a_esocket->kqueue_base_flags | l_op_flag,a_esocket->kqueue_base_fflags ,
                a_esocket->kqueue_data,a_esocket);
-        int l_kqueue_fd = a_esocket->worker? a_esocket->worker->kqueue_fd :
-                          a_esocket->proc_thread ? a_esocket->proc_thread->kqueue_fd : -1;
+        int l_kqueue_fd = a_esocket->context? a_esocket->context->kqueue_fd : -1;
         if( l_kqueue_fd>0 ){
             int l_kevent_ret=kevent(l_kqueue_fd,&l_event,1,NULL,0,NULL);
             int l_errno = errno;
@@ -1739,10 +1190,7 @@ void dap_events_socket_set_writable_unsafe( dap_events_socket_t *a_esocket, bool
     }else
         log_it(L_WARNING,"Trying to set readable/writable event, queue or timer thats you shouldnt do");
 #else
-    if( a_esocket->worker)
-        dap_events_socket_worker_poll_update_unsafe(a_esocket);
-    else if( a_esocket->proc_thread)
-        dap_proc_thread_esocket_update_poll_flags(a_esocket->proc_thread,a_esocket );
+    dap_context_poll_update(a_esocket);
 #endif
 
 }
@@ -1760,7 +1208,7 @@ bool s_remove_and_delete_unsafe_delayed_delete_callback(void * a_arg)
     assert(l_es_handler);
     assert(l_worker);
     dap_events_socket_t * l_es;
-    if( (l_es = dap_worker_esocket_find_uuid(l_worker, l_es_handler->esocket_uuid)) != NULL)
+    if( (l_es = dap_context_esocket_find_by_uuid(l_worker->context, l_es_handler->esocket_uuid)) != NULL)
         //dap_events_socket_remove_and_delete_unsafe(l_es,l_es_handler->value == 1);
         dap_events_remove_and_delete_socket_unsafe(dap_events_get_default(), l_es, l_es_handler->value == 1);
     DAP_DELETE(l_es_handler);
@@ -1780,7 +1228,7 @@ void dap_events_socket_remove_and_delete_unsafe_delayed( dap_events_socket_t *a_
     l_es_handler->value = a_preserve_inheritor ? 1 : 0;
     dap_events_socket_descriptor_close(a_es);
 
-    dap_worker_t * l_worker = a_es->worker;
+    dap_worker_t * l_worker = a_es->context->worker;
     dap_events_socket_remove_from_worker_unsafe( a_es, l_worker);
     a_es->flags |= DAP_SOCK_SIGNAL_CLOSE;
     dap_timerfd_start_on_worker(l_worker, s_delayed_ops_timeout_ms,
@@ -1804,7 +1252,7 @@ void dap_events_socket_remove_and_delete_unsafe( dap_events_socket_t *a_es, bool
 #endif
 
     //log_it( L_DEBUG, "es is going to be removed from the lists and free the memory (0x%016X)", a_es );
-    dap_events_socket_remove_from_worker_unsafe(a_es, a_es->worker);
+    dap_events_socket_remove_from_worker_unsafe(a_es, a_es->context->worker);
 
     if( a_es->callbacks.delete_callback )
         a_es->callbacks.delete_callback( a_es, NULL ); // Init internal structure
@@ -1863,15 +1311,13 @@ void dap_events_socket_delete_unsafe( dap_events_socket_t * a_esocket , bool a_p
  */
 void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap_worker_t * a_worker)
 {
-    if (!a_es->worker) {
+    if (!a_es->context->worker) {
         log_it(L_INFO, "No worker assigned to esocket %"DAP_FORMAT_SOCKET, a_es->socket);
         return;
     }
 
-    pthread_rwlock_wrlock(&a_worker->esocket_rwlock);
     a_worker->event_sockets_count--;
-    HASH_DELETE(hh_worker,a_worker->esockets, a_es);
-    pthread_rwlock_unlock(&a_worker->esocket_rwlock);
+    HASH_DELETE(hh_worker,a_worker->context->esockets, a_es);
 
 #if defined(DAP_EVENTS_CAPS_EPOLL)
 
@@ -1888,52 +1334,52 @@ void dap_events_socket_remove_from_worker_unsafe( dap_events_socket_t *a_es, dap
         struct kevent * l_event = &a_es->kqueue_event;
         if (a_es->kqueue_base_filter){
             EV_SET(l_event, a_es->socket, a_es->kqueue_base_filter ,EV_DELETE, 0,0,a_es);
-            if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
+            if ( kevent( a_worker->context->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                 int l_errno = errno;
                 char l_errbuf[128];
                 strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
                 log_it( L_ERROR,"Can't remove event socket's handler %d from the kqueue %d filter %d \"%s\" (%d)", a_es->socket,
-                    a_worker->kqueue_fd,a_es->kqueue_base_filter,  l_errbuf, l_errno);
+                    a_worker->context->kqueue_fd,a_es->kqueue_base_filter,  l_errbuf, l_errno);
             }
         }else{
             EV_SET(l_event, a_es->socket, EVFILT_EXCEPT ,EV_DELETE, 0,0,a_es);
-            kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL); // If this filter is not set up - no warnings
+            kevent( a_worker->context->kqueue_fd,l_event,1,NULL,0,NULL); // If this filter is not set up - no warnings
 
 
             if(a_es->flags & DAP_SOCK_READY_TO_WRITE){
                 EV_SET(l_event, a_es->socket, EVFILT_WRITE ,EV_DELETE, 0,0,a_es);
-                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
+                if ( kevent( a_worker->context->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                     int l_errno = errno;
                     char l_errbuf[128];
                     strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
                     log_it( L_ERROR,"Can't remove event socket's handler %d from the kqueue %d filter EVFILT_WRITE \"%s\" (%d)", a_es->socket,
-                        a_worker->kqueue_fd, l_errbuf, l_errno);
+                        a_worker->context->kqueue_fd, l_errbuf, l_errno);
                 }
             }
             if(a_es->flags & DAP_SOCK_READY_TO_READ){
                 EV_SET(l_event, a_es->socket, EVFILT_READ ,EV_DELETE, 0,0,a_es);
-                if ( kevent( a_worker->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
+                if ( kevent( a_worker->context->kqueue_fd,l_event,1,NULL,0,NULL) == -1 ) {
                     int l_errno = errno;
                     char l_errbuf[128];
                     strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
                     log_it( L_ERROR,"Can't remove event socket's handler %d from the kqueue %d filter EVFILT_READ \"%s\" (%d)", a_es->socket,
-                        a_worker->kqueue_fd, l_errbuf, l_errno);
+                        a_worker->context->kqueue_fd, l_errbuf, l_errno);
                 }
             }
 
         }
     }
 #elif defined (DAP_EVENTS_CAPS_POLL)
-    if (a_es->poll_index < a_worker->poll_count ){
-        a_worker->poll[a_es->poll_index].fd = -1;
-        a_worker->poll_compress = true;
+    if (a_es->poll_index < a_worker->context->poll_count ){
+        a_worker->context->poll[a_es->poll_index].fd = -1;
+        a_worker->context->poll_compress = true;
     }else{
         log_it(L_ERROR, "Wrong poll index when remove from worker (unsafe): %u when total count %u", a_es->poll_index, a_worker->poll_count);
     }
 #else
 #error "Unimplemented new esocket on worker callback for current platform"
 #endif
-    a_es->worker = NULL;
+    a_es->context = NULL;
 }
 
 /**
@@ -2084,7 +1530,7 @@ size_t dap_events_socket_write_f_inter(dap_events_socket_t * a_es_input, dap_eve
 
     int l_ret= dap_events_socket_queue_ptr_send_to_input(a_es_input, l_msg );
     if (l_ret!=0){
-        log_it(L_ERROR, "wite f inter: wasn't send pointer to queue input: code %d", l_ret);
+        log_it(L_ERROR, "write f inter: wasn't send pointer to queue input: code %d", l_ret);
         DAP_DELETE(l_msg);
         return 0;
     }
diff --git a/dap-sdk/net/core/dap_net.c b/dap-sdk/io/dap_net.c
similarity index 100%
rename from dap-sdk/net/core/dap_net.c
rename to dap-sdk/io/dap_net.c
diff --git a/dap-sdk/net/core/dap_proc_queue.c b/dap-sdk/io/dap_proc_queue.c
similarity index 84%
rename from dap-sdk/net/core/dap_proc_queue.c
rename to dap-sdk/io/dap_proc_queue.c
index ae7c1daaf9ed717ab8804cf5abf2959582b92f04..5ad0766c744fad4d40e3547820dcc2bb44870051 100644
--- a/dap-sdk/net/core/dap_proc_queue.c
+++ b/dap-sdk/io/dap_proc_queue.c
@@ -51,7 +51,7 @@ dap_proc_queue_t * dap_proc_queue_create_ext(dap_proc_thread_t * a_thread)
     if (!l_queue)
         return NULL;
 
-    for (int i = 0; i < DAP_QUE$K_PRIMAX; i++) {
+    for (int i = 0; i < DAP_PROC_PRI_MAX; i++) {
         assert ( !(pthread_mutex_init(&l_queue->list[i].lock, 0 )) );
     }
 
@@ -78,15 +78,14 @@ dap_proc_queue_t * dap_proc_queue_create(dap_proc_thread_t * a_thread)
     if (!l_queue)
         return NULL;
 
-    for (int i = 0; i < DAP_QUE$K_PRIMAX; i++) {
+    for (int i = 0; i < DAP_PROC_PRI_MAX; i++) {
         assert ( !(pthread_mutex_init(&l_queue->list[i].lock, 0 )) );
     }
 
     l_queue->proc_thread = a_thread;
-    l_queue->esocket = dap_events_socket_create_type_queue_ptr_unsafe(NULL,s_queue_esocket_callback);
+    l_queue->esocket = dap_context_create_esocket_queue(a_thread->context,s_queue_esocket_callback);
     l_queue->esocket->proc_thread = a_thread;
     l_queue->esocket->_inheritor = l_queue;
-
     return l_queue;
 }
 
@@ -104,7 +103,7 @@ int dap_proc_queue_delete(dap_proc_queue_t * a_queue)
         return  -ENOMEM;
 
     l_msg->signal_kill = 1;             /* TRUE */
-    l_msg->pri = DAP_QUE$K_PRI_HIGH;    /* Assume that KILL must be delivered ASAP */
+    l_msg->pri = DAP_PROC_PRI_HIGH;    /* Assume that KILL must be delivered ASAP */
 
     return  dap_events_socket_queue_ptr_send( a_queue->esocket, l_msg );
 }
@@ -157,7 +156,7 @@ static void s_queue_esocket_callback( dap_events_socket_t * a_es, void * a_msg)
      * So, all checks has been finished, now we can prepare new entry
      */
     pri = l_msg->pri;                                                       /* Validate priority */
-    pri = MIN(pri, DAP_QUE$K_PRIMAX - 1);
+    pri = MIN(pri, DAP_PROC_PRI_MAX - 1);
     pri = MAX(pri, 0);
 
         l_item->callback = l_msg->callback;
@@ -197,7 +196,7 @@ int dap_proc_queue_add_callback(dap_worker_t * a_worker,dap_proc_queue_callback_
 
     l_msg->callback = a_callback;
     l_msg->callback_arg = a_callback_arg;
-    l_msg->pri = DAP_QUE$K_PRI_NORMAL;
+    l_msg->pri = DAP_PROC_PRI_NORMAL;
     /*
      * Send message to queue with the DEFAULT priority
      */
@@ -219,10 +218,10 @@ int dap_proc_queue_add_callback_ext(dap_worker_t * a_worker,dap_proc_queue_callb
 {
 dap_proc_queue_msg_t *l_msg;
 
-    if ( !(a_pri < DAP_QUE$K_PRIMAX) )                                      /* Check that priority level is in legal range */
+    if ( !(a_pri < DAP_PROC_PRI_MAX) )                                      /* Check that priority level is in legal range */
     {
-        log_it(L_WARNING, "Priority level %d is incorrect (should be is in range %d-%d)", a_pri, DAP_QUE$K_PRI0 + 1, DAP_QUE$K_PRIMAX - 1);
-        a_pri = DAP_QUE$K_PRI_NORMAL;
+        log_it(L_WARNING, "Priority level %d is incorrect (should be is in range %d-%d)", a_pri, DAP_PROC_PRI_0 + 1, DAP_PROC_PRI_MAX - 1);
+        a_pri = DAP_PROC_PRI_NORMAL;
     }
 
     if ( !(l_msg = DAP_NEW_Z(dap_proc_queue_msg_t)) )                       /* Allocate memory for a new message */
@@ -256,7 +255,7 @@ int dap_proc_queue_add_callback_inter( dap_events_socket_t * a_es_input, dap_pro
 
     l_msg->callback = a_callback;
     l_msg->callback_arg = a_callback_arg;
-    l_msg->pri = DAP_QUE$K_PRI_NORMAL;
+    l_msg->pri = DAP_PROC_PRI_NORMAL;
 
     return  dap_events_socket_queue_ptr_send_to_input( a_es_input , l_msg );
 }
@@ -275,10 +274,10 @@ int dap_proc_queue_add_callback_inter_ext( dap_events_socket_t * a_es_input, dap
 {
 dap_proc_queue_msg_t *l_msg;
 
-    if ( !(a_pri < DAP_QUE$K_PRIMAX) )                                      /* Check that priority level is in legal range */
+    if ( !(a_pri < DAP_PROC_PRI_MAX) )                                      /* Check that priority level is in legal range */
     {
-        log_it(L_WARNING, "Priority level %d is incorrect (should be is in range %d-%d)", a_pri, DAP_QUE$K_PRI0 + 1, DAP_QUE$K_PRIMAX - 1);
-        a_pri = DAP_QUE$K_PRI_NORMAL;
+        log_it(L_WARNING, "Priority level %d is incorrect (should be is in range %d-%d)", a_pri, DAP_PROC_PRI_0 + 1, DAP_PROC_PRI_MAX - 1);
+        a_pri = DAP_PROC_PRI_NORMAL;
     }
 
     if ( !(l_msg = DAP_NEW_Z(dap_proc_queue_msg_t)) )                       /* Allocate memory for a new message */
@@ -290,3 +289,31 @@ dap_proc_queue_msg_t *l_msg;
 
     return  dap_events_socket_queue_ptr_send_to_input( a_es_input , l_msg );
 }
+
+/**
+ * @brief dap_proc_thread_add_callback_mt
+ * @param a_thread
+ * @param a_callback
+ * @param a_callback_arg
+ * @return
+ */
+int dap_proc_thread_add_callback_mt(dap_proc_thread_t * a_thread, dap_proc_queue_callback_t a_callback, void * a_callback_arg, int a_pri)
+{
+    dap_proc_queue_msg_t *l_msg;
+
+    if ( !(a_pri < DAP_PROC_PRI_MAX) )                                      /* Check that priority level is in legal range */
+    {
+        log_it(L_WARNING, "Priority level %d is incorrect (should be is in range %d-%d)", a_pri, DAP_PROC_PRI_0 + 1, DAP_PROC_PRI_MAX - 1);
+        a_pri = DAP_PROC_PRI_NORMAL;
+    }
+
+    if ( !(l_msg = DAP_NEW_Z(dap_proc_queue_msg_t)) )                       /* Allocate memory for a new message */
+        return  -ENOMEM;
+
+    l_msg->callback = a_callback;
+    l_msg->callback_arg = a_callback_arg;
+    l_msg->pri = a_pri;
+
+    return dap_events_socket_queue_ptr_send(a_thread->proc_queue->esocket, l_msg);
+}
+
diff --git a/dap-sdk/io/dap_proc_thread.c b/dap-sdk/io/dap_proc_thread.c
new file mode 100644
index 0000000000000000000000000000000000000000..70d2e1653fd9721e0eaafccae67903c84ccee39b
--- /dev/null
+++ b/dap-sdk/io/dap_proc_thread.c
@@ -0,0 +1,568 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Ltd.   https://demlabs.net
+ * Copyright  (c) 2020
+ * All rights reserved.
+
+ This file is part of DAP SDK the open source project
+
+    DAP SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    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/>.
+*/
+#include <errno.h>
+#include <stdatomic.h>
+
+#include "dap_config.h"
+#include "dap_list.h"
+#include "dap_events.h"
+#include "dap_events_socket.h"
+#include "dap_proc_thread.h"
+#include "dap_server.h"
+
+#if defined(DAP_EVENTS_CAPS_EPOLL) && !defined(DAP_OS_WINDOWS)
+#include <sys/epoll.h>
+#elif defined DAP_OS_WINDOWS
+#include "wepoll.h"
+#elif defined (DAP_EVENTS_CAPS_POLL)
+#include <poll.h>
+#elif defined (DAP_EVENTS_CAPS_KQUEUE)
+
+#include <sys/event.h>
+#include <err.h>
+
+#ifndef DAP_OS_DARWIN
+#include <pthread_np.h>
+typedef cpuset_t cpu_set_t; // Adopt BSD CPU setstructure to POSIX variant
+#else
+#define NOTE_READ NOTE_LOWAT
+#endif
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL SO_NOSIGPIPE
+#endif
+
+#else
+#error "Unimplemented poll for this platform"
+#endif
+
+#define LOG_TAG "dap_proc_thread"
+
+static size_t s_threads_count = 0;
+static dap_proc_thread_t * s_threads = NULL;
+
+static dap_slist_t s_custom_threads = $DAP_SLIST_INITALIZER;                    /* Customized proc threads out of the pool */
+static pthread_rwlock_t s_custom_threads_rwlock = PTHREAD_RWLOCK_INITIALIZER;   /* Lock to protect <s_custom_threads> */
+
+
+static void *s_proc_thread_function(void * a_arg);
+static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags);
+
+/**
+ * @brief dap_proc_thread_init
+ * @param a_cpu_count 0 means autodetect
+ * @return
+ */
+
+int dap_proc_thread_init(uint32_t a_threads_count)
+{
+int l_ret = 0;
+
+    s_threads_count = a_threads_count ? a_threads_count : dap_get_cpu_count( );
+    s_threads = DAP_NEW_Z_SIZE(dap_proc_thread_t, sizeof (dap_proc_thread_t)* s_threads_count);
+
+    for (uint32_t i = 0; i < s_threads_count; i++ )
+    {
+        dap_proc_thread_t * l_thread = s_threads + i;
+        l_thread->cpu_id = i;
+        l_thread->context = dap_context_new();
+        l_thread->context->proc_thread = l_thread;
+        pthread_cond_init(&l_thread->started_cond, NULL);
+        pthread_mutex_init( &l_thread->started_mutex,NULL);
+
+        pthread_mutex_lock( &l_thread->started_mutex );
+
+        if ( (l_ret = pthread_create( &l_thread->thread_id,NULL, s_proc_thread_function, &s_threads[i] )) ) {
+            log_it(L_CRITICAL, "Create thread failed with code %d", l_ret);
+            pthread_mutex_unlock( &l_thread->started_mutex );
+            return l_ret;
+        }
+
+        pthread_cond_wait( &l_thread->started_cond, &l_thread->started_mutex);
+        pthread_mutex_unlock( &l_thread->started_mutex);
+    }
+
+    return l_ret;
+}
+
+/**
+ * @brief dap_proc_thread_deinit
+ */
+void dap_proc_thread_deinit()
+{
+    int l_rc = 0;
+    size_t l_sz = 0;
+    dap_proc_thread_t *l_proc_thread = NULL;
+
+    for (uint32_t i = s_threads_count; i--; ){
+        dap_events_socket_event_signal(s_threads[i].event_exit, 1);
+        pthread_join(s_threads[i].thread_id, NULL);
+    }
+
+    // Cleaning custom proc threads
+    pthread_rwlock_wrlock(&s_custom_threads_rwlock);
+
+    for ( uint32_t i = s_custom_threads.nr; i--; ) {
+        if ( s_dap_slist_get4head (&s_custom_threads, (void **) &l_proc_thread, &l_sz) )
+            break;
+
+        dap_events_socket_event_signal(l_proc_thread->event_exit, 1);
+        pthread_join(l_proc_thread->thread_id, NULL);
+        DAP_DELETE(l_proc_thread);
+    }
+
+    pthread_rwlock_unlock(&s_custom_threads_rwlock);
+
+    // Signal to cancel working threads and wait for finish
+    // TODO: Android realization
+//#ifndef DAP_OS_ANDROID
+//    for (size_t i = 0; i < s_threads_count; i++ ){
+//        pthread_cancel(s_threads[i].thread_id);
+//        pthread_join(s_threads[i].thread_id, NULL);
+//    }
+//#endif
+
+}
+
+/**
+ * @brief dap_proc_thread_get
+ * @param a_cpu_id
+ * @return
+ */
+dap_proc_thread_t * dap_proc_thread_get(uint32_t a_cpu_id)
+{
+    return (a_cpu_id < s_threads_count) ? &s_threads[a_cpu_id] : NULL;
+}
+
+/**
+ * @brief dap_proc_thread_get_auto
+ * @return
+ */
+dap_proc_thread_t * dap_proc_thread_get_auto()
+{
+unsigned l_id_min = 0, l_size_min = UINT32_MAX, l_queue_size;
+
+    for (size_t i = 0; i < s_threads_count; i++ )
+    {
+        l_queue_size = atomic_load(&s_threads[i].proc_queue_size);
+
+        if( l_queue_size < l_size_min ){
+            l_size_min = l_queue_size;
+            l_id_min = i;
+        }
+    }
+
+    return &s_threads[l_id_min];
+}
+
+/**
+ * @brief dap_proc_thread_run_custom Create custom proc thread for specified task
+ * @return
+ */
+dap_proc_thread_t * dap_proc_thread_run_custom(void)
+{
+    dap_proc_thread_t * l_proc_thread = DAP_NEW_Z(dap_proc_thread_t);
+    int l_ret;
+
+    if (l_proc_thread == NULL)
+        return  log_it(L_CRITICAL,"Out of memory, can't create new proc thread, errno=%d", errno), NULL;
+
+    pthread_mutex_lock( &l_proc_thread->started_mutex );
+
+    if ( (l_ret = pthread_create( &l_proc_thread->thread_id ,NULL, s_proc_thread_function, l_proc_thread  )) ) {
+        log_it(L_CRITICAL, "Create thread failed with code %d", l_ret);
+        DAP_DEL_Z (l_proc_thread);
+    }else{
+        pthread_cond_wait( &l_proc_thread->started_cond, &l_proc_thread->started_mutex);
+        pthread_rwlock_wrlock(&s_custom_threads_rwlock);
+        assert ( !s_dap_slist_add2tail (&s_custom_threads, l_proc_thread, sizeof(l_proc_thread)) );
+        pthread_rwlock_unlock(&s_custom_threads_rwlock);
+    }
+
+    pthread_mutex_unlock( &l_proc_thread->started_mutex );
+    return l_proc_thread;
+}
+
+/**
+ * @brief s_proc_event_callback - get from queue next element and execute action routine,
+ *  repeat execution depending on status is returned by action routine.
+ *
+ * @param a_esocket
+ * @param a_value
+ *
+ */
+static void s_proc_event_callback(dap_events_socket_t * a_esocket, uint64_t __attribute__((unused))  a_value)
+{
+dap_proc_thread_t   *l_thread;
+dap_proc_queue_item_t *l_item;
+int     l_rc, l_is_anybody_in_queue, l_is_finished, l_iter_cnt, l_cur_pri;
+size_t  l_item_sz;
+dap_proc_queue_t    *l_queue;
+
+    debug_if (g_debug_reactor, L_DEBUG, "--> Proc event callback start, a_esocket:%p ", a_esocket);
+
+    if ( !(l_thread = (dap_proc_thread_t *) a_esocket->_inheritor) )
+        {
+        log_it(L_ERROR, "NULL <dap_proc_thread_t> context is detected");
+        return;
+        }
+
+    l_iter_cnt = l_is_anybody_in_queue = 0;
+    /*@RRL:  l_iter_cnt = DAP_QUE$K_ITER_NR; */
+    l_queue = l_thread->proc_queue;
+
+    for (l_cur_pri = (DAP_PROC_PRI_MAX - 1); l_cur_pri; l_cur_pri--, l_iter_cnt++ ) /* Run from higest to lowest ... */
+    {
+        if ( !l_queue->list[l_cur_pri].items.nr )                           /* A lockless quick check */
+            continue;
+
+        pthread_mutex_lock(&l_queue->list[l_cur_pri].lock);                 /* Protect list from other threads */
+        l_rc = s_dap_slist_get4head (&l_queue->list[l_cur_pri].items, (void **) &l_item, &l_item_sz);
+        pthread_mutex_unlock(&l_queue->list[l_cur_pri].lock);
+
+        if  ( l_rc == -ENOENT ) {                                           /* Queue is empty ? */
+            debug_if (g_debug_reactor, L_DEBUG, "a_esocket:%p - nothing to do at prio: %d ", a_esocket, l_cur_pri);
+            continue;
+        }
+
+        debug_if (g_debug_reactor, L_INFO, "Proc event callback: %p/%p, prio=%d, iteration=%d",
+                       l_item->callback, l_item->callback_arg, l_cur_pri, l_iter_cnt);
+
+        l_is_finished = l_item->callback(l_thread, l_item->callback_arg);
+
+        debug_if (g_debug_reactor, L_INFO, "Proc event callback: %p/%p, prio=%d, iteration=%d - is %sfinished",
+                           l_item->callback, l_item->callback_arg, l_cur_pri, l_iter_cnt, l_is_finished ? "" : "not ");
+
+        if ( !(l_is_finished) ) {
+                                                                            /* Rearm callback to be executed again */
+            pthread_mutex_lock(&l_queue->list[l_cur_pri].lock);
+            l_rc = s_dap_slist_add2tail (&l_queue->list[l_cur_pri].items, l_item, l_item_sz );
+            pthread_mutex_unlock(&l_queue->list[l_cur_pri].lock);
+
+            if ( l_rc ) {
+                log_it(L_ERROR, "Error requeue event callback: %p/%p, errno=%d", l_item->callback, l_item->callback_arg, l_rc);
+                DAP_DELETE(l_item);
+            }
+        }
+        else    {
+            DAP_DELETE(l_item);
+    	}
+    }
+    for (l_cur_pri = (DAP_PROC_PRI_MAX - 1); l_cur_pri; l_cur_pri--)        /* Really ?! */
+        l_is_anybody_in_queue += l_queue->list[l_cur_pri].items.nr;
+
+    if ( l_is_anybody_in_queue )                                            /* Arm event if we have something to proc again */
+        dap_events_socket_event_signal(a_esocket, 1);
+
+    debug_if(g_debug_reactor, L_DEBUG, "<-- Proc event callback end, items rest: %d, iterations: %d", l_is_anybody_in_queue, l_iter_cnt);
+}
+
+
+/**
+ * @brief dap_proc_thread_assign_esocket_unsafe
+ * @param a_thread
+ * @param a_esocket
+ * @return
+ */
+int dap_proc_thread_assign_esocket_unsafe(dap_proc_thread_t * a_thread, dap_events_socket_t * a_esocket)
+{
+    assert(a_esocket);
+    assert(a_thread);
+    a_esocket->proc_thread = a_thread;
+
+#ifdef DAP_EVENTS_CAPS_EPOLL
+        // Init events for EPOLL
+        a_esocket->ev.events = a_esocket->ev_base_flags ;
+        if(a_esocket->flags & DAP_SOCK_READY_TO_READ )
+            a_esocket->ev.events |= EPOLLIN;
+        if(a_esocket->flags & DAP_SOCK_READY_TO_WRITE )
+            a_esocket->ev.events |= EPOLLOUT;
+        a_esocket->ev.data.ptr = a_esocket;
+        return epoll_ctl(a_thread->epoll_ctl, EPOLL_CTL_ADD, a_esocket->socket, &a_esocket->ev);
+#elif defined (DAP_EVENTS_CAPS_POLL)
+    if (  a_thread->poll_count == a_thread->poll_count_max ){ // realloc
+        a_thread->poll_count_max *= 2;
+        log_it(L_WARNING, "Too many descriptors (%zu), resizing array twice to %zu", a_thread->poll_count, a_thread->poll_count_max);
+        a_thread->poll =DAP_REALLOC(a_thread->poll, a_thread->poll_count_max * sizeof(*a_thread->poll));
+        a_thread->esockets =DAP_REALLOC(a_thread->esockets, a_thread->poll_count_max * sizeof(*a_thread->esockets));
+    }
+
+    a_thread->poll[a_thread->poll_count].fd = a_thread->proc_queue->esocket->fd;
+    a_thread->poll[a_thread->poll_count].events = a_thread->proc_queue->esocket->poll_base_flags;
+    a_thread->esockets[a_thread->poll_count] = a_thread->proc_queue->esocket;
+    a_thread->poll_count++;
+#elif defined (DAP_EVENTS_CAPS_KQUEUE)
+/*    u_short l_flags = a_esocket->kqueue_base_flags;
+    u_int   l_fflags = a_esocket->kqueue_base_fflags;
+    short l_filter = a_esocket->kqueue_base_filter;
+        if(a_esocket->flags & DAP_SOCK_READY_TO_READ )
+            l_fflags |= NOTE_READ;
+        if(a_esocket->flags & DAP_SOCK_READY_TO_WRITE )
+            l_fflags |= NOTE_WRITE;
+
+        EV_SET(&a_esocket->kqueue_event , a_esocket->socket, l_filter, EV_ADD| l_flags | EV_CLEAR, l_fflags,0, a_esocket);
+        return kevent ( a_thread->kqueue_fd,&a_esocket->kqueue_event,1,NULL,0,NULL)==1 ? 0 : -1 ;
+*/
+    // Nothing to do if its input
+    if ( a_esocket->type == DESCRIPTOR_TYPE_QUEUE && a_esocket->pipe_out)
+        return 0;
+#else
+#error "Unimplemented new esocket on worker callback for current platform"
+#endif
+
+    return dap_context_poll_update(a_esocket);
+}
+
+
+
+/**
+ * @brief dap_proc_thread_create_queue_ptr
+ * @details Call this function as others only from safe situation, or, thats better, from a_thread's context
+ * @param a_thread
+ * @param a_callback
+ * @return
+ */
+dap_events_socket_t * dap_proc_thread_create_queue_ptr(dap_proc_thread_t * a_thread, dap_events_socket_callback_queue_ptr_t a_callback)
+{
+    dap_events_socket_t * l_es = dap_context_create_esocket_queue(a_thread->context,a_callback);
+    if(l_es == NULL)
+        return NULL;
+    l_es->proc_thread = a_thread;
+    return l_es;
+}
+
+/**
+ * @brief s_proc_thread_function
+ * @param a_arg
+ * @return
+ */
+static void * s_proc_thread_function(void * a_arg)
+{
+
+    dap_proc_thread_t * l_thread = (dap_proc_thread_t*) a_arg;
+    assert(l_thread);
+    dap_context_t * l_context = l_thread->context;
+    assert(l_context);
+    dap_cpu_assign_thread_on(l_thread->cpu_id);
+
+    struct sched_param l_shed_params;
+    l_shed_params.sched_priority = 0;
+#if defined(DAP_OS_WINDOWS)
+    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST))
+        log_it(L_ERROR, "Couldn't set thread priority, err: %lu", GetLastError());
+#elif defined (DAP_OS_LINUX)
+    pthread_setschedparam(pthread_self(),SCHED_BATCH ,&l_shed_params);
+#elif defined (DAP_OS_BSD)
+    pthread_setschedparam(pthread_self(),SCHED_OTHER ,&l_shed_params);
+#else
+#error "Undefined set sched param"
+#endif
+    if(dap_context_thread_init(l_thread->context)!=0){
+        pthread_cond_broadcast(&l_thread->started_cond);
+        return NULL;
+    }
+
+    l_thread->proc_queue = dap_proc_queue_create(l_thread);
+
+    // Init proc_queue for related worker
+    dap_worker_t * l_worker_related = dap_events_worker_get(l_thread->cpu_id);
+    assert(l_worker_related);
+    l_worker_related->proc_queue = l_thread->proc_queue;
+    l_worker_related->proc_queue_input = dap_events_socket_queue_ptr_create_input(l_worker_related->proc_queue->esocket);
+
+    dap_events_socket_assign_on_worker_mt(l_worker_related->proc_queue_input,l_worker_related);
+
+    l_thread->proc_event = dap_context_create_esocket_event( l_context , s_proc_event_callback);
+    l_thread->proc_event->proc_thread = l_thread;
+    l_thread->event_exit = dap_context_create_esocket_event(l_context, s_event_exit_callback);
+    l_thread->event_exit->proc_thread = l_thread;
+
+    l_thread->proc_event->_inheritor = l_thread; // we pass thread through it
+    l_thread->event_exit->_inheritor = l_thread;
+
+    size_t l_workers_count= dap_events_worker_get_count();
+    assert(l_workers_count);
+    l_thread->queue_assign_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
+    l_thread->queue_io_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
+    l_thread->queue_callback_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
+
+    assert(l_thread->queue_assign_input);
+    assert(l_thread->queue_io_input);
+    for (size_t n=0; n<l_workers_count; n++){
+        dap_worker_t * l_worker =dap_events_worker_get(n);
+        l_thread->queue_assign_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_new );
+        l_thread->queue_io_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_io );
+        l_thread->queue_callback_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_callback );
+    }
+
+
+    for (size_t n = 0; n< dap_events_worker_get_count(); n++){
+        // Queue asssign
+        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_assign_input[n]);
+
+        // Queue IO
+        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_io_input[n]);
+
+        // Queue callback
+        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_callback_input[n]);
+    }
+
+
+    //We've started!
+    pthread_cond_broadcast(&l_thread->started_cond);
+
+
+
+    dap_context_thread_loop(l_thread->context);
+
+    log_it(L_ATT, "Stop processing thread #%u", l_thread->cpu_id);
+    // cleanip inputs
+    for (size_t n=0; n<dap_events_worker_get_count(); n++){
+        dap_events_socket_delete_unsafe(l_thread->queue_assign_input[n], false);
+        dap_events_socket_delete_unsafe(l_thread->queue_io_input[n], false);
+        dap_events_socket_delete_unsafe(l_thread->queue_callback_input[n], false);
+    }
+
+    return NULL;
+}
+
+/**
+ * @brief dap_proc_thread_assign_on_worker_inter
+ * @param a_thread
+ * @param a_worker
+ * @param a_esocket
+ * @return
+ */
+bool dap_proc_thread_assign_on_worker_inter(dap_proc_thread_t * a_thread, dap_worker_t * a_worker, dap_events_socket_t *a_esocket  )
+{
+    dap_events_socket_t * l_es_assign_input = a_thread->queue_assign_input[a_worker->id];
+    if(g_debug_reactor)
+        log_it(L_DEBUG,"Remove esocket %p from proc thread and send it to worker #%u",a_esocket, a_worker->id);
+
+    dap_events_socket_assign_on_worker_inter(l_es_assign_input, a_esocket);
+    // TODO Make this code platform-independent
+#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
+    l_es_assign_input->flags |= DAP_SOCK_READY_TO_WRITE;
+    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_assign_input);
+#endif
+    return true;
+}
+
+/**
+ * @brief dap_proc_thread_esocket_write_inter
+ * @param a_thread
+ * @param a_worker
+ * @param a_es_uuid
+ * @param a_data
+ * @param a_data_size
+ * @return
+ */
+int dap_proc_thread_esocket_write_inter(dap_proc_thread_t * a_thread,dap_worker_t * a_worker,   dap_events_socket_uuid_t a_es_uuid,
+                                        const void * a_data, size_t a_data_size)
+{
+    dap_events_socket_t * l_es_io_input = a_thread->queue_io_input[a_worker->id];
+    dap_events_socket_write_inter(l_es_io_input,a_es_uuid, a_data, a_data_size);
+    // TODO Make this code platform-independent
+#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
+    l_es_io_input->flags |= DAP_SOCK_READY_TO_WRITE;
+    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_io_input);
+#endif
+    return 0;
+}
+
+
+/**
+ * @brief dap_proc_thread_esocket_write_f_inter
+ * @param a_thread
+ * @param a_worker
+ * @param a_es_uuid,
+ * @param a_format
+ * @return
+ */
+int dap_proc_thread_esocket_write_f_inter(dap_proc_thread_t * a_thread,dap_worker_t * a_worker,  dap_events_socket_uuid_t a_es_uuid,
+                                        const char * a_format,...)
+{
+    va_list ap, ap_copy;
+    va_start(ap,a_format);
+    va_copy(ap_copy, ap);
+    int l_data_size = dap_vsnprintf(NULL,0,a_format,ap);
+    va_end(ap);
+    if (l_data_size <0 ){
+        log_it(L_ERROR,"Can't write out formatted data '%s' with values",a_format);
+        va_end(ap_copy);
+        return 0;
+    }
+
+    dap_events_socket_t * l_es_io_input = a_thread->queue_io_input[a_worker->id];
+    char * l_data = DAP_NEW_SIZE(char,l_data_size+1);
+    if (!l_data){
+        va_end(ap_copy);
+        return -1;
+    }
+    l_data_size = dap_vsprintf(l_data,a_format,ap_copy);
+    va_end(ap_copy);
+
+    dap_events_socket_write_inter(l_es_io_input, a_es_uuid, l_data, l_data_size);
+    // TODO Make this code platform-independent
+#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
+    l_es_io_input->flags |= DAP_SOCK_READY_TO_WRITE;
+    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_io_input);
+#endif
+    DAP_DELETE(l_data);
+    return 0;
+}
+
+/**
+ * @brief dap_proc_thread_worker_exec_callback
+ * @param a_thread
+ * @param a_worker_id
+ * @param a_callback
+ * @param a_arg
+ */
+void dap_proc_thread_worker_exec_callback_inter(dap_proc_thread_t * a_thread, size_t a_worker_id, dap_worker_callback_t a_callback, void * a_arg)
+{
+    dap_worker_msg_callback_t * l_msg = DAP_NEW_Z(dap_worker_msg_callback_t);
+    l_msg->callback = a_callback;
+    l_msg->arg = a_arg;
+    dap_events_socket_queue_ptr_send_to_input(a_thread->queue_callback_input[a_worker_id],l_msg );
+
+    // TODO Make this code platform-independent
+#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
+    a_thread->queue_callback_input[a_worker_id]->flags |= DAP_SOCK_READY_TO_WRITE;
+    dap_proc_thread_esocket_update_poll_flags(a_thread, a_thread->queue_callback_input[a_worker_id]);
+#endif
+}
+
+
+static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags)
+{
+    (void) a_flags;
+    dap_proc_thread_t * l_thread = (dap_proc_thread_t *) a_es->_inheritor;
+    l_thread->context->signal_exit = true;
+    if(g_debug_reactor)
+        log_it(L_DEBUG, "Proc_thread :%u signaled to exit", l_thread->cpu_id);
+}
+
+
+
+
diff --git a/dap-sdk/net/core/dap_server.c b/dap-sdk/io/dap_server.c
similarity index 98%
rename from dap-sdk/net/core/dap_server.c
rename to dap-sdk/io/dap_server.c
index 792af686326c764b136b3fd0e88a86ab907bbb5c..84471b9c639105addb64cd7d368817654466c27b 100644
--- a/dap-sdk/net/core/dap_server.c
+++ b/dap-sdk/io/dap_server.c
@@ -104,7 +104,7 @@ void dap_server_delete(dap_server_t *a_server)
 {
     while (a_server->es_listeners) {
         dap_events_socket_t *l_es = (dap_events_socket_t *)a_server->es_listeners->data;
-        dap_events_socket_remove_and_delete_mt(l_es->worker, l_es->uuid); // TODO unsafe moment. Replace storage to uuids
+        dap_events_socket_remove_and_delete_mt(l_es->context->worker, l_es->uuid); // TODO unsafe moment. Replace storage to uuids
         dap_list_t *l_tmp = a_server->es_listeners;
         a_server->es_listeners = l_tmp->next;
         DAP_DELETE(l_tmp);
@@ -345,7 +345,7 @@ static int s_server_run(dap_server_t * a_server, dap_events_socket_callbacks_t *
  */
 static void s_es_server_new(dap_events_socket_t *a_es, void * a_arg)
 {
-    log_it(L_DEBUG, "Created server socket %p on worker %u", a_es, a_es->worker->id);
+    log_it(L_DEBUG, "Created server socket %p on worker %u", a_es, a_es->context->worker->id);
     dap_server_t *l_server = (dap_server_t*) a_es->_inheritor;
     pthread_mutex_lock( &l_server->started_mutex);
     pthread_mutex_unlock( &l_server->started_mutex);
@@ -383,7 +383,7 @@ static void s_es_server_accept(dap_events_socket_t *a_es, SOCKET a_remote_socket
     dap_events_socket_t * l_es_new = NULL;
     log_it(L_DEBUG, "Listening socket (binded on %s:%u) got new incomming connection",l_server->address,l_server->port);
     log_it(L_DEBUG, "Accepted new connection (sock %"DAP_FORMAT_SOCKET" from %"DAP_FORMAT_SOCKET")", a_remote_socket, a_es->socket);
-    l_es_new = s_es_server_create(a_es->events,a_remote_socket,&l_server->client_callbacks,l_server);
+    l_es_new = s_es_server_create(dap_events_get_default(),a_remote_socket,&l_server->client_callbacks,l_server);
     //l_es_new->is_dont_reset_write_flag = true; // By default all income connection has this flag
     getnameinfo(a_remote_addr,a_remote_addr_size, l_es_new->hostaddr
                 ,256, l_es_new->service,sizeof(l_es_new->service),
diff --git a/dap-sdk/net/core/dap_timerfd.c b/dap-sdk/io/dap_timerfd.c
similarity index 86%
rename from dap-sdk/net/core/dap_timerfd.c
rename to dap-sdk/io/dap_timerfd.c
index c38f9e27e3cc6cec551b0244e544237fdee5cca0..55d6b02dd0994323c46ac4e84cc8fe9e3928fd1e 100644
--- a/dap-sdk/net/core/dap_timerfd.c
+++ b/dap-sdk/io/dap_timerfd.c
@@ -255,7 +255,7 @@ dap_timerfd_t* dap_timerfd_create(uint64_t a_timeout_ms, dap_timerfd_callback_t
     return l_timerfd;
 }
 
-static void s_timerfd_reset(dap_timerfd_t *a_timerfd, dap_events_socket_t *a_event_sock)
+static inline void s_timerfd_reset(dap_timerfd_t *a_timerfd, dap_events_socket_t *a_es)
 {
 #if defined DAP_OS_LINUX
     struct itimerspec l_ts;
@@ -269,10 +269,10 @@ static void s_timerfd_reset(dap_timerfd_t *a_timerfd, dap_events_socket_t *a_eve
         log_it(L_WARNING, "Reset timerfd failed: timerfd_settime() errno=%d\n", errno);
     }
 #elif defined (DAP_OS_BSD)
-    dap_worker_add_events_socket_unsafe(a_event_sock,a_event_sock->worker);
-//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);
+    // Re-add timer in context
+    dap_context_t * l_context = a_es->context;
+    a_es->context = NULL;
+    dap_context_add_esocket(l_context,a_es);
 #elif defined (DAP_OS_WINDOWS)
     /*LARGE_INTEGER l_due_time;
     l_due_time.QuadPart = (long long)a_timerfd->timeout_ms * _MSEC;
@@ -285,10 +285,13 @@ static void s_timerfd_reset(dap_timerfd_t *a_timerfd, dap_events_socket_t *a_eve
 #endif
 
 #ifndef DAP_OS_BSD
-    dap_events_socket_set_readable_unsafe(a_event_sock, true);
+    dap_events_socket_set_readable_unsafe(a_es, true);
 #endif
 }
 
+
+
+
 /**
  * @brief s_es_callback_timer
  * @param a_event_sock
@@ -304,6 +307,38 @@ static void s_es_callback_timer(struct dap_events_socket *a_event_sock)
     }
 }
 
+/**
+ * @brief s_timerfd_reset_worker_callback
+ * @param a_worker
+ * @param a_arg
+ */
+static void s_timerfd_reset_worker_callback( dap_worker_t * a_worker, void * a_arg )
+{
+    dap_timerfd_t *l_timerfd = (dap_timerfd_t *) a_arg;
+    dap_events_socket_t *l_sock = NULL;
+    l_sock = dap_context_esocket_find_by_uuid(a_worker->context, l_timerfd->esocket_uuid);
+    if (l_sock)
+        s_timerfd_reset(l_timerfd, l_sock);
+
+}
+
+/**
+ * @brief s_timerfd_reset_proc_thread_callback
+ * @param a_thread
+ * @param a_arg
+ * @return
+ */
+static bool s_timerfd_reset_proc_thread_callback( dap_proc_thread_t * a_thread, void * a_arg )
+{
+    dap_timerfd_t *l_timerfd = (dap_timerfd_t *) a_arg;
+    dap_events_socket_t *l_sock = NULL;
+    l_sock = dap_context_esocket_find_by_uuid(a_thread->context, l_timerfd->esocket_uuid);
+    if (l_sock)
+        s_timerfd_reset(l_timerfd, l_sock);
+    return true;
+}
+
+
 /**
  * @brief dap_timerfd_reset
  * @param a_tfd
@@ -312,13 +347,12 @@ void dap_timerfd_reset(dap_timerfd_t *a_timerfd)
 {
     if (!a_timerfd)
         return;
-    dap_events_socket_t *l_sock = NULL;
-    if (a_timerfd->worker)
-        l_sock = dap_worker_esocket_find_uuid(a_timerfd->worker, a_timerfd->esocket_uuid);
-    else if (a_timerfd->proc_thread)
-        l_sock = a_timerfd->events_socket;
-    if (l_sock)
-        s_timerfd_reset(a_timerfd, l_sock);
+    if (a_timerfd->worker){
+        dap_worker_exec_callback_on(a_timerfd->worker,s_timerfd_reset_worker_callback, a_timerfd);
+    }else if (a_timerfd->proc_thread)
+        dap_proc_thread_add_callback_mt(a_timerfd->proc_thread,s_timerfd_reset_proc_thread_callback, a_timerfd, DAP_PROC_PRI_NORMAL );
+    else
+        log_it(L_WARNING,"Timer's context undefined, cant' reset it");
 }
 
 /**
@@ -333,6 +367,6 @@ void dap_timerfd_delete(dap_timerfd_t *a_timerfd)
     #ifdef _WIN32
         DeleteTimerQueueTimer(hTimerQueue, (HANDLE)a_timerfd->th, NULL);
     #endif
-    if (a_timerfd->events_socket->worker)
-        dap_events_socket_remove_and_delete_mt(a_timerfd->events_socket->worker, a_timerfd->esocket_uuid);
+    if (a_timerfd->events_socket->context->worker)
+        dap_events_socket_remove_and_delete_mt(a_timerfd->events_socket->context->worker, a_timerfd->esocket_uuid);
 }
diff --git a/dap-sdk/io/dap_worker.c b/dap-sdk/io/dap_worker.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c5293241abbdadd3077d44c04f5f9c6e7639c26
--- /dev/null
+++ b/dap-sdk/io/dap_worker.c
@@ -0,0 +1,442 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Ltd.   https://demlabs.net
+ * Copyright  (c) 2017
+ * All rights reserved.
+
+ This file is part of DAP SDK the open source project
+
+    DAP SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    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/>.
+*/
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "dap_common.h"
+#include "dap_config.h"
+#include "dap_context.h"
+#include "dap_math_ops.h"
+#include "dap_worker.h"
+#include "dap_timerfd.h"
+#include "dap_events.h"
+#include "dap_enc_base64.h"
+#include "dap_proc_queue.h"
+
+#ifndef DAP_NET_CLIENT_NO_SSL
+#include <wolfssl/options.h>
+#include "wolfssl/ssl.h"
+#endif
+
+#define LOG_TAG "dap_worker"
+
+static time_t s_connection_timeout = 60;    // seconds
+
+static bool s_socket_all_check_activity( void * a_arg);
+static void s_queue_add_es_callback( dap_events_socket_t * a_es, void * a_arg);
+static void s_queue_delete_es_callback( dap_events_socket_t * a_es, void * a_arg);
+static void s_queue_es_reassign_callback( dap_events_socket_t * a_es, void * a_arg);
+static void s_queue_callback_callback( dap_events_socket_t * a_es, void * a_arg);
+static void s_queue_es_io_callback( dap_events_socket_t * a_es, void * a_arg);
+static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags);
+
+/**
+ * @brief dap_worker_init
+ * @param a_threads_count
+ * @param conn_timeout
+ * @return
+ */
+int dap_worker_init( size_t a_conn_timeout )
+{
+    if ( a_conn_timeout )
+      s_connection_timeout = a_conn_timeout;
+
+    return 0;
+}
+
+void dap_worker_deinit( )
+{
+}
+
+/**
+ * @brief dap_worker_thread
+ * @param arg
+ * @return
+ */
+void *dap_worker_thread(void *arg)
+{
+    dap_worker_t *l_worker = (dap_worker_t *) arg;
+    assert(l_worker);
+    dap_context_t * l_context = l_worker->context;
+    const struct sched_param l_shed_params = {0};
+
+
+    dap_cpu_assign_thread_on(l_worker->id);
+    pthread_setspecific(l_worker->events->pth_key_worker, l_worker);
+
+#ifdef DAP_OS_WINDOWS
+    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL))
+        log_it(L_ERROR, "Couldn'r set thread priority, err: %lu", GetLastError());
+#else
+    pthread_setschedparam(pthread_self(),SCHED_FIFO ,&l_shed_params);
+#endif
+
+    if(dap_context_thread_init(l_context)!=0){
+        pthread_cond_broadcast(&l_worker->started_cond);
+        return NULL;
+    }
+
+    l_worker->queue_es_new_input      = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
+    l_worker->queue_es_delete_input   = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
+    l_worker->queue_es_io_input       = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
+    l_worker->queue_es_reassign_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)* dap_events_worker_get_count() );
+
+
+    l_worker->queue_es_new      = dap_context_create_esocket_queue(l_context, s_queue_add_es_callback);
+    l_worker->queue_es_delete   = dap_context_create_esocket_queue(l_context, s_queue_delete_es_callback);
+    l_worker->queue_es_io       = dap_context_create_esocket_queue(l_context, s_queue_es_io_callback);
+    l_worker->queue_es_reassign = dap_context_create_esocket_queue(l_context, s_queue_es_reassign_callback );
+
+
+    for( size_t n = 0; n < dap_events_worker_get_count(); n++) {
+        l_worker->queue_es_new_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_new);
+        l_worker->queue_es_delete_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_delete);
+        l_worker->queue_es_io_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_io);
+        l_worker->queue_es_reassign_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_reassign);
+    }
+
+    l_worker->queue_callback    = dap_context_create_esocket_queue(l_context, s_queue_callback_callback);
+    l_worker->event_exit        = dap_context_create_esocket_event(l_context, s_event_exit_callback);
+
+    l_worker->timer_check_activity = dap_timerfd_create(s_connection_timeout * 1000 / 2,
+                                                        s_socket_all_check_activity, l_worker);
+    dap_worker_add_events_socket_unsafe(  l_worker->timer_check_activity->events_socket, l_worker);
+    pthread_cond_broadcast(&l_worker->started_cond);
+
+    dap_context_thread_loop(l_context);
+    log_it(L_NOTICE,"Exiting thread #%u", l_worker->id);
+    return NULL;
+}
+
+/**
+ * @brief s_new_es_callback
+ * @param a_es
+ * @param a_arg
+ */
+static void s_queue_add_es_callback( dap_events_socket_t * a_es, void * a_arg)
+{
+    assert(a_es);
+    dap_context_t * l_context = a_es->context;
+    assert(l_context);
+    dap_worker_t * l_worker = l_context->worker;
+    assert(l_worker);
+    dap_events_socket_t * l_es_new =(dap_events_socket_t *) a_arg;
+    if (!l_es_new){
+        log_it(L_ERROR,"NULL esocket accepted to add on worker #%u", l_worker->id);
+        return;
+    }
+
+    if(g_debug_reactor)
+        log_it(L_NOTICE, "Received event socket %p (ident %"DAP_FORMAT_SOCKET" type %d) to add on worker", l_es_new, l_es_new->socket, l_es_new->type);
+
+    switch( l_es_new->type){
+        case DESCRIPTOR_TYPE_SOCKET_UDP: break;
+        case DESCRIPTOR_TYPE_SOCKET_CLIENT: break;
+        default:{}
+    }
+
+#ifdef DAP_EVENTS_CAPS_KQUEUE
+    if(l_es_new->socket!=0 && l_es_new->socket != -1 &&
+            l_es_new->type != DESCRIPTOR_TYPE_EVENT &&
+        l_es_new->type != DESCRIPTOR_TYPE_QUEUE &&
+        l_es_new->type != DESCRIPTOR_TYPE_TIMER
+            )
+#else
+    if(l_es_new->socket!=0 && l_es_new->socket != INVALID_SOCKET)
+
+#endif
+    if(dap_context_esocket_find_by_uuid( l_context, l_es_new->uuid)){
+        // Socket already present in worker, it's OK
+        return;
+    }
+
+    switch( l_es_new->type){
+
+        case DESCRIPTOR_TYPE_SOCKET_UDP:
+        case DESCRIPTOR_TYPE_SOCKET_CLIENT:
+        case DESCRIPTOR_TYPE_SOCKET_LISTENING:{
+
+#ifdef DAP_OS_UNIX
+#if defined (SO_INCOMING_CPU)
+            int l_cpu = l_worker->id;
+            setsockopt(l_es_new->socket , SOL_SOCKET, SO_INCOMING_CPU, &l_cpu, sizeof(l_cpu));
+#endif
+#endif
+        } break;
+        default: {}
+    }
+
+    l_es_new->last_time_active = time(NULL);
+    // We need to differ new and reassigned esockets. If its new - is_initialized is false
+    if ( ! l_es_new->is_initalized ){
+        if (l_es_new->callbacks.new_callback)
+            l_es_new->callbacks.new_callback(l_es_new, NULL);
+        l_es_new->is_initalized = true;
+    }
+
+    int l_ret =dap_context_add_esocket(l_context,l_es_new);
+    if (  l_ret != 0 ){
+        log_it(L_CRITICAL,"Can't add event socket's handler to worker i/o poll mechanism with error %d", errno);
+    }else{
+        // Add in worker
+        l_es_new->me = l_es_new;
+        if (l_es_new->socket!=0 && l_es_new->socket != INVALID_SOCKET){
+            HASH_ADD(hh_worker, l_worker->context->esockets, uuid, sizeof(l_es_new->uuid), l_es_new );
+            l_worker->event_sockets_count++;
+        }
+        //log_it(L_DEBUG, "Added socket %d on worker %u", l_es_new->socket, w->id);
+        if (l_es_new->callbacks.worker_assign_callback)
+            l_es_new->callbacks.worker_assign_callback(l_es_new, l_worker);
+
+    }
+}
+
+/**
+ * @brief s_delete_es_callback
+ * @param a_es
+ * @param a_arg
+ */
+static void s_queue_delete_es_callback( dap_events_socket_t * a_es, void * a_arg)
+{
+    assert(a_arg);
+    dap_events_socket_uuid_t * l_es_uuid_ptr = (dap_events_socket_uuid_t*) a_arg;
+    dap_events_socket_t * l_es;
+    if ( (l_es = dap_context_esocket_find_by_uuid(a_es->context,*l_es_uuid_ptr)) != NULL ){
+        //l_es->flags |= DAP_SOCK_SIGNAL_CLOSE; // Send signal to socket to kill
+        dap_events_socket_remove_and_delete_unsafe(l_es,false);
+    }else
+        log_it(L_INFO, "While we were sending the delete() message, esocket %"DAP_UINT64_FORMAT_U" has been disconnected ", *l_es_uuid_ptr);
+    DAP_DELETE(l_es_uuid_ptr);
+}
+
+/**
+ * @brief s_reassign_es_callback
+ * @param a_es
+ * @param a_arg
+ */
+static void s_queue_es_reassign_callback( dap_events_socket_t * a_es, void * a_arg)
+{
+    assert(a_es);
+    dap_context_t * l_context = a_es->context;
+    assert(l_context);
+    dap_worker_t * l_worker = l_context->worker;
+    assert(l_worker);
+    dap_worker_msg_reassign_t * l_msg = (dap_worker_msg_reassign_t*) a_arg;
+    assert(l_msg);
+    dap_events_socket_t * l_es_reassign;
+    if ( ( l_es_reassign = dap_context_esocket_find_by_uuid(l_context, l_msg->esocket_uuid))!= NULL ){
+        if( l_es_reassign->was_reassigned && l_es_reassign->flags & DAP_SOCK_REASSIGN_ONCE) {
+            log_it(L_INFO, "Reassgment request with DAP_SOCK_REASSIGN_ONCE allowed only once, declined reassigment from %u to %u",
+                   l_es_reassign->context->worker->id, l_msg->worker_new->id);
+
+        }else{
+            dap_events_socket_reassign_between_workers_unsafe(l_es_reassign,l_msg->worker_new);
+        }
+    }else{
+        log_it(L_INFO, "While we were sending the reassign message, esocket %p has been disconnected", l_msg->esocket);
+    }
+    DAP_DELETE(l_msg);
+}
+
+/**
+ * @brief s_queue_callback
+ * @param a_es
+ * @param a_arg
+ */
+static void s_queue_callback_callback( dap_events_socket_t * a_es, void * a_arg)
+{
+    dap_worker_msg_callback_t * l_msg = (dap_worker_msg_callback_t *) a_arg;
+    assert(l_msg);
+    assert(l_msg->callback);
+    l_msg->callback(a_es->context->worker, l_msg->arg);
+    DAP_DELETE(l_msg);
+}
+
+/**
+ * @brief s_event_exit_callback
+ * @param a_es
+ * @param a_flags
+ */
+static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags)
+{
+    (void) a_flags;
+    a_es->context->signal_exit = true;
+    if(g_debug_reactor)
+        log_it(L_DEBUG, "Worker :%u signaled to exit", a_es->context->worker->id);
+}
+
+/**
+ * @brief s_pipe_data_out_read_callback
+ * @param a_es
+ * @param a_arg
+ */
+static void s_queue_es_io_callback( dap_events_socket_t * a_es, void * a_arg)
+{
+    assert(a_es);
+    dap_context_t * l_context = a_es->context;
+    assert(l_context);
+    dap_worker_t * l_worker = a_es->context->worker;
+    dap_worker_msg_io_t * l_msg = a_arg;
+    assert(l_msg);
+    // Check if it was removed from the list
+    dap_events_socket_t *l_msg_es = dap_context_esocket_find_by_uuid(l_worker->context, l_msg->esocket_uuid);
+    if ( l_msg_es == NULL){
+        log_it(L_INFO, "We got i/o message for esocket %"DAP_UINT64_FORMAT_U" thats now not in list. Lost %zu data", l_msg->esocket_uuid, l_msg->data_size);
+        DAP_DELETE(l_msg);
+        return;
+    }
+
+    if (l_msg->flags_set & DAP_SOCK_CONNECTING)
+        if (!  (l_msg_es->flags & DAP_SOCK_CONNECTING) ){
+            l_msg_es->flags |= DAP_SOCK_CONNECTING;
+            dap_context_poll_update(l_msg_es);
+        }
+
+    if (l_msg->flags_set & DAP_SOCK_CONNECTING)
+        if (!  (l_msg_es->flags & DAP_SOCK_CONNECTING) ){
+            l_msg_es->flags ^= DAP_SOCK_CONNECTING;
+            dap_context_poll_update(l_msg_es);
+        }
+
+    if (l_msg->flags_set & DAP_SOCK_READY_TO_READ)
+        dap_events_socket_set_readable_unsafe(l_msg_es, true);
+    if (l_msg->flags_unset & DAP_SOCK_READY_TO_READ)
+        dap_events_socket_set_readable_unsafe(l_msg_es, false);
+    if (l_msg->flags_set & DAP_SOCK_READY_TO_WRITE)
+        dap_events_socket_set_writable_unsafe(l_msg_es, true);
+    if (l_msg->flags_unset & DAP_SOCK_READY_TO_WRITE)
+        dap_events_socket_set_writable_unsafe(l_msg_es, false);
+    if (l_msg->data_size && l_msg->data) {
+        dap_events_socket_write_unsafe(l_msg_es, l_msg->data,l_msg->data_size);
+        DAP_DELETE(l_msg->data);
+    }
+    DAP_DELETE(l_msg);
+}
+
+/**
+ * @brief s_socket_all_check_activity
+ * @param a_arg
+ */
+static bool s_socket_all_check_activity( void * a_arg)
+{
+    dap_worker_t *l_worker = (dap_worker_t*) a_arg;
+    assert(l_worker);
+    dap_events_socket_t *l_es = NULL, *tmp = NULL;
+    char l_curtimebuf[64];
+    time_t l_curtime= time(NULL);
+    //dap_ctime_r(&l_curtime, l_curtimebuf);
+    //log_it(L_DEBUG,"Check sockets activity on worker #%u at %s", l_worker->id, l_curtimebuf);
+    HASH_ITER(hh_worker, l_worker->context->esockets, l_es, tmp ) {
+        if (l_es->type == DESCRIPTOR_TYPE_SOCKET_CLIENT){
+            if ( !(l_es->flags & DAP_SOCK_SIGNAL_CLOSE) &&
+                 (  l_curtime >=  (l_es->last_time_active + s_connection_timeout) ) && !l_es->no_close ) {
+                log_it( L_INFO, "Socket %"DAP_FORMAT_SOCKET" timeout (diff %"DAP_UINT64_FORMAT_U" ), closing...",
+                                l_es->socket, l_curtime -  (time_t)l_es->last_time_active - s_connection_timeout );
+                if (l_es->callbacks.error_callback) {
+                    l_es->callbacks.error_callback(l_es, ETIMEDOUT);
+                }
+                dap_events_socket_remove_and_delete_unsafe(l_es,false);
+            }
+        }
+    }
+    return true;
+}
+
+/**
+ * @brief sap_worker_add_events_socket
+ * @param a_events_socket
+ * @param a_worker
+ */
+void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker)
+{
+/*#ifdef DAP_EVENTS_CAPS_KQUEUE
+    a_events_socket->worker = a_worker;
+    if(dap_worker_add_events_socket_unsafe(a_events_socket, a_worker)!=0)
+        a_events_socket->worker = NULL;
+
+#else*/
+    if(g_debug_reactor)
+        log_it(L_DEBUG,"Worker add esocket %"DAP_FORMAT_SOCKET, a_events_socket->socket);
+    int l_ret = dap_events_socket_queue_ptr_send( a_worker->queue_es_new, a_events_socket );
+    if(l_ret != 0 ){
+        char l_errbuf[128];
+        *l_errbuf = 0;
+        strerror_r(l_ret, l_errbuf, sizeof(l_errbuf));
+        log_it(L_ERROR, "Can't send pointer in queue: \"%s\"(code %d)", l_errbuf, l_ret);
+    }
+//#endif
+}
+
+/**
+ * @brief dap_worker_add_events_socket_inter
+ * @param a_es_input
+ * @param a_events_socket
+ */
+void dap_worker_add_events_socket_inter(dap_events_socket_t * a_es_input, dap_events_socket_t * a_events_socket)
+{
+    if( dap_events_socket_queue_ptr_send_to_input( a_es_input, a_events_socket ) != 0 ){
+        int l_errno = errno;
+        char l_errbuf[128];
+        *l_errbuf = 0;
+        strerror_r(l_errno,l_errbuf,sizeof (l_errbuf));
+        log_it(L_ERROR, "Cant send pointer to interthread queue input: \"%s\"(code %d)", l_errbuf, l_errno);
+    }
+}
+
+
+/**
+ * @brief dap_worker_exec_callback_on
+ */
+void dap_worker_exec_callback_on(dap_worker_t * a_worker, dap_worker_callback_t a_callback, void * a_arg)
+{
+    dap_worker_msg_callback_t * l_msg = DAP_NEW_Z(dap_worker_msg_callback_t);
+    l_msg->callback = a_callback;
+    l_msg->arg = a_arg;
+    int l_ret=dap_events_socket_queue_ptr_send( a_worker->queue_callback,l_msg );
+    if(l_ret != 0 ){
+        char l_errbuf[128];
+        *l_errbuf = 0;
+        strerror_r(l_ret,l_errbuf,sizeof (l_errbuf));
+        log_it(L_ERROR, "Cant send pointer in queue: \"%s\"(code %d)", l_errbuf, l_ret);
+    }
+
+}
+
+
+/**
+ * @brief dap_worker_add_events_socket
+ * @param a_worker
+ * @param a_events_socket
+ */
+dap_worker_t *dap_worker_add_events_socket_auto( dap_events_socket_t *a_es)
+{
+//  struct epoll_event ev = {0};
+  dap_worker_t *l_worker = dap_events_worker_get_auto( );
+
+  dap_worker_add_events_socket( a_es, l_worker);
+  return l_worker;
+}
+
+
+
diff --git a/dap-sdk/io/include/dap_context.h b/dap-sdk/io/include/dap_context.h
new file mode 100644
index 0000000000000000000000000000000000000000..182a1fb4213dfc93074bc803526968ec2eb7b7f9
--- /dev/null
+++ b/dap-sdk/io/include/dap_context.h
@@ -0,0 +1,93 @@
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Ltd.   https://demlabs.net
+ * Copyright  (c) 2022
+ * All rights reserved.
+
+ This file is part of DAP SDK the open source project
+
+    DAP SDK is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP SDK is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    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/>.
+*/
+#pragma once
+
+#include <pthread.h>
+#include <uthash.h>
+#include "dap_common.h"
+#include "dap_events_socket.h"
+#include "dap_proc_queue.h"
+
+typedef struct dap_worker dap_worker_t;
+typedef struct dap_proc_thread dap_proc_thread_t;
+typedef struct dap_context {
+    uint32_t id;  // Context ID
+
+    // Compatibility fields, in future should be replaced with _inheritor
+    dap_proc_thread_t * proc_thread; // If the context belongs to proc_thread
+    dap_worker_t * worker; // If the context belongs to worker
+
+#if defined DAP_EVENTS_CAPS_MSMQ
+    HANDLE msmq_events[MAXIMUM_WAIT_OBJECTS];
+#endif
+
+#if defined DAP_EVENTS_CAPS_EPOLL
+    EPOLL_HANDLE epoll_fd;
+    struct epoll_event epoll_events[ DAP_EVENTS_SOCKET_MAX];
+#elif defined ( DAP_EVENTS_CAPS_POLL)
+    int poll_fd;
+    struct pollfd * poll;
+    dap_events_socket_t ** poll_esocket;
+    atomic_uint poll_count;
+    size_t poll_count_max;
+    bool poll_compress; // Some of fd's became NULL so arrays need to be reassigned
+#elif defined (DAP_EVENTS_CAPS_KQUEUE)
+    int kqueue_fd;
+    struct kevent * kqueue_events_selected;
+    struct kevent * kqueue_events;
+    size_t kqueue_events_count;
+
+    int kqueue_events_count_max;
+    int kqueue_events_selected_count_max;
+#else
+#error "Not defined worker for your platform"
+#endif
+
+    dap_events_socket_t *esockets; // Hashmap of event sockets
+
+    // Signal to exit
+    bool signal_exit;
+
+} dap_context_t;
+
+extern pthread_key_t g_dap_context_pth_key;
+static inline dap_context_t * dap_context_current(){
+    return (dap_context_t*) pthread_getspecific(g_dap_context_pth_key);
+}
+
+
+int dap_context_init(); // Init
+
+// New context create. Thread-safe functions
+dap_context_t * dap_context_new();
+
+/// ALL THIS FUNCTIONS ARE UNSAFE ! CALL THEM ONLY INSIDE THEIR OWN CONTEXT!!
+int dap_context_thread_init(dap_context_t * a_context);
+int dap_context_thread_loop(dap_context_t * a_context);
+
+int dap_context_add_esocket(dap_context_t * a_context, dap_events_socket_t * a_esocket );
+int dap_context_poll_update(dap_events_socket_t * a_esocket);
+dap_events_socket_t *dap_context_esocket_find_by_uuid(dap_context_t * a_context, dap_events_socket_uuid_t a_es_uuid );
+dap_events_socket_t * dap_context_create_esocket_queue(dap_context_t * a_context, dap_events_socket_callback_queue_ptr_t a_callback);
+dap_events_socket_t * dap_context_create_esocket_event(dap_context_t * a_context, dap_events_socket_callback_event_t a_callback);
+dap_events_socket_t * dap_context_create_esocket_pipe(dap_context_t * a_context, dap_events_socket_callback_t a_callback, uint32_t a_flags);
diff --git a/dap-sdk/net/core/include/dap_events.h b/dap-sdk/io/include/dap_events.h
similarity index 100%
rename from dap-sdk/net/core/include/dap_events.h
rename to dap-sdk/io/include/dap_events.h
diff --git a/dap-sdk/net/core/include/dap_events_socket.h b/dap-sdk/io/include/dap_events_socket.h
similarity index 97%
rename from dap-sdk/net/core/include/dap_events_socket.h
rename to dap-sdk/io/include/dap_events_socket.h
index d0b406a1c7c31ee99fe3625f716dcd939b022f5a..52086076a9a63d1f9543f685d818e638686d9e48 100644
--- a/dap-sdk/net/core/include/dap_events_socket.h
+++ b/dap-sdk/io/include/dap_events_socket.h
@@ -115,6 +115,7 @@ typedef struct dap_events dap_events_t;
 typedef struct dap_events_socket dap_events_socket_t;
 typedef struct dap_worker dap_worker_t;
 typedef struct dap_proc_thread dap_proc_thread_t ;
+typedef struct dap_context dap_context_t;
 
 typedef struct dap_server dap_server_t;
 typedef void (*dap_events_socket_callback_t) (dap_events_socket_t *,void * ); // Callback for specific client operations
@@ -244,8 +245,8 @@ typedef struct dap_events_socket {
 
 
     // Links to related objects
-    dap_events_t *events;
-    dap_worker_t *worker;
+//    dap_events_t *events;
+    dap_context_t * context;
     dap_proc_thread_t * proc_thread; // If assigned on dap_proc_thread_t object
     dap_server_t *server; // If this socket assigned with server
 
@@ -310,7 +311,6 @@ void dap_events_socket_deinit(void); // Deinit clients module
 
 dap_events_socket_t * dap_events_socket_create(dap_events_desc_type_t a_type, dap_events_socket_callbacks_t* a_callbacks);
 
-dap_events_socket_t * dap_events_socket_create_type_queue_ptr_unsafe(dap_worker_t * a_w, dap_events_socket_callback_queue_ptr_t a_callback);
 dap_events_socket_t * dap_events_socket_create_type_queue_ptr_mt(dap_worker_t * a_w, dap_events_socket_callback_queue_ptr_t a_callback);
 int dap_events_socket_queue_proc_input_unsafe(dap_events_socket_t * a_esocket);
 
@@ -329,6 +329,7 @@ int dap_events_socket_queue_ptr_send( dap_events_socket_t * a_es, void* a_arg);
 int dap_events_socket_event_signal( dap_events_socket_t * a_es, uint64_t a_value);
 
 void dap_events_socket_delete_unsafe( dap_events_socket_t * a_esocket , bool a_preserve_inheritor);
+void dap_events_socket_delete_mt(dap_worker_t * a_worker, dap_events_socket_uuid_t a_es_uuid);
 
 dap_events_socket_t *dap_events_socket_wrap_no_add( dap_events_t *a_events,
                                             int a_sock, dap_events_socket_callbacks_t *a_callbacks );
@@ -341,13 +342,8 @@ void dap_events_socket_assign_on_worker_inter(dap_events_socket_t * a_es_input,
 void dap_events_socket_reassign_between_workers_mt(dap_worker_t * a_worker_old, dap_events_socket_t * a_es, dap_worker_t * a_worker_new);
 void dap_events_socket_reassign_between_workers_unsafe(dap_events_socket_t * a_es, dap_worker_t * a_worker_new);
 
-// Non-MT functions
-dap_events_socket_t * dap_worker_esocket_find_uuid(dap_worker_t * a_worker, dap_events_socket_uuid_t a_es_uuid);
-
 void dap_events_socket_set_readable_unsafe(dap_events_socket_t * sc,bool is_ready);
 void dap_events_socket_set_writable_unsafe(dap_events_socket_t * sc,bool is_ready);
-void dap_events_socket_worker_poll_update_unsafe(dap_events_socket_t * a_esocket);
-
 
 size_t dap_events_socket_write_unsafe(dap_events_socket_t *sc, const void * data, size_t data_size);
 size_t dap_events_socket_write_f_unsafe(dap_events_socket_t *sc, const char * format,...);
diff --git a/dap-sdk/net/core/include/dap_net.h b/dap-sdk/io/include/dap_net.h
similarity index 100%
rename from dap-sdk/net/core/include/dap_net.h
rename to dap-sdk/io/include/dap_net.h
diff --git a/dap-sdk/net/core/include/dap_proc_queue.h b/dap-sdk/io/include/dap_proc_queue.h
similarity index 74%
rename from dap-sdk/net/core/include/dap_proc_queue.h
rename to dap-sdk/io/include/dap_proc_queue.h
index cd75526c8c096e86a2ed689a34063ef638a22763..97ca1f262860bed2731502593bd9de38f7ef7a49 100644
--- a/dap-sdk/net/core/include/dap_proc_queue.h
+++ b/dap-sdk/io/include/dap_proc_queue.h
@@ -31,21 +31,21 @@ typedef bool (*dap_proc_queue_callback_t)(dap_proc_thread_t *, void *);     // C
                                                                             // we want to stop callback execution and
                                                                             // not to go on next loop
 enum    {
-        DAP_QUE$K_PRI0 = 0,                                                 /* Lowest priority (Idle)  */
-        DAP_QUE$K_PRI_IDLE = DAP_QUE$K_PRI0,                                /* Don't use Idle if u are not sure that understand how it works */
+        DAP_PROC_PRI_0 = 0,                                                 /* Lowest priority (Idle)  */
+        DAP_PROC_PRI_IDLE = DAP_PROC_PRI_0,                                /* Don't use Idle if u are not sure that understand how it works */
 
-        DAP_QUE$K_PRI1 = 1,                                                 /* Low priority */
-        DAP_QUE$K_PRI_LOW = DAP_QUE$K_PRI1,
+        DAP_PROC_PRI_1 = 1,                                                 /* Low priority */
+        DAP_PROC_PRI_LOW = DAP_PROC_PRI_1,
 
 
-        DAP_QUE$K_PRI2 = 2,
-        DAP_QUE$K_PRI_NORMAL = DAP_QUE$K_PRI2,                              /* Default priority for any queue's entry;
+        DAP_PROC_PRI_2 = 2,
+        DAP_PROC_PRI_NORMAL = DAP_PROC_PRI_2,                              /* Default priority for any queue's entry;
                                                                             has assigned implicitly */
 
-        DAP_QUE$K_PRI3 = 3,                                                 /* Higest priority */
-        DAP_QUE$K_PRI_HIGH = DAP_QUE$K_PRI3,
+        DAP_PROC_PRI_3 = 3,                                                 /* Higest priority */
+        DAP_PROC_PRI_HIGH = DAP_PROC_PRI_3,
 
-        DAP_QUE$K_PRIMAX = 4                                                /* End-of-list marker */
+        DAP_PROC_PRI_MAX = 4                                                /* End-of-list marker */
 };
 
 #define DAP_QUE$K_ITER_NR   7
@@ -63,9 +63,9 @@ typedef struct dap_proc_queue{
         dap_events_socket_t *esocket;
 
         struct {
-        pthread_mutex_t     lock;                                           /* To coordinate access to the queuee's entries */
-        dap_slist_t         items;                                          /* List of the queue' entries */
-        } list [DAP_QUE$K_PRIMAX];                                          /* An array of list according of priority numbers */
+            pthread_mutex_t     lock;                                           /* To coordinate access to the queuee's entries */
+            dap_slist_t         items;                                          /* List of the queue' entries */
+        } list [DAP_PROC_PRI_MAX];                                          /* An array of list according of priority numbers */
 } dap_proc_queue_t;
 
 dap_proc_queue_t *dap_proc_queue_create(dap_proc_thread_t * a_thread);
@@ -77,4 +77,5 @@ int dap_proc_queue_add_callback_inter(dap_events_socket_t * a_es_input, dap_proc
 
 int dap_proc_queue_add_callback_ext(dap_worker_t * a_worker, dap_proc_queue_callback_t a_callback, void * a_callback_arg, int a_pri);
 int dap_proc_queue_add_callback_inter_ext(dap_events_socket_t * a_es_input, dap_proc_queue_callback_t a_callback, void * a_callback_arg, int );
+int dap_proc_thread_add_callback_mt(dap_proc_thread_t * a_thread, dap_proc_queue_callback_t a_callback, void * a_callback_arg, int a_pri);
 
diff --git a/dap-sdk/net/core/include/dap_proc_thread.h b/dap-sdk/io/include/dap_proc_thread.h
similarity index 81%
rename from dap-sdk/net/core/include/dap_proc_thread.h
rename to dap-sdk/io/include/dap_proc_thread.h
index fb592d30cfe66020901a7aeba41bc4c0a8b5240c..e2b1e9fb5ec8efd2d70553b04fb9245a640fc845 100644
--- a/dap-sdk/net/core/include/dap_proc_thread.h
+++ b/dap-sdk/io/include/dap_proc_thread.h
@@ -27,7 +27,7 @@
 #include "dap_proc_queue.h"
 #include "dap_worker.h"
 #include "dap_common.h"
-
+#include "dap_context.h"
 typedef struct dap_proc_thread{
     uint32_t    cpu_id;
     pthread_t   thread_id;                                                  /* TID has been returned by pthread_create() */
@@ -43,27 +43,13 @@ typedef struct dap_proc_thread{
 
     dap_events_socket_t *queue_gdb_input;                                   /* Inputs for request to GDB, @RRL: #6238 */
 
-    int signal_kill;
-    int signal_exit;
+    dap_context_t * context;
 
     dap_events_socket_t * event_exit;
 
+    pthread_cond_t  started_cond;
+    pthread_mutex_t started_mutex ;
 
-#ifdef DAP_EVENTS_CAPS_EPOLL
-    EPOLL_HANDLE epoll_ctl;
-#elif defined (DAP_EVENTS_CAPS_POLL)
-    int poll_fd;
-    struct pollfd * poll;
-    dap_events_socket_t ** esockets;
-    size_t poll_count;
-    size_t poll_count_max;
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    int kqueue_fd;
-    struct kevent * kqueue_events;
-    int kqueue_events_count_max;
-#else
-#error "No poll for proc thread for your platform"
-#endif
     void * _inheritor;
 } dap_proc_thread_t;
 
@@ -83,10 +69,10 @@ int dap_proc_thread_esocket_write_inter(dap_proc_thread_t * a_thread,dap_worker_
 int dap_proc_thread_esocket_write_f_inter(dap_proc_thread_t * a_thread,dap_worker_t * a_worker,  dap_events_socket_uuid_t a_es_uuid,
                                         const char * a_format,...);
 
-int dap_proc_thread_esocket_update_poll_flags(dap_proc_thread_t * a_thread, dap_events_socket_t * a_esocket);
-
 typedef void (*dap_proc_worker_callback_t)(dap_worker_t *,void *);
 
-void dap_proc_thread_worker_exec_callback(dap_proc_thread_t * a_thread, size_t a_worker_id, dap_proc_worker_callback_t a_callback, void * a_arg);
+void dap_proc_thread_worker_exec_callback_inter(dap_proc_thread_t * a_thread, size_t a_worker_id, dap_proc_worker_callback_t a_callback, void * a_arg);
 
 int dap_proc_thread_assign_esocket_unsafe(dap_proc_thread_t * a_thread, dap_events_socket_t * a_esocket);
+
+
diff --git a/dap-sdk/net/core/include/dap_server.h b/dap-sdk/io/include/dap_server.h
similarity index 100%
rename from dap-sdk/net/core/include/dap_server.h
rename to dap-sdk/io/include/dap_server.h
diff --git a/dap-sdk/net/core/include/dap_timerfd.h b/dap-sdk/io/include/dap_timerfd.h
similarity index 100%
rename from dap-sdk/net/core/include/dap_timerfd.h
rename to dap-sdk/io/include/dap_timerfd.h
diff --git a/dap-sdk/net/core/include/dap_worker.h b/dap-sdk/io/include/dap_worker.h
similarity index 78%
rename from dap-sdk/net/core/include/dap_worker.h
rename to dap-sdk/io/include/dap_worker.h
index 4ddf9f9d30f40fc7e1caa1727e2d5c7ab96e2578..c9cf8201d45d171c089b95ea6f9fe59f538a647d 100644
--- a/dap-sdk/net/core/include/dap_worker.h
+++ b/dap-sdk/io/include/dap_worker.h
@@ -23,26 +23,24 @@
 #pragma once
 
 #include <pthread.h>
+#include <stdatomic.h>
 #include "dap_events_socket.h"
 #include "dap_proc_queue.h"
 #include "dap_common.h"
 #include "dap_events.h"
+#include "dap_context.h"
 
+typedef struct dap_context dap_context_t;
 //typedef struct dap_proc_queue dap_proc_queue_t;
 typedef struct dap_timerfd dap_timerfd_t;
 typedef struct dap_worker
 {
-    uint32_t id;
+    uint32_t  id;
     dap_events_t* events;
     dap_proc_queue_t* proc_queue;
     dap_events_socket_t *proc_queue_input;
 
-    uint32_t event_sockets_count;
-    pthread_rwlock_t esocket_rwlock;
-    dap_events_socket_t *esockets; // Hashmap of event sockets
-
-    // Signal to exit
-    int signal_exit;
+    atomic_uint event_sockets_count;
 
     // worker control queues
     dap_events_socket_t *queue_es_new; // Queue socket for new socket
@@ -64,30 +62,8 @@ typedef struct dap_worker
     dap_events_socket_t *queue_gdb_input;                                   /* Inputs for request to GDB, @RRL: #6238 */
 
     dap_timerfd_t * timer_check_activity;
-#if defined DAP_EVENTS_CAPS_MSMQ
-    HANDLE msmq_events[MAXIMUM_WAIT_OBJECTS];
-#endif
 
-#if defined DAP_EVENTS_CAPS_EPOLL
-    EPOLL_HANDLE epoll_fd;
-#elif defined ( DAP_EVENTS_CAPS_POLL)
-    int poll_fd;
-    struct pollfd * poll;
-    dap_events_socket_t ** poll_esocket;
-    atomic_uint poll_count;
-    size_t poll_count_max;
-    bool poll_compress; // Some of fd's became NULL so arrays need to be reassigned
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    int kqueue_fd;
-    struct kevent * kqueue_events_selected;
-    struct kevent * kqueue_events;
-    size_t kqueue_events_count;
-
-    int kqueue_events_count_max;
-    int kqueue_events_selected_count_max;
-#else
-#error "Not defined worker for your platform"
-#endif
+    dap_context_t *context;
     pthread_cond_t started_cond;
     pthread_mutex_t started_mutex;
     void * _inheritor;
@@ -124,7 +100,11 @@ extern "C" {
 int dap_worker_init( size_t a_conn_timeout );
 void dap_worker_deinit();
 
-int dap_worker_add_events_socket_unsafe( dap_events_socket_t * a_esocket, dap_worker_t * a_worker);
+static inline int dap_worker_add_events_socket_unsafe( dap_events_socket_t * a_esocket, dap_worker_t * a_worker)
+{
+    return dap_context_add_esocket(a_worker->context, a_esocket);
+}
+
 void dap_worker_add_events_socket(dap_events_socket_t * a_events_socket, dap_worker_t * a_worker);
 void dap_worker_add_events_socket_inter(dap_events_socket_t * a_es_input, dap_events_socket_t * a_events_socket);
 dap_worker_t *dap_worker_add_events_socket_auto( dap_events_socket_t * a_events_socket );
diff --git a/dap-sdk/net/core/libdap-net-core.pri b/dap-sdk/io/libdap-io.pri
similarity index 80%
rename from dap-sdk/net/core/libdap-net-core.pri
rename to dap-sdk/io/libdap-io.pri
index 2aa609cf66bb8c400a58bb40c9941aca317c1dbd..37dbe8509c076376eb21f8eb626019b0cc6a9cc2 100755
--- a/dap-sdk/net/core/libdap-net-core.pri
+++ b/dap-sdk/io/libdap-io.pri
@@ -5,7 +5,8 @@ HEADERS += $$PWD/include/dap_events.h \
     $$PWD/include/dap_proc_thread.h \
     $$PWD/include/dap_server.h \
     $$PWD/include/dap_timerfd.h \
-    $$PWD/include/dap_worker.h 
+    $$PWD/include/dap_context.h \
+    $$PWD/include/dap_worker.h
 
 SOURCES += $$PWD/dap_events.c \
     $$PWD/dap_events_socket.c \
@@ -14,6 +15,7 @@ SOURCES += $$PWD/dap_events.c \
     $$PWD/dap_proc_thread.c \
     $$PWD/dap_server.c \
     $$PWD/dap_timerfd.c \
-    $$PWD/dap_worker.c 
+    $$PWD/dap_context.c \
+    $$PWD/dap_worker.c
 
 INCLUDEPATH += $$PWD/include
diff --git a/dap-sdk/io/test/CMakeLists.txt b/dap-sdk/io/test/CMakeLists.txt
new file mode 100755
index 0000000000000000000000000000000000000000..a5a6ffe1a3685b504d2ff6938e80ad27c3fd855f
--- /dev/null
+++ b/dap-sdk/io/test/CMakeLists.txt
@@ -0,0 +1,17 @@
+project(server_io_test)
+
+if ( NOT ( TARGET dap_test ) )
+    add_subdirectory(libdap-test)
+endif()
+
+file(GLOB DAP_IO_TEST_SOURCES *.c)
+file(GLOB DAP_IO_TEST_HEADERS *.h)
+
+add_executable(${PROJECT_NAME} ${DAP_IO_TEST_SOURCES} ${DAP_IO_TEST_HEADERS})
+
+target_link_libraries(${PROJECT_NAME} dap_test dap_core dap_crypto dap_io)
+
+add_test(
+    NAME server_io_test
+    COMMAND server_io_test
+)
diff --git a/dap-sdk/net/core/test/dap_traffic_track_test.c b/dap-sdk/io/test/dap_traffic_track_test.c
similarity index 100%
rename from dap-sdk/net/core/test/dap_traffic_track_test.c
rename to dap-sdk/io/test/dap_traffic_track_test.c
diff --git a/dap-sdk/net/core/test/dap_traffic_track_test.h b/dap-sdk/io/test/dap_traffic_track_test.h
similarity index 100%
rename from dap-sdk/net/core/test/dap_traffic_track_test.h
rename to dap-sdk/io/test/dap_traffic_track_test.h
diff --git a/dap-sdk/net/core/test/main.c b/dap-sdk/io/test/main.c
similarity index 100%
rename from dap-sdk/net/core/test/main.c
rename to dap-sdk/io/test/main.c
diff --git a/dap-sdk/net/client/CMakeLists.txt b/dap-sdk/net/client/CMakeLists.txt
index 4c1645ab84c8b52b1adb456dca7bc21175fba756..a96449ad5fc2ad37f85bd075aca0e9ccbc8814c0 100644
--- a/dap-sdk/net/client/CMakeLists.txt
+++ b/dap-sdk/net/client/CMakeLists.txt
@@ -9,9 +9,9 @@ add_library(${PROJECT_NAME} STATIC ${DAP_CLIENT_HEADERS} ${DAP_CLIENT_SOURCES})
 
 
 if(DAPSDK_MODULES MATCHES "ssl-support")
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server dap_enc_server dap_stream dap_session dap_stream_ch json-c wolfssl)
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server dap_enc_server dap_stream dap_session dap_stream_ch json-c wolfssl)
 else()
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server dap_enc_server dap_stream dap_session dap_stream_ch json-c)
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server dap_enc_server dap_stream dap_session dap_stream_ch json-c)
 endif()
 if(UNIX AND NOT ANDROID AND NOT DARWIN)
     target_link_libraries(${PROJECT_NAME} rt)
diff --git a/dap-sdk/net/client/dap_client_http.c b/dap-sdk/net/client/dap_client_http.c
index 562f89d634f97a8158ed5c6b2a3c52c4ada70105..c321f6ab142e9920f10bf1b331aa478135a74b80 100644
--- a/dap-sdk/net/client/dap_client_http.c
+++ b/dap-sdk/net/client/dap_client_http.c
@@ -187,7 +187,7 @@ static bool s_timer_timeout_after_connected_check(void * a_arg)
 
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default()); // We're in own esocket context
     assert(l_worker);
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid( l_worker, *l_es_uuid_ptr);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid( l_worker->context, *l_es_uuid_ptr);
     if(l_es){
         dap_client_http_pvt_t * l_http_pvt = PVT(l_es);
         assert(l_http_pvt);
@@ -224,7 +224,7 @@ static bool s_timer_timeout_check(void * a_arg)
 
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default()); // We're in own esocket context
     assert(l_worker);
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid(l_worker->context, *l_es_uuid);
     if(l_es){
         if (l_es->flags & DAP_SOCK_CONNECTING ){
             dap_client_http_pvt_t * l_http_pvt = PVT(l_es);
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 75d8b06c0b2550e289243b6f775b534184c408ac..56a7fdae61c6ae27efd521d7a265e13793b3d24b 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -215,7 +215,7 @@ static void s_stream_connected(dap_client_pvt_t * a_client_pvt)
     dap_events_socket_uuid_t * l_es_uuid_ptr = DAP_NEW_Z(dap_events_socket_uuid_t);
     assert(a_client_pvt->stream_es);
     *l_es_uuid_ptr = a_client_pvt->stream_es->uuid;
-    if( dap_timerfd_start_on_worker(a_client_pvt->stream_es->worker, s_client_timeout_active_after_connect_seconds * 1000, s_stream_timer_timeout_after_connected_check ,l_es_uuid_ptr) == NULL ){
+    if( dap_timerfd_start_on_worker(a_client_pvt->stream_es->context->worker, s_client_timeout_active_after_connect_seconds * 1000, s_stream_timer_timeout_after_connected_check ,l_es_uuid_ptr) == NULL ){
         log_it(L_ERROR,"Can't run timer for stream after connect check for esocket uuid %"DAP_UINT64_FORMAT_U, *l_es_uuid_ptr);
         DAP_DEL_Z(l_es_uuid_ptr);
     }
@@ -233,7 +233,7 @@ static bool s_stream_timer_timeout_check(void * a_arg)
     dap_worker_t *l_worker = dap_events_get_current_worker(dap_events_get_default());
     assert(l_worker);
 
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid(l_worker->context, *l_es_uuid_ptr);
     if(l_es){
         if (l_es->flags & DAP_SOCK_CONNECTING ){
             dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
@@ -275,7 +275,7 @@ static bool s_stream_timer_timeout_after_connected_check(void * a_arg)
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default());
     assert(l_worker);
 
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid(l_worker->context, *l_es_uuid_ptr);
     if( l_es ){
         dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
         if (dap_client_pvt_find(l_client_pvt->uuid)) {
@@ -315,7 +315,7 @@ static bool s_enc_init_delay_before_request_timer_callback(void * a_arg)
     assert (a_arg);
     dap_events_socket_uuid_t* l_es_uuid_ptr = (dap_events_socket_uuid_t*) a_arg;
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default());
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid_ptr);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid(l_worker->context, *l_es_uuid_ptr);
     if(l_es){
         dap_client_pvt_t *l_client_pvt = DAP_ESOCKET_CLIENT_PVT(l_es);
         s_stage_status_after(l_client_pvt);
diff --git a/dap-sdk/net/client/test/CMakeLists.txt b/dap-sdk/net/client/test/CMakeLists.txt
index 065db522c9ca6c0ce661dc47e244e3f7c16cf6dc..db92897878bba8f5c160c4ad3dd2fd24ea4d324d 100755
--- a/dap-sdk/net/client/test/CMakeLists.txt
+++ b/dap-sdk/net/client/test/CMakeLists.txt
@@ -10,7 +10,7 @@ file(GLOB DAP_CLIENT_TEST_HEADERS *.h)
 
 add_executable(${PROJECT_NAME} ${DAP_CLIENT_TEST_SOURCES} ${DAP_CLIENT_TEST_HEADERS})
 
-target_link_libraries(${PROJECT_NAME} dap_test dap_core dap_crypto dap_server_core ev pthread)
+target_link_libraries(${PROJECT_NAME} dap_test dap_core dap_crypto dap_io ev pthread)
 
 add_test(
     NAME dap_client_test
diff --git a/dap-sdk/net/core/dap_proc_thread.c b/dap-sdk/net/core/dap_proc_thread.c
deleted file mode 100644
index 6a4151e277e7d370a45d2fd73560a166802337bf..0000000000000000000000000000000000000000
--- a/dap-sdk/net/core/dap_proc_thread.c
+++ /dev/null
@@ -1,1111 +0,0 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Ltd.   https://demlabs.net
- * Copyright  (c) 2020
- * All rights reserved.
-
- This file is part of DAP SDK the open source project
-
-    DAP SDK is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP SDK is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    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/>.
-*/
-#include <errno.h>
-#include <stdatomic.h>
-
-#include "dap_config.h"
-#include "dap_list.h"
-#include "dap_events.h"
-#include "dap_events_socket.h"
-#include "dap_proc_thread.h"
-#include "dap_server.h"
-
-#if defined(DAP_EVENTS_CAPS_EPOLL) && !defined(DAP_OS_WINDOWS)
-#include <sys/epoll.h>
-#elif defined DAP_OS_WINDOWS
-#include "wepoll.h"
-#elif defined (DAP_EVENTS_CAPS_POLL)
-#include <poll.h>
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-
-#include <sys/event.h>
-#include <err.h>
-
-#ifndef DAP_OS_DARWIN
-#include <pthread_np.h>
-typedef cpuset_t cpu_set_t; // Adopt BSD CPU setstructure to POSIX variant
-#else
-#define NOTE_READ NOTE_LOWAT
-#endif
-
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL SO_NOSIGPIPE
-#endif
-
-#else
-#error "Unimplemented poll for this platform"
-#endif
-
-#define LOG_TAG "dap_proc_thread"
-
-static size_t s_threads_count = 0;
-static dap_proc_thread_t * s_threads = NULL;
-
-static dap_slist_t s_custom_threads = $DAP_SLIST_INITALIZER;                    /* Customized proc threads out of the pool */
-static pthread_rwlock_t s_custom_threads_rwlock = PTHREAD_RWLOCK_INITIALIZER;   /* Lock to protect <s_custom_threads> */
-
-
-static void *s_proc_thread_function(void * a_arg);
-static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags);
-
-/**
- * @brief dap_proc_thread_init
- * @param a_cpu_count 0 means autodetect
- * @return
- */
-static pthread_cond_t  s_started_cond = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t s_started_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-int dap_proc_thread_init(uint32_t a_threads_count)
-{
-int l_ret = 0;
-
-    s_threads_count = a_threads_count ? a_threads_count : dap_get_cpu_count( );
-    s_threads = DAP_NEW_Z_SIZE(dap_proc_thread_t, sizeof (dap_proc_thread_t)* s_threads_count);
-
-    for (uint32_t i = 0; i < s_threads_count; i++ )
-    {
-        s_threads[i].cpu_id = i;
-        pthread_mutex_lock( &s_started_mutex );
-
-        if ( (l_ret = pthread_create( &s_threads[i].thread_id,NULL, s_proc_thread_function, &s_threads[i] )) ) {
-            log_it(L_CRITICAL, "Create thread failed with code %d", l_ret);
-            pthread_mutex_unlock( &s_started_mutex );
-            return l_ret;
-        }
-
-        pthread_cond_wait( &s_started_cond, &s_started_mutex);
-        pthread_mutex_unlock( &s_started_mutex);
-    }
-
-    return l_ret;
-}
-
-/**
- * @brief dap_proc_thread_deinit
- */
-void dap_proc_thread_deinit()
-{
-int l_rc;
-size_t l_sz;
-dap_proc_thread_t *l_proc_thread;
-
-    for (uint32_t i = s_threads_count; i--; ){
-        dap_events_socket_event_signal(s_threads[i].event_exit, 1);
-        pthread_join(s_threads[i].thread_id, NULL);
-    }
-
-    // Cleaning custom proc threads
-    pthread_rwlock_wrlock(&s_custom_threads_rwlock);
-
-    for ( uint32_t i = s_custom_threads.nr; i--; ) {
-        if ( s_dap_slist_get4head (&s_custom_threads, (void **) &l_proc_thread, &l_sz) )
-            break;
-
-        dap_events_socket_event_signal(l_proc_thread->event_exit, 1);
-        pthread_join(l_proc_thread->thread_id, NULL);
-        DAP_DELETE(l_proc_thread);
-    }
-
-    pthread_rwlock_unlock(&s_custom_threads_rwlock);
-
-    // Signal to cancel working threads and wait for finish
-    // TODO: Android realization
-//#ifndef DAP_OS_ANDROID
-//    for (size_t i = 0; i < s_threads_count; i++ ){
-//        pthread_cancel(s_threads[i].thread_id);
-//        pthread_join(s_threads[i].thread_id, NULL);
-//    }
-//#endif
-
-}
-
-/**
- * @brief dap_proc_thread_get
- * @param a_cpu_id
- * @return
- */
-dap_proc_thread_t * dap_proc_thread_get(uint32_t a_cpu_id)
-{
-    return (a_cpu_id < s_threads_count) ? &s_threads[a_cpu_id] : NULL;
-}
-
-/**
- * @brief dap_proc_thread_get_auto
- * @return
- */
-dap_proc_thread_t * dap_proc_thread_get_auto()
-{
-unsigned l_id_min = 0, l_size_min = UINT32_MAX, l_queue_size;
-
-    for (size_t i = 0; i < s_threads_count; i++ )
-    {
-        l_queue_size = atomic_load(&s_threads[i].proc_queue_size);
-
-        if( l_queue_size < l_size_min ){
-            l_size_min = l_queue_size;
-            l_id_min = i;
-        }
-    }
-
-    return &s_threads[l_id_min];
-}
-
-/**
- * @brief dap_proc_thread_run_custom Create custom proc thread for specified task
- * @return
- */
-dap_proc_thread_t * dap_proc_thread_run_custom(void)
-{
-dap_proc_thread_t * l_proc_thread = DAP_NEW_Z(dap_proc_thread_t);
-int l_ret;
-
-    if (l_proc_thread == NULL)
-        return  log_it(L_CRITICAL,"Out of memory, can't create new proc thread, errno=%d", errno), NULL;
-
-    pthread_mutex_lock( &s_started_mutex );
-
-    if ( (l_ret = pthread_create( &l_proc_thread->thread_id ,NULL, s_proc_thread_function, l_proc_thread  )) ) {
-        log_it(L_CRITICAL, "Create thread failed with code %d", l_ret);
-        DAP_DEL_Z (l_proc_thread);
-    }else{
-        pthread_cond_wait( &s_started_cond, &s_started_mutex);
-        pthread_rwlock_wrlock(&s_custom_threads_rwlock);
-        assert ( !s_dap_slist_add2tail (&s_custom_threads, l_proc_thread, sizeof(l_proc_thread)) );
-        pthread_rwlock_unlock(&s_custom_threads_rwlock);
-    }
-
-    pthread_mutex_unlock( &s_started_mutex );
-    return l_proc_thread;
-}
-
-/**
- * @brief s_proc_event_callback - get from queue next element and execute action routine,
- *  repeat execution depending on status is returned by action routine.
- *
- * @param a_esocket
- * @param a_value
- *
- */
-static void s_proc_event_callback(dap_events_socket_t * a_esocket, uint64_t __attribute__((unused))  a_value)
-{
-dap_proc_thread_t   *l_thread;
-dap_proc_queue_item_t *l_item;
-int     l_rc, l_is_anybody_in_queue, l_is_finished, l_iter_cnt, l_cur_pri;
-size_t  l_item_sz;
-dap_proc_queue_t    *l_queue;
-
-    debug_if (g_debug_reactor, L_DEBUG, "--> Proc event callback start, a_esocket:%p ", a_esocket);
-
-    if ( !(l_thread = (dap_proc_thread_t *) a_esocket->_inheritor) )
-        {
-        log_it(L_ERROR, "NULL <dap_proc_thread_t> context is detected");
-        return;
-        }
-
-    l_iter_cnt = l_is_anybody_in_queue = 0;
-    /*@RRL:  l_iter_cnt = DAP_QUE$K_ITER_NR; */
-    l_queue = l_thread->proc_queue;
-
-    for (l_cur_pri = (DAP_QUE$K_PRIMAX - 1); l_cur_pri; l_cur_pri--, l_iter_cnt++ ) /* Run from higest to lowest ... */
-    {
-        if ( !l_queue->list[l_cur_pri].items.nr )                           /* A lockless quick check */
-            continue;
-
-        pthread_mutex_lock(&l_queue->list[l_cur_pri].lock);                 /* Protect list from other threads */
-        l_rc = s_dap_slist_get4head (&l_queue->list[l_cur_pri].items, (void **) &l_item, &l_item_sz);
-        pthread_mutex_unlock(&l_queue->list[l_cur_pri].lock);
-
-        if  ( l_rc == -ENOENT ) {                                           /* Queue is empty ? */
-            debug_if (g_debug_reactor, L_DEBUG, "a_esocket:%p - nothing to do at prio: %d ", a_esocket, l_cur_pri);
-            continue;
-        }
-
-        debug_if (g_debug_reactor, L_INFO, "Proc event callback: %p/%p, prio=%d, iteration=%d",
-                       l_item->callback, l_item->callback_arg, l_cur_pri, l_iter_cnt);
-
-        l_is_finished = l_item->callback(l_thread, l_item->callback_arg);
-
-        debug_if (g_debug_reactor, L_INFO, "Proc event callback: %p/%p, prio=%d, iteration=%d - is %sfinished",
-                           l_item->callback, l_item->callback_arg, l_cur_pri, l_iter_cnt, l_is_finished ? "" : "not ");
-
-        if ( !(l_is_finished) ) {
-                                                                            /* Rearm callback to be executed again */
-            pthread_mutex_lock(&l_queue->list[l_cur_pri].lock);
-            l_rc = s_dap_slist_add2tail (&l_queue->list[l_cur_pri].items, l_item, l_item_sz );
-            pthread_mutex_unlock(&l_queue->list[l_cur_pri].lock);
-
-            if ( l_rc ) {
-                log_it(L_ERROR, "Error requeue event callback: %p/%p, errno=%d", l_item->callback, l_item->callback_arg, l_rc);
-                DAP_DELETE(l_item);
-            }
-        }
-        else    {
-            DAP_DELETE(l_item);
-    	}
-    }
-    for (l_cur_pri = (DAP_QUE$K_PRIMAX - 1); l_cur_pri; l_cur_pri--)        /* Really ?! */
-        l_is_anybody_in_queue += l_queue->list[l_cur_pri].items.nr;
-
-    if ( l_is_anybody_in_queue )                                            /* Arm event if we have something to proc again */
-        dap_events_socket_event_signal(a_esocket, 1);
-
-    debug_if(g_debug_reactor, L_DEBUG, "<-- Proc event callback end, items rest: %d, iterations: %d", l_is_anybody_in_queue, l_iter_cnt);
-}
-
-
-/**
- * @brief dap_proc_thread_assign_esocket_unsafe
- * @param a_thread
- * @param a_esocket
- * @return
- */
-int dap_proc_thread_assign_esocket_unsafe(dap_proc_thread_t * a_thread, dap_events_socket_t * a_esocket)
-{
-    assert(a_esocket);
-    assert(a_thread);
-    a_esocket->proc_thread = a_thread;
-
-#ifdef DAP_EVENTS_CAPS_EPOLL
-        // Init events for EPOLL
-        a_esocket->ev.events = a_esocket->ev_base_flags ;
-        if(a_esocket->flags & DAP_SOCK_READY_TO_READ )
-            a_esocket->ev.events |= EPOLLIN;
-        if(a_esocket->flags & DAP_SOCK_READY_TO_WRITE )
-            a_esocket->ev.events |= EPOLLOUT;
-        a_esocket->ev.data.ptr = a_esocket;
-        return epoll_ctl(a_thread->epoll_ctl, EPOLL_CTL_ADD, a_esocket->socket, &a_esocket->ev);
-#elif defined (DAP_EVENTS_CAPS_POLL)
-    if (  a_thread->poll_count == a_thread->poll_count_max ){ // realloc
-        a_thread->poll_count_max *= 2;
-        log_it(L_WARNING, "Too many descriptors (%zu), resizing array twice to %zu", a_thread->poll_count, a_thread->poll_count_max);
-        a_thread->poll =DAP_REALLOC(a_thread->poll, a_thread->poll_count_max * sizeof(*a_thread->poll));
-        a_thread->esockets =DAP_REALLOC(a_thread->esockets, a_thread->poll_count_max * sizeof(*a_thread->esockets));
-    }
-
-    a_thread->poll[a_thread->poll_count].fd = a_thread->proc_queue->esocket->fd;
-    a_thread->poll[a_thread->poll_count].events = a_thread->proc_queue->esocket->poll_base_flags;
-    a_thread->esockets[a_thread->poll_count] = a_thread->proc_queue->esocket;
-    a_thread->poll_count++;
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-/*    u_short l_flags = a_esocket->kqueue_base_flags;
-    u_int   l_fflags = a_esocket->kqueue_base_fflags;
-    short l_filter = a_esocket->kqueue_base_filter;
-        if(a_esocket->flags & DAP_SOCK_READY_TO_READ )
-            l_fflags |= NOTE_READ;
-        if(a_esocket->flags & DAP_SOCK_READY_TO_WRITE )
-            l_fflags |= NOTE_WRITE;
-
-        EV_SET(&a_esocket->kqueue_event , a_esocket->socket, l_filter, EV_ADD| l_flags | EV_CLEAR, l_fflags,0, a_esocket);
-        return kevent ( a_thread->kqueue_fd,&a_esocket->kqueue_event,1,NULL,0,NULL)==1 ? 0 : -1 ;
-*/
-    // Nothing to do if its input
-    if ( a_esocket->type == DESCRIPTOR_TYPE_QUEUE && a_esocket->pipe_out)
-        return 0;
-#else
-#error "Unimplemented new esocket on worker callback for current platform"
-#endif
-
-    return dap_proc_thread_esocket_update_poll_flags(a_thread,a_esocket);
-}
-
-/**
- * @brief dap_proc_thread_esocket_update_poll_flags
- * @param a_thread
- * @param a_esocket
- * @return
- */
-int dap_proc_thread_esocket_update_poll_flags(dap_proc_thread_t * a_thread, dap_events_socket_t * a_esocket)
-{
-#ifdef DAP_EVENTS_CAPS_EPOLL
-    u_int events = a_esocket->ev_base_flags;
-    if( a_esocket->flags & DAP_SOCK_READY_TO_READ) {
-        events |= EPOLLIN;
-#ifdef DAP_OS_WINDOWS
-        events ^= EPOLLONESHOT;
-#endif
-    }
-    if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE) {
-        events |= EPOLLOUT;
-#ifdef DAP_OS_WINDOWS
-        events |= EPOLLONESHOT;
-#endif
-    }
-    a_esocket->ev.events = events;
-    if( epoll_ctl(a_thread->epoll_ctl, EPOLL_CTL_MOD, a_esocket->socket, &a_esocket->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-        log_it(L_CRITICAL, "Can't add proc queue on epoll ctl, err: %d", errno);
-        return -1;
-    }
-#elif defined (DAP_EVENTS_CAPS_POLL)
-    if (  a_thread->poll_count == a_thread->poll_count_max ){ // realloc
-        a_thread->poll_count_max *= 2;
-        log_it(L_WARNING, "Too many descriptors (%zu), resizing array twice to %zu", a_thread->poll_count, a_thread->poll_count_max);
-        a_thread->poll =DAP_REALLOC(a_thread->poll, a_thread->poll_count_max * sizeof(*a_thread->poll));
-        a_thread->esockets =DAP_REALLOC(a_thread->esockets, a_thread->poll_count_max * sizeof(*a_thread->esockets));
-    }
-    a_thread->poll[a_esocket->poll_index].events= a_esocket->poll_base_flags;
-    if( a_esocket->flags & DAP_SOCK_READY_TO_READ)
-        a_thread->poll[a_esocket->poll_index].events |= POLLIN;
-    if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE)
-        a_thread->poll[a_esocket->poll_index].events |= POLLOUT;
-
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-
-    u_short l_flags = a_esocket->kqueue_base_flags;
-    u_int   l_fflags = a_esocket->kqueue_base_fflags;
-    short l_filter = a_esocket->kqueue_base_filter;
-    int l_kqueue_fd = a_esocket->proc_thread ? a_esocket->proc_thread->kqueue_fd : -1;
-    if ( l_kqueue_fd == -1 ){
-        log_it(L_ERROR, "Esocket is not assigned with anything ,exit");
-    }
-    struct kevent * l_event = &a_esocket->kqueue_event;
-    // Check & add
-    int l_is_error=false;
-    int l_errno=0;
-    if (a_esocket->type == DESCRIPTOR_TYPE_EVENT || a_esocket->type == DESCRIPTOR_TYPE_QUEUE){
-        EV_SET(l_event, a_esocket->socket, EVFILT_USER,EV_ADD| EV_CLEAR ,0,0, &a_esocket->kqueue_event_catched_data );
-        if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL)!=0){
-            l_is_error = true;
-            l_errno = errno;
-        }
-    }else{
-        EV_SET(l_event, a_esocket->socket, l_filter,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-        if( a_esocket->flags & DAP_SOCK_READY_TO_READ ){
-            EV_SET(l_event, a_esocket->socket, EVFILT_READ,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-            if( kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) != 1 ){
-                l_is_error = true;
-                l_errno = errno;
-            }
-        }
-        if( !l_is_error){
-            if( a_esocket->flags & DAP_SOCK_READY_TO_WRITE || a_esocket->flags &DAP_SOCK_CONNECTING ){
-                EV_SET(l_event, a_esocket->socket, EVFILT_WRITE,l_flags| EV_ADD,l_fflags,a_esocket->kqueue_data,a_esocket);
-                if(kevent( l_kqueue_fd,l_event,1,NULL,0,NULL) != 1){
-                    l_is_error = true;
-                    l_errno = errno;
-                }
-            }
-        }
-    }
-
-    if ( l_is_error){
-        char l_errbuf[128];
-        l_errbuf[0]=0;
-        strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-        log_it(L_ERROR,"Can't update client socket state on kqueue fd %d: \"%s\" (%d)",
-            l_kqueue_fd, l_errbuf, l_errno);
-    }
-
-#else
-#error "Not defined dap_proc_thread.c::s_update_poll_flags() on your platform"
-#endif
-    return 0;
-}
-
-/**
- * @brief dap_proc_thread_create_queue_ptr
- * @details Call this function as others only from safe situation, or, thats better, from a_thread's context
- * @param a_thread
- * @param a_callback
- * @return
- */
-dap_events_socket_t * dap_proc_thread_create_queue_ptr(dap_proc_thread_t * a_thread, dap_events_socket_callback_queue_ptr_t a_callback)
-{
-    dap_events_socket_t * l_es = dap_events_socket_create_type_queue_ptr_unsafe(NULL,a_callback);
-    if(l_es == NULL)
-        return NULL;
-    l_es->proc_thread = a_thread;
-    dap_proc_thread_assign_esocket_unsafe (a_thread, l_es);
-    return l_es;
-}
-
-/**
- * @brief s_proc_thread_function
- * @param a_arg
- * @return
- */
-static void * s_proc_thread_function(void * a_arg)
-{
-
-    dap_proc_thread_t * l_thread = (dap_proc_thread_t*) a_arg;
-    assert(l_thread);
-    dap_cpu_assign_thread_on(l_thread->cpu_id);
-
-    struct sched_param l_shed_params;
-    l_shed_params.sched_priority = 0;
-#if defined(DAP_OS_WINDOWS)
-    if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST))
-        log_it(L_ERROR, "Couldn't set thread priority, err: %lu", GetLastError());
-#elif defined (DAP_OS_LINUX)
-    pthread_setschedparam(pthread_self(),SCHED_BATCH ,&l_shed_params);
-#elif defined (DAP_OS_BSD)
-    pthread_setschedparam(pthread_self(),SCHED_OTHER ,&l_shed_params);
-#else
-#error "Undefined set sched param"
-#endif
-    l_thread->proc_queue = dap_proc_queue_create(l_thread);
-
-    // Init proc_queue for related worker
-    dap_worker_t * l_worker_related = dap_events_worker_get(l_thread->cpu_id);
-    assert(l_worker_related);
-    l_worker_related->proc_queue = l_thread->proc_queue;
-    l_worker_related->proc_queue_input = dap_events_socket_queue_ptr_create_input(l_worker_related->proc_queue->esocket);
-
-    dap_events_socket_assign_on_worker_mt(l_worker_related->proc_queue_input,l_worker_related);
-
-    l_thread->proc_event = dap_events_socket_create_type_event_unsafe(NULL, s_proc_event_callback);
-    l_thread->event_exit = dap_events_socket_create_type_event_unsafe(NULL, s_event_exit_callback);
-
-    l_thread->proc_event->_inheritor = l_thread; // we pass thread through it
-    l_thread->event_exit->_inheritor = l_thread;
-
-    size_t l_workers_count= dap_events_worker_get_count();
-    assert(l_workers_count);
-    l_thread->queue_assign_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
-    l_thread->queue_io_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
-    l_thread->queue_callback_input = DAP_NEW_Z_SIZE(dap_events_socket_t*, sizeof (dap_events_socket_t*)*l_workers_count  );
-
-    assert(l_thread->queue_assign_input);
-    assert(l_thread->queue_io_input);
-    for (size_t n=0; n<l_workers_count; n++){
-        dap_worker_t * l_worker =dap_events_worker_get(n);
-        l_thread->queue_assign_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_new );
-        l_thread->queue_io_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_es_io );
-        l_thread->queue_callback_input[n] = dap_events_socket_queue_ptr_create_input(l_worker->queue_callback );
-    }
-#ifdef DAP_EVENTS_CAPS_EPOLL
-    struct epoll_event l_epoll_events[ DAP_EVENTS_SOCKET_MAX]= { { 0 } };
-
-    // Create epoll ctl
-    l_thread->epoll_ctl = epoll_create( DAP_EVENTS_SOCKET_MAX );
-
-    // add proc queue
-    l_thread->proc_queue->esocket->ev.events    = l_thread->proc_queue->esocket->ev_base_flags;
-    l_thread->proc_queue->esocket->ev.data.ptr  = l_thread->proc_queue->esocket;
-    if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->proc_queue->esocket->socket , &l_thread->proc_queue->esocket->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-        log_it(L_CRITICAL, "Can't add proc queue %zu on epoll ctl, error %d", l_thread->proc_queue->esocket->socket, errno);
-        return NULL;
-    }
-
-    // Add proc event
-    l_thread->proc_event->ev.events     = l_thread->proc_event->ev_base_flags ;
-    l_thread->proc_event->ev.data.ptr   = l_thread->proc_event;
-    if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->proc_event->socket , &l_thread->proc_event->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-        log_it(L_CRITICAL, "Can't add proc event on epoll ctl, err: %d", errno);
-        return NULL;
-    }
-
-    // Add exit event
-    l_thread->event_exit->ev.events     = l_thread->event_exit->ev_base_flags;
-    l_thread->event_exit->ev.data.ptr   = l_thread->event_exit;
-    if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->event_exit->socket , &l_thread->event_exit->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-        log_it(L_CRITICAL, "Can't add exit event on epoll ctl, err: %d", errno);
-        return NULL;
-    }
-
-    for (size_t n = 0; n< dap_events_worker_get_count(); n++){
-        // Queue asssign
-        l_thread->queue_assign_input[n]->ev.events      = l_thread->queue_assign_input[n]->ev_base_flags ;
-        l_thread->queue_assign_input[n]->ev.data.ptr    = l_thread->queue_assign_input[n];
-        if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->queue_assign_input[n]->socket, &l_thread->queue_assign_input[n]->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-            log_it(L_CRITICAL, "Can't add queue input on epoll ctl, err: %d", errno);
-            return NULL;
-        }
-
-        // Queue IO
-        l_thread->queue_io_input[n]->ev.events      = l_thread->queue_io_input[n]->ev_base_flags ;
-        l_thread->queue_io_input[n]->ev.data.ptr    = l_thread->queue_io_input[n];
-        if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->queue_io_input[n]->fd , &l_thread->queue_io_input[n]->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-            log_it(L_CRITICAL, "Can't add proc io input on epoll ctl, err: %d", errno);
-            return NULL;
-        }
-
-        // Queue callback
-        l_thread->queue_callback_input[n]->ev.events      = l_thread->queue_callback_input[n]->ev_base_flags ;
-        l_thread->queue_callback_input[n]->ev.data.ptr    = l_thread->queue_callback_input[n];
-        if( epoll_ctl(l_thread->epoll_ctl, EPOLL_CTL_ADD, l_thread->queue_callback_input[n]->fd , &l_thread->queue_callback_input[n]->ev) != 0 ){
-#ifdef DAP_OS_WINDOWS
-        errno = WSAGetLastError();
-#endif
-            log_it(L_CRITICAL, "Can't add proc io input on epoll ctl, err: %d", errno);
-            return NULL;
-        }
-    }
-#elif defined(DAP_EVENTS_CAPS_POLL)
-    l_thread->poll_count_max = DAP_EVENTS_SOCKET_MAX;
-    l_thread->poll_count = 0;
-    int l_poll_compress = false;
-    l_thread->poll = DAP_NEW_Z_SIZE(struct pollfd,l_thread->poll_count_max *sizeof (*l_thread->poll));
-    l_thread->esockets = DAP_NEW_Z_SIZE(dap_events_socket_t*,l_thread->poll_count_max *sizeof (*l_thread->esockets));
-
-    // Add proc queue
-    dap_proc_thread_assign_esocket_unsafe(l_thread,l_thread->proc_queue->esocket);
-
-    // Add proc event
-    l_thread->poll[l_thread->poll_count].fd = l_thread->proc_event->fd;
-    l_thread->poll[l_thread->poll_count].events = l_thread->proc_event->poll_base_flags;
-    l_thread->esockets[l_thread->poll_count] = l_thread->proc_event;
-    l_thread->poll_count++;
-
-    // Add exit event
-    l_thread->poll[l_thread->poll_count].fd = l_thread->event_exit->fd;
-    l_thread->poll[l_thread->poll_count].events = l_thread->event_exit->poll_base_flags;
-    l_thread->esockets[l_thread->poll_count] = l_thread->event_exit;
-    l_thread->poll_count++;
-
-    for (size_t n = 0; n< dap_events_worker_get_count(); n++){
-        dap_events_socket_t * l_queue_assign_input =  l_thread->queue_assign_input[n];
-        dap_events_socket_t * l_queue_io_input =  l_thread->queue_io_input[n];
-        dap_events_socket_t * l_queue_callback_input =  l_thread->queue_callback_input[n];
-        if (l_queue_assign_input&&l_queue_io_input){
-
-            // Queue assign input
-            l_queue_assign_input->poll_index = l_thread->poll_count;
-            l_thread->poll[l_thread->poll_count].fd = l_queue_assign_input->fd;
-            l_thread->poll[l_thread->poll_count].events = l_queue_assign_input->poll_base_flags;
-            l_thread->esockets[l_thread->poll_count] = l_queue_assign_input;
-            l_thread->poll_count++;
-
-            // Queue io input
-            l_queue_io_input->poll_index = l_thread->poll_count;
-            l_thread->poll[l_thread->poll_count].fd = l_queue_io_input->fd;
-            l_thread->poll[l_thread->poll_count].events = l_queue_io_input->poll_base_flags;
-            l_thread->esockets[l_thread->poll_count] = l_queue_io_input;
-            l_thread->poll_count++;
-
-            // Queue callback input
-            l_queue_callback_input->poll_index = l_thread->poll_count;
-            l_thread->poll[l_thread->poll_count].fd = l_queue_callback_input->fd;
-            l_thread->poll[l_thread->poll_count].events = l_queue_callback_input->poll_base_flags;
-            l_thread->esockets[l_thread->poll_count] = l_queue_callback_input;
-            l_thread->poll_count++;
-        }
-    }
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-    // Create kqueue fd
-    l_thread->kqueue_fd = kqueue();
-    l_thread->kqueue_events_count_max = DAP_EVENTS_SOCKET_MAX;
-    l_thread->kqueue_events = DAP_NEW_Z_SIZE(struct kevent, l_thread->kqueue_events_count_max *sizeof(struct kevent));
-
-    dap_proc_thread_assign_esocket_unsafe(l_thread,l_thread->proc_queue->esocket);
-    dap_proc_thread_assign_esocket_unsafe(l_thread,l_thread->proc_event);
-    dap_proc_thread_assign_esocket_unsafe(l_thread,l_thread->event_exit);
-
-    for (size_t n = 0; n< dap_events_worker_get_count(); n++){
-        // Queue asssign
-        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_assign_input[n]);
-
-        // Queue IO
-        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_io_input[n]);
-
-        // Queue callback
-        dap_proc_thread_assign_esocket_unsafe(l_thread, l_thread->queue_callback_input[n]);
-    }
-
-#else
-#error "Unimplemented poll events analog for this platform"
-#endif
-
-    //We've started!
-    pthread_mutex_lock(&s_started_mutex);
-    pthread_mutex_unlock(&s_started_mutex);
-    pthread_cond_broadcast(&s_started_cond);
-
-    l_thread->signal_exit = false;
-
-    // Main loop
-    while (!l_thread->signal_kill && !l_thread->signal_exit){
-
-        int l_selected_sockets;
-        size_t l_sockets_max;
-#ifdef DAP_EVENTS_CAPS_EPOLL
-        //log_it(L_DEBUG, "Epoll_wait call");
-        l_selected_sockets = epoll_wait(l_thread->epoll_ctl, l_epoll_events, DAP_EVENTS_SOCKET_MAX, -1);
-        l_sockets_max = (size_t)l_selected_sockets;
-#elif defined (DAP_EVENTS_CAPS_POLL)
-        l_selected_sockets = poll(l_thread->poll,l_thread->poll_count,-1);
-        l_sockets_max = l_thread->poll_count;
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-        l_selected_sockets = kevent(l_thread->kqueue_fd,NULL,0,l_thread->kqueue_events,l_thread->kqueue_events_count_max,NULL);
-        l_sockets_max = l_selected_sockets;
-#else
-#error "Unimplemented poll wait analog for this platform"
-#endif
-
-        if(l_selected_sockets == -1) {
-            if( errno == EINTR)
-                continue;
-#if defined DAP_OS_UNIX
-            int l_errno = errno;
-            char l_errbuf[128];
-            strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-            log_it(L_ERROR, "Proc thread #%d got errno:\"%s\" (%d)", l_thread->cpu_id , l_errbuf, l_errno);
-#elif DAP_OS_WINDOWS
-            log_it(L_ERROR, "Error occured on thread #%d, errno: %d", l_thread->cpu_id , errno);
-#endif
-            break;
-        }
-        for(size_t n = 0; n < l_sockets_max; n++) {
-            dap_events_socket_t * l_cur;
-            int l_flag_hup, l_flag_rdhup, l_flag_read, l_flag_write, l_flag_error,
-                    l_flag_nval,l_flag_pri,l_flag_msg;
-#ifdef DAP_EVENTS_CAPS_EPOLL
-            l_cur = (dap_events_socket_t *) l_epoll_events[n].data.ptr;
-            uint32_t l_cur_events = l_epoll_events[n].events;
-            l_flag_hup = l_cur_events & EPOLLHUP;
-            l_flag_rdhup = l_cur_events & EPOLLHUP;
-            l_flag_write = l_cur_events & EPOLLOUT;
-            l_flag_read = l_cur_events & EPOLLIN;
-            l_flag_error = l_cur_events & EPOLLERR;
-            l_flag_nval = false;
-            l_flag_pri = false;
-            l_flag_msg = false;
-#elif defined ( DAP_EVENTS_CAPS_POLL)
-            if(n>=l_thread->poll_count){
-                log_it(L_WARNING,"selected_sockets(%d) is bigger then poll count (%zu)", l_selected_sockets, l_thread->poll_count);
-                break;
-            }
-            short l_cur_events = l_thread->poll[n].revents ;
-            if (!l_cur_events)
-                continue;
-            l_cur = l_thread->esockets[n];
-            l_flag_hup =  l_cur_events& POLLHUP;
-            l_flag_rdhup = l_cur_events & POLLRDHUP;
-            l_flag_write = (l_cur_events & POLLOUT) || (l_cur_events &POLLRDNORM)|| (l_cur_events &POLLRDBAND ) ;
-            l_flag_read = l_cur_events & POLLIN || (l_cur_events &POLLWRNORM)|| (l_cur_events &POLLWRBAND );
-            l_flag_error = l_cur_events & POLLERR;
-            l_flag_nval = l_cur_events & POLLNVAL;
-            l_flag_pri = l_cur_events & POLLPRI;
-            l_flag_msg = l_cur_events & POLLMSG;
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-            struct kevent * l_kevent = &l_thread->kqueue_events[n];
-            l_flag_hup=l_flag_rdhup=l_flag_read=l_flag_write=l_flag_error=l_flag_nval=l_flag_msg =l_flag_pri = false;
-
-            if (l_kevent->filter & EVFILT_USER){
-                dap_events_socket_w_data_t * l_es_w_data = (dap_events_socket_w_data_t*) l_kevent->udata;
-                assert(l_es_w_data);
-                l_cur = l_es_w_data->esocket;
-                assert(l_cur);
-                memcpy(&l_cur->kqueue_event_catched_data,l_es_w_data,sizeof(*l_es_w_data));
-                if(l_es_w_data != &l_cur->kqueue_event_catched_data )
-                    DAP_DELETE(l_es_w_data);
-                else if (g_debug_reactor)
-                    log_it(L_DEBUG,"Own event signal without actual event data");
-                if ( l_cur->pipe_out == NULL){ // If we're not the input for pipe or queue
-                                               // we must drop write flag and set read flag
-                    l_flag_read = true;
-                }else{
-                    l_flag_write = true;
-                }
-            }else{
-                l_cur = (dap_events_socket_t*) l_kevent->udata;
-                assert(l_cur);
-
-                switch (l_kevent->filter) {
-                    case EVFILT_TIMER:
-                    case EVFILT_READ: l_flag_read = true; break;
-                    case EVFILT_WRITE: l_flag_write = true; break;
-                    case EVFILT_EXCEPT : l_flag_rdhup = true; break;
-                    default: log_it(L_CRITICAL,"Unknown filter type in polling, exit thread"); return NULL;
-                }
-
-            }
-            l_cur->kqueue_event_catched = l_kevent;
-#ifndef DAP_OS_DARWIN
-            u_int l_cur_events = l_thread->kqueue_events[n].fflags;
-#else
-            uint32_t l_cur_events = l_thread->kqueue_events[n].fflags;
-#endif
-
-#else
-#error "Unimplemented fetch esocket after poll"
-#endif
-            assert(l_cur);
-            if(g_debug_reactor)
-                log_it(L_DEBUG, "Proc thread #%u esocket %p fd=%"DAP_FORMAT_SOCKET" type=%d flags=0x%0X (%s:%s:%s:%s:%s:%s:%s:%s)", l_thread->cpu_id, l_cur, l_cur->socket,
-                    l_cur->type, l_cur_events, 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":"");
-
-            //log_it(L_DEBUG,"Waked up esocket %p (socket %d) {read:%s,write:%s,error:%s} ", l_cur, l_cur->fd,
-            //           l_flag_read?"true":"false", l_flag_write?"true":"false", l_flag_error?"true":"false" );
-            time_t l_cur_time = time( NULL);
-            l_cur->last_time_active = l_cur_time;
-            if (l_flag_error){
-#ifdef DAP_OS_WINDOWS
-                int l_errno = WSAGetLastError();
-#else
-                int l_errno = errno;
-#endif
-                char l_errbuf[128];
-                strerror_r(l_errno, l_errbuf,sizeof (l_errbuf));
-                log_it(L_ERROR,"Some error on proc thread #%u with %"DAP_FORMAT_SOCKET" socket: %s(%d)",l_thread->cpu_id, l_cur->socket, l_errbuf, l_errno);
-                if(l_cur->callbacks.error_callback)
-                    l_cur->callbacks.error_callback(l_cur, errno);
-            }
-            if (l_flag_read ){
-                int32_t l_bytes_read = 0;
-                switch (l_cur->type) {
-                    case DESCRIPTOR_TYPE_QUEUE:
-                        dap_events_socket_queue_proc_input_unsafe(l_cur);
-#ifdef DAP_OS_WINDOWS
-                        l_bytes_read = dap_recvfrom(l_cur->socket, NULL, 0);
-#endif
-                        break;
-                    case DESCRIPTOR_TYPE_EVENT:
-                        dap_events_socket_event_proc_input_unsafe (l_cur);
-                        break;
-
-                    default:
-                        log_it(L_ERROR, "Unprocessed descriptor type accepted in proc thread loop");
-#ifdef DAP_OS_WINDOWS
-                        l_bytes_read = dap_recvfrom(l_cur->socket, NULL, 0);
-#endif
-                        break;
-                }
-            }
-            if (l_flag_write ){
-                int l_errno=0;
-                if (l_cur->buf_out_size){
-                    ssize_t l_bytes_sent = -1;
-                    switch (l_cur->type) {
-                        case DESCRIPTOR_TYPE_QUEUE:
-                            if (l_cur->flags & DAP_SOCK_QUEUE_PTR){
-                                #if defined(DAP_EVENTS_CAPS_QUEUE_PIPE2)
-                                    l_bytes_sent = write(l_cur->socket, l_cur->buf_out, sizeof (void *) ); // We send pointer by pointer
-                                #elif defined DAP_EVENTS_CAPS_MSMQ
-                                DWORD l_mp_id = 0;
-                                MQMSGPROPS    l_mps;
-                                MQPROPVARIANT l_mpvar[1];
-                                MSGPROPID     l_p_id[1];
-                                HRESULT       l_mstatus[1];
-
-                                l_p_id[l_mp_id] = PROPID_M_BODY;
-                                l_mpvar[l_mp_id].vt = VT_VECTOR | VT_UI1;
-                                l_mpvar[l_mp_id].caub.pElems = l_cur->buf_out;
-                                l_mpvar[l_mp_id].caub.cElems = (u_long)l_cur->buf_out_size;
-                                l_mp_id++;
-
-                                l_mps.cProp = l_mp_id;
-                                l_mps.aPropID = l_p_id;
-                                l_mps.aPropVar = l_mpvar;
-                                l_mps.aStatus = l_mstatus;
-                                HRESULT hr = MQSendMessage(l_cur->mqh, &l_mps, MQ_NO_TRANSACTION);
-
-                                if (hr != MQ_OK) {
-                                    log_it(L_ERROR, "An error occured on sending message to queue, errno: %ld", hr);
-                                    break;
-                                } else {
-                                    if(dap_sendto(l_cur->socket, l_cur->port, NULL, 0) == SOCKET_ERROR) {
-                                        log_it(L_ERROR, "Write to sock error: %d", WSAGetLastError());
-                                    }
-                                    l_cur->buf_out_size = 0;
-                                    dap_events_socket_set_writable_unsafe(l_cur,false);
-
-                                    break;
-                                }
-                                #elif defined (DAP_EVENTS_CAPS_QUEUE_MQUEUE)
-                                    char * l_ptr = (char *) l_cur->buf_out;
-                                    l_bytes_sent = mq_send(l_cur->mqd, l_ptr, sizeof (l_ptr),0);
-                                    if (l_bytes_sent==0){
-//                                        log_it(L_DEBUG,"mq_send %p success", l_ptr_in);
-                                        l_bytes_sent = sizeof (void *);
-                                    }else if (l_bytes_sent == -1 && errno == EINVAL){ // To make compatible with other
-                                        l_errno = EAGAIN;                        // non-blocking sockets
-//                                        log_it(L_DEBUG,"mq_send %p EAGAIN", l_ptr_in);
-                                    }else{
-                                        l_errno = errno;
-                                        log_it(L_WARNING,"mq_send %p errno: %d", l_ptr, l_errno);
-                                    }
-                                #elif defined (DAP_EVENTS_CAPS_KQUEUE)
-
-                                    // Select socket and kqueue fd to send the event
-                                    dap_events_socket_t * l_es_output = l_cur->pipe_out ? l_cur->pipe_out : l_cur;
-                                    int l_kqueue_fd = l_es_output->worker ? l_es_output->worker->kqueue_fd : l_es_output->proc_thread ? l_es_output->proc_thread->kqueue_fd : -1;
-
-                                    struct kevent l_event;
-                                    dap_events_socket_w_data_t * l_es_w_data = DAP_NEW_Z(dap_events_socket_w_data_t);
-                                    l_es_w_data->esocket = l_es_output;
-
-                                    memcpy(&l_es_w_data->ptr,l_cur->buf_out,sizeof(l_es_w_data->ptr) );
-                                    EV_SET(&l_event,l_es_output->socket, EVFILT_USER,0,NOTE_TRIGGER ,0, l_es_w_data);
-
-
-                                    int l_n =  l_kqueue_fd==-1 ? -1 : kevent(l_kqueue_fd,&l_event,1,NULL,0,NULL);
-                                    if (l_n != -1)
-                                        l_bytes_sent = sizeof(l_es_w_data->ptr);
-                                    else{
-                                        l_errno = errno;
-                                        log_it(L_WARNING,"queue ptr send error: kevent %p errno: %d", l_es_w_data->ptr, l_errno);
-                                        DAP_DELETE(l_es_w_data);
-                                    }
-                                #else
-                                    #error "Not implemented dap_events_socket_queue_ptr_send() for this platform"
-                                #endif
-                                //int l_errno = errno;
-
-                                break;
-                            }break;
-                        default:
-                            log_it(L_ERROR, "Dont process write flags for this socket %d in proc thread", l_cur->fd);
-
-                    }
-                    l_errno = errno;
-
-                    if(l_bytes_sent>0){
-                        l_cur->buf_out_size -= l_bytes_sent;
-                        //log_it(L_DEBUG,"Sent %zd bytes out, left %zd in buf out", l_bytes_sent, l_cur->buf_out);
-                        if (l_cur->buf_out_size ){ // Shrink output buffer
-
-                            memmove(l_cur->buf_out, l_cur->buf_out+l_bytes_sent, l_cur->buf_out_size );
-                        }else{
-#ifndef DAP_EVENTS_CAPS_KQUEUE
-                            l_cur->flags ^= DAP_SOCK_READY_TO_WRITE;
-                            dap_proc_thread_esocket_update_poll_flags(l_thread, l_cur);
-#else
-                            log_it(L_WARNING,"(!) Write event receieved but nothing in buffer");
-                            sleep(500); // to prevent shitting the log files
-#endif
-                        }
-                    }
-
-                }else{
-                    // TODO Make this code platform-independent
-#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
-                    log_it(L_DEBUG,"(!) Write event receieved but nothing in buffer, switching off this flag");
-                    l_cur->flags ^= DAP_SOCK_READY_TO_WRITE;
-                    dap_proc_thread_esocket_update_poll_flags(l_thread, l_cur);
-                    // TODO Make this code platform-independent
-#else
-                    log_it(L_WARNING,"(!) Write event receieved but nothing in buffer");
-                    sleep(500); // to prevent shitting the log files
-#endif
-                }
-
-
-            }
-            if(l_cur->flags & DAP_SOCK_SIGNAL_CLOSE){
-#ifdef DAP_EVENTS_CAPS_EPOLL
-                log_it(L_WARNING, "Deleting esocket %d from proc thread?...", l_cur->fd);
-                if ( epoll_ctl( l_thread->epoll_ctl, EPOLL_CTL_DEL, l_cur->fd, &l_cur->ev) == -1 )
-                    log_it( L_ERROR,"Can't remove event socket's handler from the epoll ctl" );
-                //else
-                //    log_it( L_DEBUG,"Removed epoll's event from proc thread #%u", l_thread->cpu_id );
-                if (l_cur->callbacks.delete_callback)
-                    l_cur->callbacks.delete_callback(l_cur, l_thread);
-                if(l_cur->_inheritor)
-                    DAP_DELETE(l_cur->_inheritor);
-                DAP_DELETE(l_cur);
-#elif defined (DAP_EVENTS_CAPS_POLL)
-                l_thread->poll[n].fd = -1;
-                l_poll_compress = true;
-#elif defined (DAP_EVENTS_CAPS_KQUEUE)
-        if (l_cur->socket != -1 ){
-            struct kevent * l_event = &l_cur->kqueue_event;
-            EV_SET(l_event, l_cur->socket, 0 ,EV_DELETE, 0,0,l_cur);
-            if ( kevent( l_thread->kqueue_fd,l_event,1,NULL,0,NULL) != 1 ) {
-                int l_errno = errno;
-                char l_errbuf[128];
-                strerror_r(l_errno, l_errbuf, sizeof (l_errbuf));
-                log_it( L_ERROR,"Can't remove event socket's handler %d from the epoll_fd %d  \"%s\" (%d)", l_cur->socket,
-                l_thread->kqueue_fd, l_errbuf, l_errno);
-            }
-        }
-
-#else
-#error "Unimplemented poll ctl analog for this platform"
-#endif
-            }
-
-        }
-#ifdef DAP_EVENTS_CAPS_POLL
-        /***********************************************************/
-        /* If the compress_array flag was turned on, we need       */
-        /* to squeeze together the array and decrement the number  */
-        /* of file descriptors.                                    */
-        /***********************************************************/
-        if ( l_poll_compress){
-           l_poll_compress = false;
-           for (size_t i = 0; i < l_thread->poll_count ; i++)  {
-               if ( l_thread->poll[i].fd == -1){
-                    for(size_t j = i; j +1 < l_thread->poll_count; j++){
-                        l_thread->poll[j].fd = l_thread->poll[j+1].fd;
-                        l_thread->poll[j].events = l_thread->poll[j+1].events;
-                        l_thread->poll[j].revents = l_thread->poll[j+1].revents;
-                        l_thread->esockets[j] = l_thread->esockets[j+1];
-                        if(l_thread->esockets[j])
-                            l_thread->esockets[j]->poll_index = j;
-                    }
-                   i--;
-                   l_thread->poll_count--;
-               }
-           }
-        }
-#endif
-    }
-    log_it(L_ATT, "Stop processing thread #%u", l_thread->cpu_id);
-    fflush(stdout);
-
-    // cleanip inputs
-    for (size_t n=0; n<dap_events_worker_get_count(); n++){
-        dap_events_socket_delete_unsafe(l_thread->queue_assign_input[n], false);
-        dap_events_socket_delete_unsafe(l_thread->queue_io_input[n], false);
-        dap_events_socket_delete_unsafe(l_thread->queue_callback_input[n], false);
-    }
-
-    return NULL;
-}
-
-/**
- * @brief dap_proc_thread_assign_on_worker_inter
- * @param a_thread
- * @param a_worker
- * @param a_esocket
- * @return
- */
-bool dap_proc_thread_assign_on_worker_inter(dap_proc_thread_t * a_thread, dap_worker_t * a_worker, dap_events_socket_t *a_esocket  )
-{
-    dap_events_socket_t * l_es_assign_input = a_thread->queue_assign_input[a_worker->id];
-    if(g_debug_reactor)
-        log_it(L_DEBUG,"Remove esocket %p from proc thread and send it to worker #%u",a_esocket, a_worker->id);
-
-    dap_events_socket_assign_on_worker_inter(l_es_assign_input, a_esocket);
-    // TODO Make this code platform-independent
-#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
-    l_es_assign_input->flags |= DAP_SOCK_READY_TO_WRITE;
-    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_assign_input);
-#endif
-    return true;
-}
-
-/**
- * @brief dap_proc_thread_esocket_write_inter
- * @param a_thread
- * @param a_worker
- * @param a_es_uuid
- * @param a_data
- * @param a_data_size
- * @return
- */
-int dap_proc_thread_esocket_write_inter(dap_proc_thread_t * a_thread,dap_worker_t * a_worker,   dap_events_socket_uuid_t a_es_uuid,
-                                        const void * a_data, size_t a_data_size)
-{
-    dap_events_socket_t * l_es_io_input = a_thread->queue_io_input[a_worker->id];
-    dap_events_socket_write_inter(l_es_io_input,a_es_uuid, a_data, a_data_size);
-    // TODO Make this code platform-independent
-#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
-    l_es_io_input->flags |= DAP_SOCK_READY_TO_WRITE;
-    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_io_input);
-#endif
-    return 0;
-}
-
-
-/**
- * @brief dap_proc_thread_esocket_write_f_inter
- * @param a_thread
- * @param a_worker
- * @param a_es_uuid,
- * @param a_format
- * @return
- */
-int dap_proc_thread_esocket_write_f_inter(dap_proc_thread_t * a_thread,dap_worker_t * a_worker,  dap_events_socket_uuid_t a_es_uuid,
-                                        const char * a_format,...)
-{
-    va_list ap, ap_copy;
-    va_start(ap,a_format);
-    va_copy(ap_copy, ap);
-    int l_data_size = dap_vsnprintf(NULL,0,a_format,ap);
-    va_end(ap);
-    if (l_data_size <0 ){
-        log_it(L_ERROR,"Can't write out formatted data '%s' with values",a_format);
-        va_end(ap_copy);
-        return 0;
-    }
-
-    dap_events_socket_t * l_es_io_input = a_thread->queue_io_input[a_worker->id];
-    char * l_data = DAP_NEW_SIZE(char,l_data_size+1);
-    if (!l_data){
-        va_end(ap_copy);
-        return -1;
-    }
-    l_data_size = dap_vsprintf(l_data,a_format,ap_copy);
-    va_end(ap_copy);
-
-    dap_events_socket_write_inter(l_es_io_input, a_es_uuid, l_data, l_data_size);
-    // TODO Make this code platform-independent
-#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
-    l_es_io_input->flags |= DAP_SOCK_READY_TO_WRITE;
-    dap_proc_thread_esocket_update_poll_flags(a_thread, l_es_io_input);
-#endif
-    DAP_DELETE(l_data);
-    return 0;
-}
-
-/**
- * @brief dap_proc_thread_worker_exec_callback
- * @param a_thread
- * @param a_worker_id
- * @param a_callback
- * @param a_arg
- */
-void dap_proc_thread_worker_exec_callback(dap_proc_thread_t * a_thread, size_t a_worker_id, dap_worker_callback_t a_callback, void * a_arg)
-{
-    dap_worker_msg_callback_t * l_msg = DAP_NEW_Z(dap_worker_msg_callback_t);
-    l_msg->callback = a_callback;
-    l_msg->arg = a_arg;
-    dap_events_socket_queue_ptr_send_to_input(a_thread->queue_callback_input[a_worker_id],l_msg );
-
-    // TODO Make this code platform-independent
-#ifndef DAP_EVENTS_CAPS_EVENT_KEVENT
-    a_thread->queue_callback_input[a_worker_id]->flags |= DAP_SOCK_READY_TO_WRITE;
-    dap_proc_thread_esocket_update_poll_flags(a_thread, a_thread->queue_callback_input[a_worker_id]);
-#endif
-}
-
-static void s_event_exit_callback( dap_events_socket_t * a_es, uint64_t a_flags)
-{
-    (void) a_flags;
-    dap_proc_thread_t * l_thread = (dap_proc_thread_t *) a_es->_inheritor;
-    l_thread->signal_exit = true;
-    if(g_debug_reactor)
-        log_it(L_DEBUG, "Proc_thread :%u signaled to exit", l_thread->cpu_id);
-}
-
diff --git a/dap-sdk/net/core/test/CMakeLists.txt b/dap-sdk/net/core/test/CMakeLists.txt
deleted file mode 100755
index 1149697b7fd05108808487b46e94be484231cdd7..0000000000000000000000000000000000000000
--- a/dap-sdk/net/core/test/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-project(server_core_test)
-
-if ( NOT ( TARGET dap_test ) )
-    add_subdirectory(libdap-test)
-endif()
-
-file(GLOB DAP_SERVER_CORE_TEST_SOURCES *.c)
-file(GLOB DAP_SERVER_CORE_TEST_HEADERS *.h)
-
-add_executable(${PROJECT_NAME} ${DAP_SERVER_CORE_TEST_SOURCES} ${DAP_SERVER_CORE_TEST_HEADERS})
-
-target_link_libraries(${PROJECT_NAME} dap_test dap_core dap_crypto dap_server_core ev)
-
-add_test(
-    NAME server_core_test
-    COMMAND server_core_test
-)
diff --git a/dap-sdk/net/libdap-net.pri b/dap-sdk/net/libdap-net.pri
index f753e5f14e8b91509e61f8dbe4e81e441219bf29..bd828a94f94b863d6214f6375434fb6ff0ef3e99 100755
--- a/dap-sdk/net/libdap-net.pri
+++ b/dap-sdk/net/libdap-net.pri
@@ -1,6 +1,5 @@
 
 include (../net/client/libdap-net-client.pri)
-include (../net/core/libdap-net-core.pri)
 include (../net/server/libdap-net-server.pri)
 include (../net/stream/libdap-net-stream.pri)
 
diff --git a/dap-sdk/net/server/enc_server/CMakeLists.txt b/dap-sdk/net/server/enc_server/CMakeLists.txt
index 4f95407a85ec0b43c836ac9f5da15bb12ae3fe64..8aaba2be3cae6e9d374e519d10c15d462df4228e 100644
--- a/dap-sdk/net/server/enc_server/CMakeLists.txt
+++ b/dap-sdk/net/server/enc_server/CMakeLists.txt
@@ -19,7 +19,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC include)
 target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../3rdparty/uthash/src)
 
 if(WIN32)
-  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server json-c
+  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server json-c
   KERNEL32
   USER32
   SHELL32
@@ -41,6 +41,6 @@ if(WIN32)
 endif()
 
 if(UNIX)
-  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server json-c )
+  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server json-c )
 endif()
 
diff --git a/dap-sdk/net/server/http_server/CMakeLists.txt b/dap-sdk/net/server/http_server/CMakeLists.txt
index e4f3397887bd535d710929565b5021bca94cd3d7..2af0aec59f1e03d422c56188ec11e02fe7aa031d 100644
--- a/dap-sdk/net/server/http_server/CMakeLists.txt
+++ b/dap-sdk/net/server/http_server/CMakeLists.txt
@@ -26,7 +26,7 @@ if(DARWIN)
 endif()
 
 if(WIN32)
-  target_link_libraries(dap_http_server dap_core dap_crypto dap_server_core magic regex tre intl iconv
+  target_link_libraries(dap_http_server dap_core dap_crypto dap_io magic regex tre intl iconv
   KERNEL32
   USER32
   SHELL32
@@ -48,7 +48,7 @@ if(WIN32)
 endif()
 
 if(UNIX)
-  target_link_libraries(${PROJECT_NAME} dap_core dap_server_core magic json-c)
+  target_link_libraries(${PROJECT_NAME} dap_core dap_io magic json-c)
   target_include_directories(${PROJECT_NAME} PUBLIC ${IPUTILS_INCLUDE_DIRS})
 endif()
 
diff --git a/dap-sdk/net/server/http_server/dap_http_simple.c b/dap-sdk/net/server/http_server/dap_http_simple.c
index c37bd1ab719d972f2e0fde41e6ce87454c1675ae..6dead19f9665feff878750090f3a08effb63fc1a 100644
--- a/dap-sdk/net/server/http_server/dap_http_simple.c
+++ b/dap-sdk/net/server/http_server/dap_http_simple.c
@@ -343,7 +343,7 @@ static void s_http_client_headers_read( dap_http_client_t *a_http_client, void *
 
     l_http_simple->esocket = a_http_client->esocket;
     l_http_simple->http_client = a_http_client;
-    l_http_simple->worker = a_http_client->esocket->worker;
+    l_http_simple->worker = a_http_client->esocket->context->worker;
     l_http_simple->reply_size_max = DAP_HTTP_SIMPLE_URL_PROC( a_http_client->proc )->reply_size_max;
     l_http_simple->reply_byte = DAP_NEW_Z_SIZE(uint8_t, DAP_HTTP_SIMPLE(a_http_client)->reply_size_max );
 
@@ -411,7 +411,7 @@ void s_http_client_data_read( dap_http_client_t *a_http_client, void * a_arg )
 
         // bool isOK=true;
         log_it( L_INFO,"Data for http_simple_request collected" );
-        dap_events_socket_remove_from_worker_unsafe(a_http_client->esocket,a_http_client->esocket->worker);
+        dap_events_socket_remove_from_worker_unsafe(a_http_client->esocket,a_http_client->esocket->context->worker);
         dap_proc_queue_add_callback_inter( l_http_simple->worker->proc_queue_input , s_proc_queue_callback, l_http_simple);
     }
 }
diff --git a/dap-sdk/net/server/json_rpc/CMakeLists.txt b/dap-sdk/net/server/json_rpc/CMakeLists.txt
index 30207dcaa5881382df12e9c164e4bea61e7d0771..5dcedf1f91891868501c7d969f2b6c1f3984a9b6 100644
--- a/dap-sdk/net/server/json_rpc/CMakeLists.txt
+++ b/dap-sdk/net/server/json_rpc/CMakeLists.txt
@@ -14,5 +14,5 @@ target_include_directories(${PROJECT_NAME} INTERFACE . include/)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
 target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../3rdparty/uthash/src)
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server dap_client json-c )
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server dap_client json-c )
 #target_link_libraries(${PROJECT_NAME} dap_core)# dap_http_server json-c)
diff --git a/dap-sdk/net/server/notify_server/CMakeLists.txt b/dap-sdk/net/server/notify_server/CMakeLists.txt
index 8390370099ff6c10b1d12bf7be69d16e16f23d3c..de3816c16ef052fe0e3b688b58bd0d34c373925e 100644
--- a/dap-sdk/net/server/notify_server/CMakeLists.txt
+++ b/dap-sdk/net/server/notify_server/CMakeLists.txt
@@ -8,5 +8,5 @@ add_library(${PROJECT_NAME} STATIC ${DAP_NOTIFY_SRV_SRCS} ${DAP_NOTIFY_SRV_HDRS}
 target_include_directories(${PROJECT_NAME} INTERFACE . include/)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_server_core json-c )
+target_link_libraries(${PROJECT_NAME} dap_core dap_io json-c )
 
diff --git a/dap-sdk/net/server/notify_server/src/dap_notify_srv.c b/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
index 9b79bd6e7b296707299baba0b2930843223ffa11..37df9da127904d3d47e5ff5deff8956c545d82b7 100644
--- a/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
+++ b/dap-sdk/net/server/notify_server/src/dap_notify_srv.c
@@ -182,7 +182,7 @@ static void s_notify_server_callback_queue(dap_events_socket_t * a_es, void * a_
         }
         size_t l_str_len = a_arg? strlen((char*)a_arg): 0;
         if(l_str_len){
-            dap_events_socket_write_mt(l_socket_handler->esocket->worker, //_inter(a_es->worker->queue_es_io_input[l_worker_id],
+            dap_events_socket_write_mt(l_socket_handler->esocket->context->worker, //_inter(a_es->worker->queue_es_io_input[l_worker_id],
                                           l_socket_handler->uuid,
                                           a_arg, l_str_len + 1);
         }
@@ -206,12 +206,12 @@ static void s_notify_server_callback_new(dap_events_socket_t * a_es, void * a_ar
         uint64_t *l_uuid_u64 =(uint64_t*) &a_es->uuid;
         log_it(L_WARNING,"Trying to add notify client with uuid 0x%016"DAP_UINT64_FORMAT_X" but already present this UUID in list, updating only esocket pointer if so", *l_uuid_u64);
         l_hh_new->esocket = a_es;
-        l_hh_new->worker_id = a_es->worker->id;
+        l_hh_new->worker_id = a_es->context->worker->id;
     }else {
         l_hh_new = DAP_NEW_Z(dap_events_socket_handler_hh_t);
         l_hh_new->esocket = a_es;
         l_hh_new->uuid = a_es->uuid;
-        l_hh_new->worker_id = a_es->worker->id;
+        l_hh_new->worker_id = a_es->context->worker->id;
         a_es->no_close = true;
         HASH_ADD(hh, s_notify_server_clients, uuid, sizeof (l_hh_new->uuid), l_hh_new);
     }
diff --git a/dap-sdk/net/stream/stream/CMakeLists.txt b/dap-sdk/net/stream/stream/CMakeLists.txt
index 11d4b6896a85fa96512ad37d6a9c72cf06a36831..5cc4ec636542842c0eb1720158484e25beaa016c 100755
--- a/dap-sdk/net/stream/stream/CMakeLists.txt
+++ b/dap-sdk/net/stream/stream/CMakeLists.txt
@@ -6,7 +6,7 @@ file(GLOB STREAM_HDRS include/*.h)
 
 add_library(${PROJECT_NAME} STATIC ${STREAM_SRCS} ${STREAM_HDRS})
 
-target_link_libraries(dap_stream dap_core dap_server_core dap_crypto
+target_link_libraries(dap_stream dap_core dap_io dap_crypto
     dap_http_server dap_enc_server dap_session dap_stream_ch dap_client)
 
 target_include_directories(dap_stream INTERFACE .)
diff --git a/dap-sdk/net/stream/stream/dap_stream.c b/dap-sdk/net/stream/stream/dap_stream.c
index 359d81b5348b175d8c0aa853388aa0b3ea153682..d49d08488c5dae84e10d305487dc04c99850af87 100644
--- a/dap-sdk/net/stream/stream/dap_stream.c
+++ b/dap-sdk/net/stream/stream/dap_stream.c
@@ -266,7 +266,7 @@ dap_stream_t *s_stream_new(dap_http_client_t *a_http_client)
     dap_stream_t *l_ret = DAP_NEW_Z(dap_stream_t);
 
     l_ret->esocket = a_http_client->esocket;
-    l_ret->stream_worker = (dap_stream_worker_t *)a_http_client->esocket->worker->_inheritor;
+    l_ret->stream_worker = (dap_stream_worker_t *)a_http_client->esocket->context->worker->_inheritor;
     l_ret->conn_http = a_http_client;
     l_ret->buf_defrag_size = 0;
     l_ret->seq_id = 0;
@@ -274,7 +274,7 @@ dap_stream_t *s_stream_new(dap_http_client_t *a_http_client)
     // Start server keep-alive timer
     dap_events_socket_uuid_t *l_es_uuid = DAP_NEW_Z(dap_events_socket_uuid_t);
     *l_es_uuid = l_ret->esocket->uuid;
-    l_ret->keepalive_timer = dap_timerfd_start_on_worker(l_ret->esocket->worker,
+    l_ret->keepalive_timer = dap_timerfd_start_on_worker(l_ret->esocket->context->worker,
                                                          STREAM_KEEPALIVE_TIMEOUT * 1000,
                                                          (dap_timerfd_callback_t)s_callback_server_keepalive,
                                                          l_es_uuid);
@@ -889,7 +889,7 @@ static bool s_callback_keepalive(void *a_arg, bool a_server_side)
         return false;
     dap_events_socket_uuid_t * l_es_uuid = (dap_events_socket_uuid_t*) a_arg;
     dap_worker_t * l_worker = dap_events_get_current_worker(dap_events_get_default());
-    dap_events_socket_t * l_es = dap_worker_esocket_find_uuid(l_worker, *l_es_uuid);
+    dap_events_socket_t * l_es = dap_context_esocket_find_by_uuid(l_worker->context, *l_es_uuid);
     if(l_es) {
         dap_stream_t *l_stream = NULL;
         if (a_server_side) {
diff --git a/dap-sdk/net/stream/stream/dap_stream_worker.c b/dap-sdk/net/stream/stream/dap_stream_worker.c
index 8e553a3da951ce8762c8acadceb73cb27242a873..8d1fa9e5158a0dc4251fe0b2442e4b5eaa51d4d7 100644
--- a/dap-sdk/net/stream/stream/dap_stream_worker.c
+++ b/dap-sdk/net/stream/stream/dap_stream_worker.c
@@ -96,7 +96,7 @@ int dap_stream_worker_init()
  */
 static void s_ch_io_callback(dap_events_socket_t * a_es, void * a_msg)
 {
-    dap_stream_worker_t * l_stream_worker = DAP_STREAM_WORKER( a_es->worker );
+    dap_stream_worker_t * l_stream_worker = DAP_STREAM_WORKER( a_es->context->worker );
     dap_stream_worker_msg_io_t * l_msg = (dap_stream_worker_msg_io_t*) a_msg;
 
     assert(l_msg);
diff --git a/modules/chain/btc_rpc/CMakeLists.txt b/modules/chain/btc_rpc/CMakeLists.txt
index 930181f7283cee04960465242c2c5448d8ee00b7..5a8bfff563162fe9ef2eb56b524418a2bb29b1ea 100644
--- a/modules/chain/btc_rpc/CMakeLists.txt
+++ b/modules/chain/btc_rpc/CMakeLists.txt
@@ -14,5 +14,5 @@ target_include_directories(${PROJECT_NAME} INTERFACE . include/)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
 
 target_link_libraries(${PROJECT_NAME} dap_core dap_json_rpc)
-#target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_http_server dap_client json-c )
+#target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_http_server dap_client json-c )
 #target_link_libraries(${PROJECT_NAME} dap_core)# dap_http_server json-c)
diff --git a/modules/channel/chain-net-srv/CMakeLists.txt b/modules/channel/chain-net-srv/CMakeLists.txt
index 08b1ea5c1996bb155320f30f87a658a9759dab1d..e9c147d210b11713e39472c28ee466d62fe1089a 100644
--- a/modules/channel/chain-net-srv/CMakeLists.txt
+++ b/modules/channel/chain-net-srv/CMakeLists.txt
@@ -6,7 +6,7 @@ file(GLOB DAP_STREAM_CH_CHAIN_NET_SRV_HDRS include/*.h)
 
 add_library(${PROJECT_NAME} STATIC ${DAP_STREAM_CH_CHAIN_NET_SRV_SRCS} ${DAP_STREAM_CH_CHAIN_NET_SRV_HDRS})
 
-target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain_common dap_chain dap_chain_mempool dap_chain_net dap_chain_net_srv dap_server_core dap_stream dap_stream_ch dap_stream_ch_chain dap_stream_ch_chain_net)
+target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain_common dap_chain dap_chain_mempool dap_chain_net dap_chain_net_srv dap_io dap_stream dap_stream_ch dap_stream_ch_chain dap_stream_ch_chain_net)
 
 target_include_directories(${PROJECT_NAME} INTERFACE .)
 target_include_directories(${PROJECT_NAME} PUBLIC include)
diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c
index add1f75c8d46dddb91ef9aafedcd1434df9341eb..617dc0178693ffc00a04955e9b21a18fc194eb71 100644
--- a/modules/channel/chain/dap_stream_ch_chain.c
+++ b/modules/channel/chain/dap_stream_ch_chain.c
@@ -305,10 +305,10 @@ static bool s_sync_out_chains_proc_callback(dap_proc_thread_t *a_thread, void *a
 
 
         //pthread_rwlock_unlock(&l_chain->atoms_rwlock);
-        dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id, s_sync_out_chains_first_worker_callback, l_sync_request );
+        dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id, s_sync_out_chains_first_worker_callback, l_sync_request );
     } else {
         //pthread_rwlock_unlock(&l_chain->atoms_rwlock);
-        dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id,s_sync_out_chains_last_worker_callback, l_sync_request );
+        dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id,s_sync_out_chains_last_worker_callback, l_sync_request );
     }
     return true;
 }
@@ -415,9 +415,9 @@ static bool s_sync_out_gdb_proc_callback(dap_proc_thread_t *a_thread, void *a_ar
             log_it(L_DEBUG, "Sync out gdb proc, requested %"DAP_UINT64_FORMAT_U" transactions from address "NODE_ADDR_FP_STR,
                              l_ch_chain->request_db_log->items_number, NODE_ADDR_FP_ARGS_S(l_sync_request->request.node_addr));
         l_sync_request->gdb.db_log = l_ch_chain->request_db_log;
-        dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id, s_sync_out_gdb_first_worker_callback, l_sync_request );
+        dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id, s_sync_out_gdb_first_worker_callback, l_sync_request );
     } else {
-        dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id, s_sync_out_gdb_last_worker_callback, l_sync_request );
+        dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id, s_sync_out_gdb_last_worker_callback, l_sync_request );
     }
     return true;
 }
@@ -472,7 +472,7 @@ static bool s_sync_update_gdb_proc_callback(dap_proc_thread_t *a_thread, void *a
     l_ch_chain->state = CHAIN_STATE_UPDATE_GLOBAL_DB;
     l_sync_request->gdb.db_log = l_ch_chain->request_db_log;
     l_sync_request->request.node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net);
-    dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id, s_sync_update_gdb_start_worker_callback, l_sync_request);
+    dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id, s_sync_update_gdb_start_worker_callback, l_sync_request);
     return true;
 }
 
@@ -743,7 +743,7 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg)
                 l_sync_req_tsd->request.id_end = l_last_id;
                 l_sync_req_tsd->gdb.sync_group = l_obj->type == DAP_DB$K_OPTYPE_ADD ? dap_strdup(l_last_group) :
                                                                       dap_strdup_printf("%s.del", l_last_group);
-                dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id,
+                dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id,
                                                      s_gdb_sync_tsd_worker_callback, l_sync_req_tsd);
             }
             l_last_id = l_obj->id;
@@ -806,7 +806,7 @@ static bool s_gdb_in_pkt_proc_callback(dap_proc_thread_t *a_thread, void *a_arg)
                 // save data to global_db
                 if(!dap_chain_global_db_obj_save(l_obj, 1)) {
                     struct sync_request *l_sync_req_err = DAP_DUP(l_sync_request);
-                    dap_proc_thread_worker_exec_callback(a_thread, l_sync_request->worker->id,
+                    dap_proc_thread_worker_exec_callback_inter(a_thread, l_sync_request->worker->id,
                                                     s_gdb_in_pkt_error_worker_callback, l_sync_req_err);
                 } else if (s_debug_more)
                     log_it(L_DEBUG, "Added new GLOBAL_DB synchronization record");
diff --git a/modules/global-db/dap_chain_global_db.c b/modules/global-db/dap_chain_global_db.c
index 7546c2e6add927f5105944a26b7678c7d5f2b1d0..331c6a9beaf6174458929d2cde7f54eaa0c04e6c 100644
--- a/modules/global-db/dap_chain_global_db.c
+++ b/modules/global-db/dap_chain_global_db.c
@@ -818,8 +818,8 @@ dap_events_socket_t     *l_es;
     l_proc_que = s_global_db_proc_thread->_inheritor;
     l_es = l_proc_que->esocket;
 
-    l_wrk = l_proc_que->esocket->worker;
-    l_proc_thd = l_proc_que->esocket->proc_thread;
+    l_wrk = l_proc_que->esocket->context->worker;
+    l_proc_thd = l_proc_que->esocket->context->proc_thread;
 
     if ( !l_wrk && !l_proc_thd )
         return  log_it(L_ERROR, "Both <worker> or <proc_thread> contexts are NULL"), -EINVAL;
@@ -827,8 +827,6 @@ dap_events_socket_t     *l_es;
     if ( l_wrk && l_proc_thd )
         return  log_it(L_ERROR, "Both <worker> or <proc_thread> contexts are NOT NULL"), -EINVAL;
 
-    /* So, at this point we should decide a what <event socket> context will be used */
-    l_es = l_wrk ? l_wrk->esockets : l_proc_thd->esockets[0];
 
     if ( !(l_db_req = DAP_NEW_Z(dap_grobal_db_req_t)) )                     /* Allocate memory for new DB Request context */
         return  log_it(L_ERROR, "Cannot allocate memory for DB Request, errno=%d", errno), -errno;
diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt
index 0c5b0075b36ca522fdb0b47ea8ae20b82e01ef44..ea6f12058037b9e67982566cdfd3b2d75a312dca 100644
--- a/modules/net/CMakeLists.txt
+++ b/modules/net/CMakeLists.txt
@@ -37,16 +37,16 @@ endif()
 add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
 
 if(WIN32)
-  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_server_core dap_notify_srv dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain dap_chain_wallet dap_chain_net_srv dap_stream_ch_chain_voting
+  target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_io dap_notify_srv dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_chain dap_chain_wallet dap_chain_net_srv dap_stream_ch_chain_voting
                             dap_chain_mempool dap_chain_global_db dap_chain_cs_none)
 endif()
 
 if(LINUX)
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_stream_ch_chain_voting dap_chain
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_stream_ch_chain_voting dap_chain
       dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db dap_chain_cs_none
       resolv )
 elseif(BSD)
-    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_server_core dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_stream_ch_chain_voting dap_chain
+    target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_io dap_notify_srv dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_stream_ch_chain_net_srv dap_stream_ch_chain_voting dap_chain
       dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db dap_chain_cs_none )
 endif()
 
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index 5de75f6190e7b107d7550a4f91bfff8d84811254..cc1a2a0c7501766a0677dfbdaab0c139df51dd5c 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -302,12 +302,12 @@ int dap_chain_net_init()
             "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
         "net -net <chain net name> get status\n"
             "\tLook at current status\n"
-        "net -net <chain net name> stats tx [-from <From time>] [-to <To time>] [-prev_sec <Seconds>] \n"
+        "net -net <chain net name> stats tx|tps [-from <From time>] [-to <To time>] [-prev_sec <Seconds>] \n"
             "\tTransactions statistics. Time format is <Year>-<Month>-<Day>_<Hours>:<Minutes>:<Seconds> or just <Seconds> \n"
         "net -net <chain net name> [-mode {update | all}] sync {all | gdb | chains}\n"
             "\tSyncronyze gdb, chains or everything\n"
             "\tMode \"update\" is by default when only new chains and gdb are updated. Mode \"all\" updates everything from zero\n"
-        "net -net <chain net name> link {list | add | del | info | establish}\n"
+        "net -net <chain net name> link {list | add | del | info | disconnect_all}\n"
             "\tList, add, del, dump or establish links\n"
         "net -net <chain net name> ca add {-cert <cert name> | -hash <cert hash>}\n"
             "\tAdd certificate to list of authority cetificates in GDB group\n"
@@ -1638,6 +1638,29 @@ void dap_chain_net_load_all()
     DAP_DELETE (l_net_dir_str);
 }
 
+dap_string_t* dap_cli_list_net()
+{
+    dap_chain_net_item_t * l_net_item, *l_net_item_tmp;
+    dap_string_t *l_string_ret = dap_string_new("");
+    dap_chain_net_t * l_net = NULL;
+    int l_net_i = 0;
+    dap_string_append(l_string_ret,"Available networks and chains:\n");
+    pthread_rwlock_rdlock(&g_net_items_rwlock);
+    HASH_ITER(hh, s_net_items, l_net_item, l_net_item_tmp){
+        l_net = l_net_item->chain_net;
+        dap_string_append_printf(l_string_ret, "\t%s:\n", l_net_item->name);
+        l_net_i++;
+
+        dap_chain_t * l_chain = l_net->pub.chains;
+        while (l_chain) {
+            dap_string_append_printf(l_string_ret, "\t\t%s\n", l_chain->name );
+            l_chain = l_chain->next;
+        }
+    }
+    pthread_rwlock_unlock(&g_net_items_rwlock);
+    return l_string_ret;
+}
+
 void s_set_reply_text_node_status(char **a_str_reply, dap_chain_net_t * a_net){
     char* l_node_address_text_block = NULL;
     dap_chain_node_addr_t l_cur_node_addr = { 0 };
diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c
index 702014929cc8ec2c0cd1bf1197bacfa5360e5c1d..9ca432efacc8557c5ca633908137fdbe30462c5b 100644
--- a/modules/net/dap_chain_node_cli_cmd.c
+++ b/modules/net/dap_chain_node_cli_cmd.c
@@ -1988,6 +1988,13 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int argc, ch
 
     if((*a_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network
         dap_chain_node_cli_set_reply_text(a_str_reply, "%s can't find network \"%s\"", argv[0], l_net_str);
+        char l_str_to_reply_chain[500] = {0};
+        char *l_str_to_reply = NULL;
+        dap_sprintf(l_str_to_reply_chain, "%s can't find network \"%s\"\n", argv[0], l_net_str);
+        l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
+        dap_string_t* l_net_str = dap_cli_list_net();
+        l_str_to_reply = dap_strcat2(l_str_to_reply,l_net_str->str);
+        dap_chain_node_cli_set_reply_text(a_str_reply, l_str_to_reply);
         return -102;
     }
 
@@ -2000,7 +2007,20 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int argc, ch
             if((*a_chain = dap_chain_net_get_chain_by_name(*a_net, l_chain_str)) == NULL) { // Can't find such chain
                 dap_chain_node_cli_set_reply_text(a_str_reply,
                         "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid",
+                char l_str_to_reply_chain[500] = {0};
+                char *l_str_to_reply = NULL;
+                dap_sprintf(l_str_to_reply_chain, "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid\n",
                         argv[0], l_net_str, l_chain_str);
+                l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
+                dap_chain_t * l_chain;
+                dap_chain_net_t * l_chain_net = *a_net;
+                l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chains:\n");
+                DL_FOREACH(l_chain_net->pub.chains, l_chain){
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,"\t");
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,l_chain->name);
+                        l_str_to_reply = dap_strcat2(l_str_to_reply,"\n");
+                }
+                dap_chain_node_cli_set_reply_text(a_str_reply, l_str_to_reply);
                 return -103;
             }
         }
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 6a53d0cca80f206dc8851e3d5db0b64417cfa3b2..298c91925144f909093996fc46fb59425de09cef 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -211,7 +211,7 @@ dap_chain_node_sync_status_t dap_chain_node_client_start_sync(dap_events_socket_
     dap_events_socket_t * l_es = NULL;
     dap_events_socket_uuid_t l_es_uuid = l_me->esocket_uuid;
     // check if esocket still in worker
-    if( (l_es = dap_worker_esocket_find_uuid(l_worker, l_es_uuid)) != NULL ) {
+    if( (l_es = dap_context_esocket_find_by_uuid(l_worker->context, l_es_uuid)) != NULL ) {
         dap_client_t * l_client = dap_client_from_esocket(l_es);
         if (l_client ) {
             dap_chain_node_client_t * l_node_client = (dap_chain_node_client_t*) l_client->_inheritor;
@@ -330,9 +330,9 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg)
             l_node_client->stream_worker = l_stream->stream_worker;
             if (l_node_client->keep_connection) {
                 dap_events_socket_uuid_t *l_uuid = DAP_DUP(&l_node_client->uuid);
-                dap_worker_exec_callback_on(l_stream->esocket->worker, s_node_client_connected_synchro_start_callback, l_uuid);
+                dap_worker_exec_callback_on(l_stream->esocket->context->worker, s_node_client_connected_synchro_start_callback, l_uuid);
                 dap_events_socket_uuid_t *l_uuid_timer = DAP_DUP(&l_node_client->uuid);
-                l_node_client->sync_timer = dap_timerfd_start_on_worker(l_stream->esocket->worker,
+                l_node_client->sync_timer = dap_timerfd_start_on_worker(l_stream->esocket->context->worker,
                                                                         s_timer_update_states * 1000,
                                                                         s_timer_update_states_callback,
                                                                         l_uuid_timer);
diff --git a/modules/net/dap_chain_node_dns_client.c b/modules/net/dap_chain_node_dns_client.c
index 1122be737e9606639e4952727a6ea6d224ad2523..ee4fdc06aa3df44418e47f3eef3ca0b5df92e18a 100644
--- a/modules/net/dap_chain_node_dns_client.c
+++ b/modules/net/dap_chain_node_dns_client.c
@@ -68,7 +68,7 @@ static void s_dns_client_esocket_read_callback(dap_events_socket_t * a_esocket,
     size_t l_addr_point = DNS_HEADER_SIZE + strlen(l_dns_client->name) + 2 + 2 * sizeof(uint16_t) + DNS_ANSWER_SIZE - sizeof(uint32_t);
     if (l_recieved < l_addr_point + sizeof(uint32_t)) {
         log_it(L_WARNING, "DNS answer incomplete");
-        l_dns_client->callback_error(a_esocket->worker, l_dns_client->result,l_dns_client->callbacks_arg,EIO );
+        l_dns_client->callback_error(a_esocket->context->worker, l_dns_client->result,l_dns_client->callbacks_arg,EIO );
         l_dns_client->is_callbacks_called = true;
         a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
         a_esocket->buf_in_size = a_esocket->buf_out_size = 0;
@@ -78,7 +78,7 @@ static void s_dns_client_esocket_read_callback(dap_events_socket_t * a_esocket,
     int l_answers_count = ntohs(*(uint16_t *)l_cur);
     if (l_answers_count != 1) {
         log_it(L_WARNING, "Incorrect DNS answer format");
-        l_dns_client->callback_error(a_esocket->worker, l_dns_client->result,l_dns_client->callbacks_arg,EINVAL);
+        l_dns_client->callback_error(a_esocket->context->worker, l_dns_client->result,l_dns_client->callbacks_arg,EINVAL);
         l_dns_client->is_callbacks_called = true;
         a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
         a_esocket->buf_in_size = a_esocket->buf_out_size = 0;
@@ -101,7 +101,7 @@ static void s_dns_client_esocket_read_callback(dap_events_socket_t * a_esocket,
         }
     }
 
-    l_dns_client->callback_success(a_esocket->worker,l_dns_client->result,l_dns_client->callbacks_arg);
+    l_dns_client->callback_success(a_esocket->context->worker,l_dns_client->result,l_dns_client->callbacks_arg);
     l_dns_client->is_callbacks_called = true;
     a_esocket->flags |= DAP_SOCK_SIGNAL_CLOSE;
     a_esocket->buf_in_size = a_esocket->buf_out_size = 0;
@@ -116,7 +116,7 @@ static void s_dns_client_esocket_error_callback(dap_events_socket_t * a_esocket,
 {
     struct dns_client * l_dns_client = (struct dns_client*) a_esocket->_inheritor;
     log_it(L_ERROR,"DNS client esocket error %d", a_error);
-    l_dns_client->callback_error(a_esocket->worker, l_dns_client->result,l_dns_client->callbacks_arg,a_error);
+    l_dns_client->callback_error(a_esocket->context->worker, l_dns_client->result,l_dns_client->callbacks_arg,a_error);
     l_dns_client->is_callbacks_called = true;
 }
 
@@ -139,11 +139,11 @@ static bool s_dns_client_esocket_timeout_callback(void * a_arg)
     assert(l_worker);
 
     dap_events_socket_t * l_es;
-    if((l_es = dap_worker_esocket_find_uuid(l_worker ,*l_es_uuid_ptr) ) != NULL){ // If we've not closed this esocket
+    if((l_es = dap_context_esocket_find_by_uuid(l_worker->context,*l_es_uuid_ptr) ) != NULL){ // If we've not closed this esocket
         struct dns_client * l_dns_client = (struct dns_client*) l_es->_inheritor;
         log_it(L_WARNING,"DNS request timeout, bad network?");
         if(! l_dns_client->is_callbacks_called ){
-            l_dns_client->callback_error(l_es->worker,l_dns_client->result,l_dns_client->callbacks_arg,ETIMEDOUT);
+            l_dns_client->callback_error(l_es->context->worker,l_dns_client->result,l_dns_client->callbacks_arg,ETIMEDOUT);
             l_dns_client->is_callbacks_called = true;
         }
 
@@ -163,7 +163,7 @@ static void s_dns_client_esocket_delete_callback(dap_events_socket_t * a_esocket
     (void) a_arg;
     struct dns_client * l_dns_client = (struct dns_client*) a_esocket->_inheritor;
     if(! l_dns_client->is_callbacks_called )
-        l_dns_client->callback_error(a_esocket->worker,l_dns_client->result,l_dns_client->callbacks_arg,EBUSY);
+        l_dns_client->callback_error(a_esocket->context->worker,l_dns_client->result,l_dns_client->callbacks_arg,EBUSY);
     if(l_dns_client->name)
         DAP_DELETE(l_dns_client->name);
     DAP_DEL_Z(l_dns_client->buf);
diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h
index 4e8d1438de9a1a76a3a3630c50237fd483df6a79..8e300c0fe411d5d10001bad0411c1fc0d070d7d4 100644
--- a/modules/net/include/dap_chain_net.h
+++ b/modules/net/include/dap_chain_net.h
@@ -124,6 +124,7 @@ dap_chain_net_t * dap_chain_net_by_id( dap_chain_net_id_t a_id);
 uint16_t dap_chain_net_acl_idx_by_id(dap_chain_net_id_t a_id);
 dap_chain_net_id_t dap_chain_net_id_by_name( const char * a_name);
 dap_ledger_t * dap_chain_ledger_by_net_name( const char * a_net_name);
+dap_string_t* dap_cli_list_net();
 
 dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const char * a_name);
 
diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c
index 72767f217f139a0cb37186a71192b4339bbb1bc4..6538a04c0ab4a28e5c1de1c0c6bd2ad23902eaed 100644
--- a/modules/service/stake/dap_chain_net_srv_stake.c
+++ b/modules/service/stake/dap_chain_net_srv_stake.c
@@ -346,7 +346,12 @@ bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum
         }
     }
     dap_list_free(l_list_out_items);
-    uint256_t l_fee = {}; // TODO replace with fractional mult MULT_256_FRAC_FRAC(l_outs_sum, l_stake->fee_value / 100.0);
+    uint256_t l_fee = uint256_0; // TODO replace with fractional mult MULT_256_FRAC_FRAC(l_outs_sum, l_stake->fee_value / 100.0); +++
+	DIV_256(l_stake->fee_value, dap_chain_coins_to_balance("100.0"), &l_fee);
+	if (MULT_256_COIN(l_outs_sum, l_fee, &l_fee)) {
+		log_it(L_WARNING, "DANGER: MULT_256_COIN overflow! in dap_chain_net_srv_stake_validator()");
+		l_fee = uint256_0;
+	}
     if (compare256(l_fee_sum, l_fee) == -1) {
         return false;
     }
diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c
index 529b51064ebd4356c2897d43fc52352f1d47d7f0..f04ea9ce2faeb7be6d2e3d5039446c4e100dfaec 100644
--- a/modules/service/xchange/dap_chain_net_srv_xchange.c
+++ b/modules/service/xchange/dap_chain_net_srv_xchange.c
@@ -142,7 +142,12 @@ static dap_chain_datum_tx_receipt_t *s_xchage_receipt_create(dap_chain_net_srv_x
 {
     uint32_t l_ext_size = sizeof(uint256_t) + DAP_CHAIN_TICKER_SIZE_MAX;
     uint8_t *l_ext = DAP_NEW_S_SIZE(uint8_t, l_ext_size);
-    uint256_t l_datoshi_buy = {}; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate);
+    uint256_t l_datoshi_buy = uint256_0; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate); +++
+	DIV_256(dap_chain_coins_to_balance("1.0"), a_price->rate, &l_datoshi_buy);
+	if (MULT_256_COIN(a_price->datoshi_sell, l_datoshi_buy, &l_datoshi_buy)) {
+		log_it(L_WARNING, "DANGER: MULT_256_COIN overflow! in s_xchage_receipt_create()");
+		l_datoshi_buy = uint256_0;
+	}
     memcpy(l_ext, &l_datoshi_buy, sizeof(uint256_t));
     strcpy((char *)&l_ext[sizeof(uint256_t)], a_price->token_buy);
     dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 = SERV_UNIT_UNDEFINED};
@@ -237,7 +242,12 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha
     dap_enc_key_t *l_seller_key = dap_chain_wallet_get_key(a_wallet, 0);
     uint256_t l_value_buy = {}; // how many coins to transfer
     // list of transaction with 'out' items to sell
-    uint256_t l_datoshi_buy = {}; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate);
+	uint256_t l_datoshi_buy = uint256_0; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate); +++
+	DIV_256(dap_chain_coins_to_balance("1.0"), a_price->rate, &l_datoshi_buy);
+	if (MULT_256_COIN(a_price->datoshi_sell, l_datoshi_buy, &l_datoshi_buy)) {
+		log_it(L_WARNING, "DANGER: MULT_256_COIN overflow! in s_xchange_tx_create_exchange()");
+		l_datoshi_buy = uint256_0;
+	}
     dap_list_t *l_list_used_out = dap_chain_ledger_get_list_tx_outs_with_val(l_ledger, a_price->token_buy,
                                                                              l_seller_addr, l_datoshi_buy, &l_value_buy);
     if(!l_list_used_out) {
@@ -414,7 +424,12 @@ char *s_xchange_order_create(dap_chain_net_srv_xchange_price_t *a_price, dap_cha
     dap_chain_node_addr_t *l_node_addr = dap_chain_net_get_cur_addr(a_price->net_sell);
     dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 =  SERV_UNIT_UNDEFINED};
     dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_XCHANGE_ID };
-    uint256_t l_datoshi_buy = {}; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate);
+	uint256_t l_datoshi_buy = uint256_0; // TODO rework it with fixed point MULT_256_FRAC_FRAC(a_price->datoshi_sell, 1 / a_price->rate); +++
+	DIV_256(dap_chain_coins_to_balance("1.0"), a_price->rate, &l_datoshi_buy);
+	if (MULT_256_COIN(a_price->datoshi_sell, l_datoshi_buy, &l_datoshi_buy)) {
+		log_it(L_WARNING, "DANGER: MULT_256_COIN overflow! in s_xchange_order_create()");
+		l_datoshi_buy = uint256_0;
+	}
     char *l_order_hash_str = dap_chain_net_srv_order_create(a_price->net_buy, SERV_DIR_SELL, l_uid, *l_node_addr,
                                                             l_tx_hash, l_datoshi_buy, l_unit, a_price->token_buy, 0,
                                                             (uint8_t *)&l_ext, l_ext_size, NULL, 0, a_price->wallet_key);
@@ -431,7 +446,7 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a
     strcpy(l_price->token_sell, l_ext->token_sell);
     l_price->net_buy = a_net;
     strcpy(l_price->token_buy, a_order->price_ticker);
-    l_price->rate = 1; // TODO (long double)l_price->datoshi_sell / a_order->price;
+    DIV_256(l_price->datoshi_sell, a_order->price, &l_price->rate);//l_price->rate = dap_chain_coins_to_balance("1.0");//1; // TODO (long double)l_price->datoshi_sell / a_order->price;
     return l_price;
 }
 
@@ -573,8 +588,8 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'price create' required parameter -rate");
                 return -8;
             }
-            long double l_rate = strtold(l_val_rate_str, NULL);
-            if (!l_rate) {
+			uint256_t l_rate = dap_chain_coins_to_balance(l_val_rate_str);
+            if (!compare256(l_rate, uint256_0)) { // if (l_rate == 0)
                 dap_chain_node_cli_set_reply_text(a_str_reply, "Format -rate <long double> = sell / buy");
                 return -9;
             }
@@ -684,7 +699,7 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
             } else {    // CMD_UPDATE
                 const char *l_val_sell_str = NULL, *l_val_rate_str = NULL, *l_wallet_str = NULL, *l_new_wallet_str = NULL;
                 uint256_t l_datoshi_sell = {};
-                long double l_rate = 0;
+				uint256_t l_rate = uint256_0;
                 dap_chain_wallet_t *l_wallet = NULL;
                 dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_val_sell_str);
                 if (l_val_sell_str) {
@@ -696,8 +711,8 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
                 }
                 dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-rate", &l_val_rate_str);
                 if (l_val_rate_str) {
-                    l_rate = strtold(l_val_rate_str, NULL);
-                    if (!l_rate) {
+                    l_rate = dap_chain_coins_to_balance(l_val_rate_str);
+                    if (!compare256(l_rate, uint256_0)) { // if (l_rate == 0)
                         dap_chain_node_cli_set_reply_text(a_str_reply, "Format -rate <long double> = sell / buy");
                         return -9;
                     }
@@ -784,9 +799,9 @@ static int s_cli_srv_xchange_price(int a_argc, char **a_argv, int a_arg_index, c
             dap_string_t *l_reply_str = dap_string_new("");
             HASH_ITER(hh, s_srv_xchange->pricelist, l_price, l_tmp) {
                 char *l_order_hash_str = dap_chain_hash_fast_to_str_new(&l_price->order_hash);
-                dap_string_append_printf(l_reply_str, "%s %s %s %s %s %s %Lf %s\n", l_order_hash_str, l_price->token_sell,
+                dap_string_append_printf(l_reply_str, "%s %s %s %s %s %s %s %s\n", l_order_hash_str, l_price->token_sell,
                                          l_price->net_sell->pub.name, l_price->token_buy, l_price->net_buy->pub.name,
-                                         dap_chain_balance_print(l_price->datoshi_sell), l_price->rate, l_price->wallet_str);
+                                         dap_chain_balance_print(l_price->datoshi_sell), dap_chain_balance_print(l_price->rate), l_price->wallet_str);
                 DAP_DELETE(l_order_hash_str);
             }
             if (!l_reply_str->len) {
@@ -851,9 +866,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, char **a_str_reply)
                     continue;
                 // TODO add filters to list (tokens, network, etc.)
                 l_price = s_xchange_price_from_order(l_net, l_order);
-                dap_string_append_printf(l_reply_str, "%s %s %s %s %s %s %Lf\n", l_orders[i].key, l_price->token_sell,
+                dap_string_append_printf(l_reply_str, "%s %s %s %s %s %s %s\n", l_orders[i].key, l_price->token_sell,
                                          l_price->net_sell->pub.name, l_price->token_buy, l_price->net_buy->pub.name,
-                                         dap_chain_balance_print(l_price->datoshi_sell), l_price->rate);
+                                         dap_chain_balance_print(l_price->datoshi_sell), dap_chain_balance_print(l_price->rate));
                 DAP_DELETE(l_price);
             }
             dap_chain_global_db_objs_delete(l_orders, l_orders_count);
diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
index 6776a7e0baa5bef0590af7fa7bf809fc8c1ee250..216f1ca0edfebb895a07ec57b0b032f1c4c924b8 100644
--- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h
+++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h
@@ -37,7 +37,7 @@ typedef struct dap_chain_net_srv_xchange_price {
     uint256_t datoshi_sell;
     dap_chain_net_t *net_buy;
     char token_buy[DAP_CHAIN_TICKER_SIZE_MAX];
-    long double rate;
+	uint256_t rate;
     dap_chain_hash_fast_t tx_hash;
     dap_chain_hash_fast_t order_hash;
     dap_enc_key_t *wallet_key;
@@ -53,7 +53,7 @@ typedef struct dap_chain_net_srv_xchange_db_item {
     uint64_t net_sell_id;
     uint64_t net_buy_id;
     uint256_t datoshi_sell;
-    long double rate;
+	uint256_t rate;
     dap_chain_hash_fast_t tx_hash;
     dap_chain_hash_fast_t order_hash;
     char wallet_str[];
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3376bcd0556feb9e8ee0a20180d575ecb401f66b..5b9ff4421933a85b2ff6b13f0c6e9210d89309bf 100755
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -50,7 +50,7 @@ target_link_libraries(dap_global_db_test -pthread -lrt)
 
 target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/modules/global-db/libdap_chain_global_db.a)
 target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/dap-sdk/crypto/libdap_crypto.a)
-target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/dap-sdk/net/core/libdap_server_core.a)
+target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/dap-sdk/net/core/libdap_io.a)
 target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/dap-sdk/core/libdap_core.a)
 target_link_libraries(dap_global_db_test  ${DAP_LIBSDK_ROOT}/3rdparty/cuttdb/libdap_cuttdb.a)
 target_link_libraries(dap_global_db_test -lsqlite3)