diff --git a/include/dap_client_remote.h b/include/dap_client_remote.h
index 29cbfc81fe71b4ef33d5b103621d6686b127019c..b3b663bf988807f2a6a780a8c37dc949bab86fcf 100755
--- a/include/dap_client_remote.h
+++ b/include/dap_client_remote.h
@@ -1,129 +1,131 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2018
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include "uthash.h"
-
-#ifndef WIN32
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#endif
-
-#ifndef EPOLL_HANDLE
-  #ifndef WIN32
-    #define EPOLL_HANDLE  int
-  #else
-    #define EPOLL_HANDLE  HANDLE
-  #endif
-#endif
-
-typedef char str_ip[16];
-
-typedef struct dap_server dap_server_t;
-typedef struct dap_server_thread_s dap_server_thread_t;
-
-struct dap_client_remote;
-
-typedef void (*dap_server_client_callback_t) (struct dap_client_remote *,void * arg); // Callback for specific client operations
-
-#define DAP_CLIENT_REMOTE_BUF 500000
-#define CLIENT_ID_SIZE 12
-
-typedef char dap_server_client_id[CLIENT_ID_SIZE];
-
-typedef struct traffic_stats {
-
-  size_t buf_size_total;
-  size_t buf_size_total_old; // for calculate speed
-  double speed_mbs; // MegaBits per second
-} traffic_stats_t;
-
-typedef struct dap_client_remote {
-
-  int socket;
-  dap_server_client_id id;
-
-  uint32_t  flags;
-  bool close_denied;
-  bool kill_signal;
-
-  uint16_t port;
-  str_ip s_ip;
-
-  uint32_t buf_out_zero_count;
-  char buf_in[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for input data
-
-  size_t buf_in_size; // size of data that is in the input buffer
-
-  traffic_stats_t upload_stat;
-  traffic_stats_t download_stat;
-
-  char buf_out[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for output data
-  size_t buf_out_offset;
-
-  char hostaddr[1024]; // Address
-  char service[128];
-
-  size_t buf_out_size; // size of data that is in the output buffer
-  struct epoll_event  pevent;
-
-  EPOLL_HANDLE efd;            // Epoll fd
-  int tn;             // working thread index
-
-  time_t time_connection;
-  time_t last_time_active;
-
-  struct dap_server *server;
-
-  UT_hash_handle hh;
-  struct dap_client_remote *next, *prev;
-  struct dap_client_remote *knext, *kprev;
-
-  void *_internal;
-  void *_inheritor; // Internal data to specific client type, usualy states for state machine
-
-} dap_client_remote_t; // Node of bidirectional list of clients
-
-int   dap_client_remote_init( void ); //  Init clients module
-void  dap_client_remote_deinit( void ); // Deinit clients module
-
-dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *dsth );
-dap_client_remote_t *dap_client_remote_find( int sock, struct dap_server *sh); // Find client by socket
-
-bool dap_client_remote_is_ready_to_read( dap_client_remote_t * sc );
-bool dap_client_remote_is_ready_to_write( dap_client_remote_t * sc );
-void dap_client_remote_ready_to_read( dap_client_remote_t * sc,bool is_ready );
-void dap_client_remote_ready_to_write( dap_client_remote_t * sc,bool is_ready );
-
-size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size );
-size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format,... );
-size_t dap_client_remote_read( dap_client_remote_t *sc, void * data, size_t data_size );
-
-void dap_client_remote_remove( dap_client_remote_t *sc, struct dap_server * sh ); // Removes the client from the list
-
-void dap_client_remote_shrink_buf_in( dap_client_remote_t * cl, size_t shrink_size );
-
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "uthash.h"
+
+#ifndef WIN32
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#endif
+
+#ifndef EPOLL_HANDLE
+  #ifndef WIN32
+    #define EPOLL_HANDLE  int
+  #else
+    #define EPOLL_HANDLE  HANDLE
+  #endif
+#endif
+
+typedef char str_ip[16];
+
+typedef struct dap_server dap_server_t;
+typedef struct dap_server_thread_s dap_server_thread_t;
+
+struct dap_client_remote;
+
+typedef void (*dap_server_client_callback_t) (struct dap_client_remote *,void * arg); // Callback for specific client operations
+
+#define DAP_CLIENT_REMOTE_BUF 500000
+#define CLIENT_ID_SIZE 12
+
+typedef char dap_server_client_id[CLIENT_ID_SIZE];
+
+typedef struct traffic_stats {
+
+  size_t buf_size_total;
+  size_t buf_size_total_old; // for calculate speed
+  double speed_mbs; // MegaBits per second
+} traffic_stats_t;
+
+typedef struct dap_client_remote {
+
+  int socket;
+  dap_server_client_id id;
+
+  uint32_t  flags;
+  bool no_close;
+  bool kill_signal;
+
+  uint16_t port;
+  str_ip s_ip;
+
+  uint32_t buf_out_zero_count;
+  char buf_in[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for input data
+
+  size_t buf_in_size; // size of data that is in the input buffer
+
+  traffic_stats_t upload_stat;
+  traffic_stats_t download_stat;
+
+  char buf_out[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for output data
+  size_t buf_out_offset;
+
+  char hostaddr[1024]; // Address
+  char service[128];
+
+  size_t buf_out_size; // size of data that is in the output buffer
+  struct epoll_event  pevent;
+
+  EPOLL_HANDLE efd;            // Epoll fd
+  int tn;             // working thread index
+
+  time_t time_connection;
+  time_t last_time_active;
+
+  struct dap_server *server;
+  dap_server_thread_t *thread;
+
+  UT_hash_handle hh;
+  struct dap_client_remote *next, *prev;
+  struct dap_client_remote *knext, *kprev;
+
+  void *_internal;
+  void *_inheritor; // Internal data to specific client type, usualy states for state machine
+
+} dap_client_remote_t; // Node of bidirectional list of clients
+
+int   dap_client_remote_init( void ); //  Init clients module
+void  dap_client_remote_deinit( void ); // Deinit clients module
+
+dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *dsth );
+dap_client_remote_t *dap_client_remote_find( int sock, dap_server_thread_t *t );
+
+bool dap_client_remote_is_ready_to_read( dap_client_remote_t * sc );
+bool dap_client_remote_is_ready_to_write( dap_client_remote_t * sc );
+void dap_client_remote_ready_to_read( dap_client_remote_t * sc,bool is_ready );
+void dap_client_remote_ready_to_write( dap_client_remote_t * sc,bool is_ready );
+
+size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size );
+size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format,... );
+size_t dap_client_remote_read( dap_client_remote_t *sc, void * data, size_t data_size );
+
+//void dap_client_remote_remove( dap_client_remote_t *sc, struct dap_server * sh ); // Removes the client from the list
+void dap_client_remote_remove( dap_client_remote_t *sc );
+
+void dap_client_remote_shrink_buf_in( dap_client_remote_t * cl, size_t shrink_size );
+
diff --git a/include/dap_events.h b/include/dap_events.h
index 1b2d52ae807b080dba10cb2ad9a65c9959e3d069..2b27453f87088e5d8c3c26a4b57b391f98001439 100755
--- a/include/dap_events.h
+++ b/include/dap_events.h
@@ -1,94 +1,94 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#ifndef WIN32
-#include <netinet/in.h>
-
-#include <stdint.h>
-#include <pthread.h>
-#define EPOLL_HANDLE  int
-#else
-#define EPOLL_HANDLE  HANDLE
-#endif
-
-#include "uthash.h"
-#include "dap_events_socket.h"
-#include "dap_server.h"
-
-struct dap_events;
-
-typedef void (*dap_events_callback_t) (struct dap_events *, void *arg); // Callback for specific server's operations
-
-typedef struct dap_thread {
-  pthread_t tid;
-} dap_thread_t;
-
-struct dap_worker;
-
-typedef struct dap_events {
-
-  dap_events_socket_t *sockets; // Hashmap of event sockets
-  dap_events_socket_t *dlsockets; // Dlist of event sockets
-  dap_events_socket_t *to_kill_sockets; // Dlist of event sockets
-
-  pthread_rwlock_t sockets_rwlock;
-  void *_inheritor;  // Pointer to the internal data, HTTP for example
-  dap_thread_t proc_thread;
-  pthread_rwlock_t servers_rwlock;
-
-} dap_events_t;
-
-typedef struct dap_worker
-{
-  uint32_t event_sockets_count;
-  uint32_t event_to_kill_count;
-
-  EPOLL_HANDLE epoll_fd;
-  uint32_t number_thread;
-  pthread_mutex_t locker_on_count;
-  dap_events_t *events;
-
-} dap_worker_t;
-
-int32_t  dap_events_init( uint32_t a_threads_count, size_t conn_t ); // Init server module
-void dap_events_deinit( ); // Deinit server module
-
-void dap_events_thread_wake_up( dap_thread_t *th );
-dap_events_t* dap_events_new( );
-void dap_events_delete( dap_events_t * sh );
-//void dap_events_socket_remove_and_delete( dap_events_socket_t* a_es );
-void dap_events_socket_remove_and_delete(dap_events_socket_t* a_es, bool preserve_inheritor );
-
-void dap_events_kill_socket( dap_events_socket_t *a_es );
-
-int32_t dap_events_start( dap_events_t *sh );
-int32_t dap_events_wait( dap_events_t *sh );
-
-uint32_t dap_worker_get_index_min( );
-dap_worker_t *dap_worker_get_min( );
-
-void dap_worker_add_events_socket( dap_events_socket_t * a_events_socket );
-void dap_worker_print_all( );
-
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#ifndef WIN32
+#include <netinet/in.h>
+
+#include <stdint.h>
+#include <pthread.h>
+#define EPOLL_HANDLE  int
+#else
+#define EPOLL_HANDLE  HANDLE
+#endif
+
+#include "uthash.h"
+#include "dap_events_socket.h"
+#include "dap_server.h"
+
+struct dap_events;
+
+typedef void (*dap_events_callback_t) (struct dap_events *, void *arg); // Callback for specific server's operations
+
+typedef struct dap_thread {
+  pthread_t tid;
+} dap_thread_t;
+
+struct dap_worker;
+
+typedef struct dap_events {
+
+  dap_events_socket_t *sockets; // Hashmap of event sockets
+  dap_events_socket_t *dlsockets; // Dlist of event sockets
+  dap_events_socket_t *to_kill_sockets; // Dlist of event sockets
+
+  pthread_rwlock_t sockets_rwlock;
+  void *_inheritor;  // Pointer to the internal data, HTTP for example
+  dap_thread_t proc_thread;
+  pthread_rwlock_t servers_rwlock;
+
+} dap_events_t;
+
+typedef struct dap_worker
+{
+  uint32_t event_sockets_count;
+  uint32_t event_to_kill_count;
+
+  EPOLL_HANDLE epoll_fd;
+  uint32_t number_thread;
+  pthread_mutex_t locker_on_count;
+  dap_events_t *events;
+
+} dap_worker_t;
+
+int32_t  dap_events_init( uint32_t a_threads_count, size_t conn_t ); // Init server module
+void dap_events_deinit( ); // Deinit server module
+
+void dap_events_thread_wake_up( dap_thread_t *th );
+dap_events_t* dap_events_new( );
+void dap_events_delete( dap_events_t * sh );
+//void dap_events_socket_remove_and_delete( dap_events_socket_t* a_es );
+void dap_events_socket_remove_and_delete(dap_events_socket_t* a_es, bool preserve_inheritor );
+
+void dap_events_kill_socket( dap_events_socket_t *a_es );
+
+int32_t dap_events_start( dap_events_t *sh );
+int32_t dap_events_wait( dap_events_t *sh );
+
+uint32_t dap_worker_get_index_min( );
+dap_worker_t *dap_worker_get_min( );
+
+void dap_worker_add_events_socket( dap_events_socket_t * a_events_socket );
+void dap_worker_print_all( );
+
diff --git a/include/dap_events_socket.h b/include/dap_events_socket.h
index 0a3dd3bfe02b7ade9ae36f2912c12ce35340d5e0..ea1822433b904a84acd302b8abb7694fd9d2e8d6 100755
--- a/include/dap_events_socket.h
+++ b/include/dap_events_socket.h
@@ -1,158 +1,158 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#include <stdint.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include "uthash.h"
-#ifndef _WIN32
-#include <sys/epoll.h>
-#endif
-
-struct dap_events;
-struct dap_events_socket;
-struct dap_worker;
-
-typedef struct dap_server dap_server_t;
-typedef void (*dap_events_socket_callback_t) (struct dap_events_socket *,void * arg); // Callback for specific client operations
-
-typedef struct dap_events_socket_callbacks {
-
-    dap_events_socket_callback_t new_callback; // Create new client callback
-    dap_events_socket_callback_t delete_callback; // Delete client callback
-    dap_events_socket_callback_t read_callback; // Read function
-    dap_events_socket_callback_t write_callback; // Write function
-    dap_events_socket_callback_t error_callback; // Error processing function
-
-} dap_events_socket_callbacks_t;
-
-#define DAP_EVENTS_SOCKET_BUF 100000
-
-#if 0
-typedef struct dap_events_socket {
-
-    int socket;
-    bool signal_close;
-
-    bool _ready_to_write;
-    bool _ready_to_read;
-
-    uint32_t buf_out_zero_count;
-    union{
-        uint8_t buf_in[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for input data
-        char buf_in_str[DAP_EVENTS_SOCKET_BUF+1];
-    };
-    size_t buf_in_size; // size of data that is in the input buffer
-
-    uint8_t buf_out[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for output data
-
-    char hostaddr[1024]; // Address
-    char service[128];
-
-    size_t buf_out_size; // size of data that is in the output buffer
-
-    struct dap_events *events;
-
-    struct dap_worker *dap_worker;
-    dap_events_socket_callbacks_t *callbacks;
-
-    time_t time_connection;
-    time_t last_ping_request;
-    bool is_pingable;
-
-    UT_hash_handle hh;
-
-    void * _inheritor; // Inheritor data to specific client type, usualy states for state machine
-} dap_events_socket_t; // Node of bidirectional list of clients
-#endif
-
-typedef struct dap_events_socket {
-
-  int32_t socket;
-
-  uint32_t  flags;
-//  bool signal_close;
-  bool close_denied;
-  bool kill_signal;
-//  bool _ready_to_write;
-//  bool _ready_to_read;
-
-  uint32_t buf_out_zero_count;
-  union{
-    uint8_t buf_in[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for input data
-    char buf_in_str[DAP_EVENTS_SOCKET_BUF+1];
-  };
-  size_t buf_in_size; // size of data that is in the input buffer
-
-  uint8_t buf_out[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for output data
-
-  char hostaddr[1024]; // Address
-  char service[128];
-
-  size_t buf_out_size; // size of data that is in the output buffer
-
-  struct dap_events *events;
-  struct dap_worker *dap_worker;
-  struct epoll_event ev;
-
-  dap_events_socket_callbacks_t *callbacks;
-
-  time_t time_connection;
-  time_t last_time_active;
-  time_t last_ping_request;
-  bool is_pingable;
-
-  UT_hash_handle hh;
-  struct dap_events_socket *next, *prev;
-  struct dap_events_socket *knext, *kprev;
-
-  void *_inheritor; // Inheritor data to specific client type, usualy states for state machine
-
-} dap_events_socket_t; // Node of bidirectional list of clients
-
-int dap_events_socket_init(); //  Init clients module
-void dap_events_socket_deinit(); // Deinit clients module
-
-void dap_events_socket_create_after(dap_events_socket_t * a_es);
-
-dap_events_socket_t * dap_events_socket_wrap_no_add(struct dap_events * a_events,
-                                            int s, dap_events_socket_callbacks_t * a_callbacks); // Create new client and add it to the list
-
-
-dap_events_socket_t * dap_events_socket_find(int sock, struct dap_events * sh); // Find client by socket
-
-bool dap_events_socket_is_ready_to_read(dap_events_socket_t * sc);
-bool dap_events_socket_is_ready_to_write(dap_events_socket_t * sc);
-void dap_events_socket_set_readable(dap_events_socket_t * sc,bool is_ready);
-void dap_events_socket_set_writable(dap_events_socket_t * sc,bool is_ready);
-
-size_t dap_events_socket_write(dap_events_socket_t *sc, const void * data, size_t data_size);
-size_t dap_events_socket_write_f(dap_events_socket_t *sc, const char * format,...);
-size_t dap_events_socket_read(dap_events_socket_t *sc, void * data, size_t data_size);
-
-void dap_events_socket_delete(dap_events_socket_t *sc,bool preserve_inheritor); // Removes the client from the list
-
-void dap_events_socket_shrink_buf_in(dap_events_socket_t * cl, size_t shrink_size);
-
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include "uthash.h"
+#ifndef _WIN32
+#include <sys/epoll.h>
+#endif
+
+struct dap_events;
+struct dap_events_socket;
+struct dap_worker;
+
+typedef struct dap_server dap_server_t;
+typedef void (*dap_events_socket_callback_t) (struct dap_events_socket *,void * arg); // Callback for specific client operations
+
+typedef struct dap_events_socket_callbacks {
+
+    dap_events_socket_callback_t new_callback; // Create new client callback
+    dap_events_socket_callback_t delete_callback; // Delete client callback
+    dap_events_socket_callback_t read_callback; // Read function
+    dap_events_socket_callback_t write_callback; // Write function
+    dap_events_socket_callback_t error_callback; // Error processing function
+
+} dap_events_socket_callbacks_t;
+
+#define DAP_EVENTS_SOCKET_BUF 100000
+
+#if 0
+typedef struct dap_events_socket {
+
+    int socket;
+    bool signal_close;
+
+    bool _ready_to_write;
+    bool _ready_to_read;
+
+    uint32_t buf_out_zero_count;
+    union{
+        uint8_t buf_in[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for input data
+        char buf_in_str[DAP_EVENTS_SOCKET_BUF+1];
+    };
+    size_t buf_in_size; // size of data that is in the input buffer
+
+    uint8_t buf_out[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for output data
+
+    char hostaddr[1024]; // Address
+    char service[128];
+
+    size_t buf_out_size; // size of data that is in the output buffer
+
+    struct dap_events *events;
+
+    struct dap_worker *dap_worker;
+    dap_events_socket_callbacks_t *callbacks;
+
+    time_t time_connection;
+    time_t last_ping_request;
+    bool is_pingable;
+
+    UT_hash_handle hh;
+
+    void * _inheritor; // Inheritor data to specific client type, usualy states for state machine
+} dap_events_socket_t; // Node of bidirectional list of clients
+#endif
+
+typedef struct dap_events_socket {
+
+  int32_t socket;
+
+  uint32_t  flags;
+//  bool signal_close;
+  bool no_close;
+  bool kill_signal;
+//  bool _ready_to_write;
+//  bool _ready_to_read;
+
+  uint32_t buf_out_zero_count;
+  union{
+    uint8_t buf_in[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for input data
+    char buf_in_str[DAP_EVENTS_SOCKET_BUF+1];
+  };
+  size_t buf_in_size; // size of data that is in the input buffer
+
+  uint8_t buf_out[DAP_EVENTS_SOCKET_BUF+1]; // Internal buffer for output data
+
+  char hostaddr[1024]; // Address
+  char service[128];
+
+  size_t buf_out_size; // size of data that is in the output buffer
+
+  struct dap_events *events;
+  struct dap_worker *dap_worker;
+  struct epoll_event ev;
+
+  dap_events_socket_callbacks_t *callbacks;
+
+  time_t time_connection;
+  time_t last_time_active;
+  time_t last_ping_request;
+  bool is_pingable;
+
+  UT_hash_handle hh;
+  struct dap_events_socket *next, *prev;
+  struct dap_events_socket *knext, *kprev;
+
+  void *_inheritor; // Inheritor data to specific client type, usualy states for state machine
+
+} dap_events_socket_t; // Node of bidirectional list of clients
+
+int dap_events_socket_init(); //  Init clients module
+void dap_events_socket_deinit(); // Deinit clients module
+
+void dap_events_socket_create_after(dap_events_socket_t * a_es);
+
+dap_events_socket_t * dap_events_socket_wrap_no_add(struct dap_events * a_events,
+                                            int s, dap_events_socket_callbacks_t * a_callbacks); // Create new client and add it to the list
+
+
+dap_events_socket_t * dap_events_socket_find(int sock, struct dap_events * sh); // Find client by socket
+
+bool dap_events_socket_is_ready_to_read(dap_events_socket_t * sc);
+bool dap_events_socket_is_ready_to_write(dap_events_socket_t * sc);
+void dap_events_socket_set_readable(dap_events_socket_t * sc,bool is_ready);
+void dap_events_socket_set_writable(dap_events_socket_t * sc,bool is_ready);
+
+size_t dap_events_socket_write(dap_events_socket_t *sc, const void * data, size_t data_size);
+size_t dap_events_socket_write_f(dap_events_socket_t *sc, const char * format,...);
+size_t dap_events_socket_read(dap_events_socket_t *sc, void * data, size_t data_size);
+
+void dap_events_socket_delete(dap_events_socket_t *sc,bool preserve_inheritor); // Removes the client from the list
+
+void dap_events_socket_shrink_buf_in(dap_events_socket_t * cl, size_t shrink_size);
+
diff --git a/include/dap_memcached.h b/include/dap_memcached.h
index 40b87576dcfa52220ad37cda38436779e18ce119..169a1bf2d6126acaff65dc6dcd8599b80c9d2b8f 100755
--- a/include/dap_memcached.h
+++ b/include/dap_memcached.h
@@ -1,50 +1,50 @@
-#pragma once
-
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include "dap_common.h"
-
-/**
- * @brief dap_memcached_init
- * @param server_host
- * @param port
- * @return
- */
-int dap_memcached_init(const char *server_host, uint16_t port);
-
-/**
- * @brief is_dap_memcache_enable
- * @return
- */
-bool dap_memcache_is_enable(void);
-
-/**
- * @brief dap_memcached_deinit
- */
-void dap_memcached_deinit(void);
-
-/**
- * @brief dap_memcache_put
- * @param key
- * @param value
- * @param value_size
- * @param expiration if 0 value is never expire
- * @return
- */
-bool dap_memcache_put(const char* key, void *value, size_t value_size, time_t expiration);
-
-/**
- * @brief dap_memcache_get
- * @param key
- * @return true if key found
- */
-bool dap_memcache_get(const char* key, size_t * value_size, void ** result);
-
-/**
- * @brief dap_memcache_delete
- * @param key
- * @return
- */
-bool dap_memcache_delete(const char* key);
+#pragma once
+
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "dap_common.h"
+
+/**
+ * @brief dap_memcached_init
+ * @param server_host
+ * @param port
+ * @return
+ */
+int dap_memcached_init(const char *server_host, uint16_t port);
+
+/**
+ * @brief is_dap_memcache_enable
+ * @return
+ */
+bool dap_memcache_is_enable(void);
+
+/**
+ * @brief dap_memcached_deinit
+ */
+void dap_memcached_deinit(void);
+
+/**
+ * @brief dap_memcache_put
+ * @param key
+ * @param value
+ * @param value_size
+ * @param expiration if 0 value is never expire
+ * @return
+ */
+bool dap_memcache_put(const char* key, void *value, size_t value_size, time_t expiration);
+
+/**
+ * @brief dap_memcache_get
+ * @param key
+ * @return true if key found
+ */
+bool dap_memcache_get(const char* key, size_t * value_size, void ** result);
+
+/**
+ * @brief dap_memcache_delete
+ * @param key
+ * @return
+ */
+bool dap_memcache_delete(const char* key);
diff --git a/include/dap_server.h b/include/dap_server.h
index 0aada31337fae99308b3f0010c6e0111a24146f1..eb668b3c4ae520471009a12f6a5177107bf4aca2 100755
--- a/include/dap_server.h
+++ b/include/dap_server.h
@@ -1,147 +1,146 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP 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 Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#pragma once
-
-#ifndef _WIN32
-#include <netinet/in.h>
-
-#include <stdint.h>
-#include <pthread.h>
-
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#define EPOLL_HANDLE  int
-#else
-#define EPOLL_HANDLE  HANDLE
-#endif
-
-#include "uthash.h"
-#include "utlist.h"
-
-#include "dap_cpu_monitor.h"
-#include "dap_client_remote.h"
-
-typedef enum dap_server_type {DAP_SERVER_TCP} dap_server_type_t;
-
-#define DAP_BIT( x ) ( 1 << x )
-
-#define DAP_SOCK_READY_TO_READ     DAP_BIT( 0 )
-#define DAP_SOCK_READY_TO_WRITE    DAP_BIT( 1 )
-#define DAP_SOCK_SIGNAL_CLOSE      DAP_BIT( 2 )
-#define DAP_SOCK_ACTIVE            DAP_BIT( 3 )
-
-typedef struct dap_server_thread_s {
-
-  EPOLL_HANDLE epoll_fd;
-
-  uint32_t thread_num;
-  uint32_t connections_count;
-  uint32_t to_kill_count;
-
-  struct epoll_event  *epoll_events;
-  dap_client_remote_t *dap_remote_clients;
-  dap_client_remote_t *dap_clients_to_kill;
-
-  pthread_mutex_t mutex_dlist_add_remove;
-
-} dap_server_thread_t;
-
-struct dap_server;
-
-typedef void (*dap_server_callback_t)( struct dap_server *,void * arg ); // Callback for specific server's operations
-
-typedef struct dap_server {
-
-  dap_server_type_t type; // Server's type
-  uint16_t port; // Listen port
-  char *address; // Listen address
-
-  dap_client_remote_t *clients; // Hashmap of clients
-
-  int32_t socket_listener; // Socket for listener
-  EPOLL_HANDLE epoll_fd; // Epoll fd
-
-  struct sockaddr_in listener_addr; // Kernel structure for listener's binded address
-
-  void *_inheritor;  // Pointer to the internal data, HTTP for example
-
-  pthread_mutex_t mutex_on_hash;
-  dap_cpu_stats_t cpu_stats;
-
-  dap_server_callback_t server_delete_callback;
-
-  dap_server_client_callback_t client_new_callback; // Create new client callback
-  dap_server_client_callback_t client_delete_callback; // Delete client callback
-  dap_server_client_callback_t client_read_callback; // Read function
-  dap_server_client_callback_t client_write_callback; // Write function
-  dap_server_client_callback_t client_error_callback; // Error processing function
-
-} dap_server_t;
-
-int32_t dap_server_init( uint32_t count_threads ); // Init server module
-void    dap_server_deinit( void ); // Deinit server module
-
-dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type );
-
-int32_t dap_server_loop( dap_server_t *d_server );
-
-#define DL_LIST_REMOVE_NODE( head, obj, _prev_, _next_, total )  \
-                                                                 \
-  if ( obj->_next_ ) {                                           \
-                                                                 \
-    if ( obj->_prev_ )                                           \
-      obj->_next_->_prev_ = obj->_prev_;                         \
-    else {                                                       \
-                                                                 \
-      obj->_next_->_prev_ = NULL;                                \
-      head = obj->_next_;                                        \
-    }                                                            \
-  }                                                              \
-                                                                 \
-  if ( obj->_prev_ ) {                                           \
-                                                                 \
-    if ( obj->_next_ )                                           \
-      obj->_prev_->_next_ = obj->_next_;                         \
-    else {                                                       \
-                                                                 \
-      obj->_prev_->_next_ = NULL;                                \
-    }                                                            \
-  }                                                              \
-  -- total;
-
-#define DL_LIST_ADD_NODE_HEAD( head, obj, _prev_, _next_, total )\
-                                                                 \
-  if ( !total ) {                                                \
-                                                                 \
-    obj->_prev_    = NULL;                                       \
-    obj->_next_    = NULL;                                       \
-                                                                 \
-    head = obj;                                                  \
-  }                                                              \
-  else {                                                         \
-                                                                 \
-    head->_prev_ = obj;                                          \
-                                                                 \
-    obj->_prev_ = NULL;                                          \
-    obj->_next_ = head;                                          \
-                                                                 \
-    head = obj;                                                  \
-  }                                                              \
-  ++ total;
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#pragma once
+
+#ifndef _WIN32
+#include <netinet/in.h>
+
+#include <stdint.h>
+#include <pthread.h>
+
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#define EPOLL_HANDLE  int
+#else
+#define EPOLL_HANDLE  HANDLE
+#endif
+
+#include "uthash.h"
+#include "utlist.h"
+
+#include "dap_cpu_monitor.h"
+#include "dap_client_remote.h"
+
+typedef enum dap_server_type {DAP_SERVER_TCP} dap_server_type_t;
+
+#define BIT( x ) ( 1 << x )
+
+#define DAP_SOCK_READY_TO_READ     BIT( 0 )
+#define DAP_SOCK_READY_TO_WRITE    BIT( 1 )
+#define DAP_SOCK_SIGNAL_CLOSE      BIT( 2 )
+#define DAP_SOCK_ACTIVE            BIT( 3 )
+
+typedef struct dap_server_thread_s {
+
+  EPOLL_HANDLE epoll_fd;
+
+  uint32_t thread_num;
+  uint32_t connections_count;
+  uint32_t to_kill_count;
+
+  struct epoll_event  *epoll_events;
+  dap_client_remote_t *dap_remote_clients;
+  dap_client_remote_t *hclients; // Hashmap of clients
+  dap_client_remote_t *dap_clients_to_kill;
+
+  pthread_mutex_t mutex_dlist_add_remove;
+  pthread_mutex_t mutex_on_hash;
+
+} dap_server_thread_t;
+
+struct dap_server;
+
+typedef void (*dap_server_callback_t)( struct dap_server *,void * arg ); // Callback for specific server's operations
+
+typedef struct dap_server {
+
+  dap_server_type_t type; // Server's type
+  uint16_t port; // Listen port
+  char *address; // Listen address
+
+  int32_t socket_listener; // Socket for listener
+  EPOLL_HANDLE epoll_fd; // Epoll fd
+
+  struct sockaddr_in listener_addr; // Kernel structure for listener's binded address
+
+  void *_inheritor;  // Pointer to the internal data, HTTP for example
+
+  dap_cpu_stats_t cpu_stats;
+
+  dap_server_callback_t server_delete_callback;
+
+  dap_server_client_callback_t client_new_callback; // Create new client callback
+  dap_server_client_callback_t client_delete_callback; // Delete client callback
+  dap_server_client_callback_t client_read_callback; // Read function
+  dap_server_client_callback_t client_write_callback; // Write function
+  dap_server_client_callback_t client_error_callback; // Error processing function
+
+} dap_server_t;
+
+int32_t dap_server_init( uint32_t count_threads ); // Init server module
+void    dap_server_deinit( void ); // Deinit server module
+
+dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type );
+
+int32_t dap_server_loop( dap_server_t *d_server );
+
+#define DL_LIST_REMOVE_NODE( head, obj, _prev_, _next_, total )  \
+                                                                 \
+  if ( obj->_next_ ) {                                           \
+                                                                 \
+    if ( obj->_prev_ )                                           \
+      obj->_next_->_prev_ = obj->_prev_;                         \
+    else {                                                       \
+                                                                 \
+      obj->_next_->_prev_ = NULL;                                \
+      head = obj->_next_;                                        \
+    }                                                            \
+  }                                                              \
+                                                                 \
+  if ( obj->_prev_ ) {                                           \
+                                                                 \
+    if ( obj->_next_ )                                           \
+      obj->_prev_->_next_ = obj->_next_;                         \
+    else {                                                       \
+                                                                 \
+      obj->_prev_->_next_ = NULL;                                \
+    }                                                            \
+  }                                                              \
+  -- total;
+
+#define DL_LIST_ADD_NODE_HEAD( head, obj, _prev_, _next_, total )\
+                                                                 \
+  if ( !total ) {                                                \
+                                                                 \
+    obj->_prev_    = NULL;                                       \
+    obj->_next_    = NULL;                                       \
+                                                                 \
+    head = obj;                                                  \
+  }                                                              \
+  else {                                                         \
+                                                                 \
+    head->_prev_ = obj;                                          \
+                                                                 \
+    obj->_prev_ = NULL;                                          \
+    obj->_next_ = head;                                          \
+                                                                 \
+    head = obj;                                                  \
+  }                                                              \
+  ++ total;
diff --git a/include/dap_traffic_track.h b/include/dap_traffic_track.h
index 1cfae9d22689621d0c99a746f96d07a9321543a3..899a77a80c2e457f8bddc3e922e9409820862ae0 100755
--- a/include/dap_traffic_track.h
+++ b/include/dap_traffic_track.h
@@ -1,50 +1,50 @@
-/*
- * Authors:
- * Anatoliy Jurotich  <anatoliy.kurotich@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2018
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#pragma once
-
-#include "dap_client_remote.h"
-#include "dap_server.h"
-
-typedef void (*dap_traffic_callback_t) (dap_server_t *);
-
-/**
- * @brief dap_traffic_track_init
- * @param clients
- * @param timeout callback
- */
-void dap_traffic_track_init( dap_server_t *server, time_t timeout );
-
-/**
- * @brief dap_traffic_track_deinit
- */
-void dap_traffic_track_deinit( void );
-
-/**
- * @brief dap_traffic_add_callback
- */
-void dap_traffic_callback_set( dap_traffic_callback_t );
-
-void dap_traffic_callback_stop( void );
-
+/*
+ * Authors:
+ * Anatoliy Jurotich  <anatoliy.kurotich@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include "dap_client_remote.h"
+#include "dap_server.h"
+
+typedef void (*dap_traffic_callback_t) (dap_server_t *);
+
+/**
+ * @brief dap_traffic_track_init
+ * @param clients
+ * @param timeout callback
+ */
+void dap_traffic_track_init( dap_server_t *server, time_t timeout );
+
+/**
+ * @brief dap_traffic_track_deinit
+ */
+void dap_traffic_track_deinit( void );
+
+/**
+ * @brief dap_traffic_add_callback
+ */
+void dap_traffic_callback_set( dap_traffic_callback_t );
+
+void dap_traffic_callback_stop( void );
+
diff --git a/src/dap_client_remote.c b/src/dap_client_remote.c
index ad163e09a938950d907a69ea9e4b5a3f6fb48fb4..6f60751ff90eee8ff93421a8558268648f8e5733 100755
--- a/src/dap_client_remote.c
+++ b/src/dap_client_remote.c
@@ -1,345 +1,345 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2018
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#ifndef _WIN32
-#include <unistd.h>
-#include <arpa/inet.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include "dap_common.h"
-#include "dap_server.h"
-#include "dap_client_remote.h"
-
-#define LOG_TAG "dap_client_remote"
-
-/**
- * @brief dap_client_init Init clients module
- * @return Zero if ok others if no
- */
-int dap_client_remote_init( )
-{
-  log_it( L_NOTICE, "Initialized socket client module" );
-
-  return 0;
-}
-
-/**
- * @brief dap_client_deinit Deinit clients module
- */
-void dap_client_remote_deinit( )
-{
-
-  return;
-}
-
-/**
- * @brief _save_ip_and_port
- * @param cl
- */
-void _save_ip_and_port( dap_client_remote_t * cl )
-{
-  struct sockaddr_in ip_adr_get;
-  socklen_t ip_adr_len;
-
-  getpeername( cl->socket, (struct sockaddr * restrict)&ip_adr_get, &ip_adr_len );
-
-  cl->port = ntohs( ip_adr_get.sin_port );
-  strcpy( cl->s_ip, inet_ntoa(ip_adr_get.sin_addr) );
-}
-
-/**
- * @brief dap_client_remote_create Create new client and add it to the list
- * @param sh Server instance
- * @param s Client's socket
- * @return Pointer to the new list's node
- */
-dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *dsth )
-{
-  dap_client_remote_t *dsc = DAP_NEW_Z( dap_client_remote_t );
-
-  dap_random_string_fill( dsc->id, CLIENT_ID_SIZE );
-
-  dsc->socket = s;
-  dsc->server = sh;
-  dsc->tn = dsth->thread_num;
-  dsc->efd = dsth->epoll_fd;
-  dsc->time_connection = dsc->last_time_active = time( NULL) ;
-
-  dsc->pevent.events = EPOLLIN | EPOLLOUT | EPOLLERR;
-  dsc->pevent.data.ptr = dsc;
-
-  dsc->flags = DAP_SOCK_READY_TO_READ;
-  dsc->buf_out_offset = 0;
-
-  _save_ip_and_port( dsc );
-
-  pthread_mutex_lock( &sh->mutex_on_hash );
-  HASH_ADD_INT( sh->clients, socket, dsc );
-  pthread_mutex_unlock( &sh->mutex_on_hash );
-
-  if ( sh->client_new_callback )
-    sh->client_new_callback( dsc, NULL ); // Init internal structure
-
-  log_it(L_DEBUG, "Create remote client: ip: %s port %d", dsc->s_ip, dsc->port );
-
-    //log_it(L_DEBUG, "Create new client. ID: %s", dsc->id);
-  return dsc;
-}
-
-/**
- * @brief safe_client_remove Removes the client from the list
- * @param sc Client instance
- */
-void dap_client_remote_remove( dap_client_remote_t *sc, struct dap_server * sh )
-{
-  log_it(L_DEBUG, "dap_client_remote_remove [THREAD %u] efd %u", sc->tn , sc->efd );
-
-//  EPOLL_HANDLE efd;            // Epoll fd
-//  int tn;             // working thread index
-
-  pthread_mutex_lock( &sh->mutex_on_hash );
-  HASH_DEL( sc->server->clients, sc );
-  pthread_mutex_unlock( &sh->mutex_on_hash );
-
-  if( sc->server->client_delete_callback )
-    sc->server->client_delete_callback( sc, NULL ); // Init internal structure
-
-  if( sc->_inheritor )
-    free( sc->_inheritor );
-
-  if( sc->socket )
-    close( sc->socket );
-
-  free( sc );
-}
-
-/**
- * @brief dap_server_client_find
- * @param sock
- * @param sh
- * @return
- */
-dap_client_remote_t *dap_client_remote_find( int sock, struct dap_server *sh )
-{
-  dap_client_remote_t *ret = NULL;
-
-  pthread_mutex_lock( &sh->mutex_on_hash );
-  HASH_FIND_INT( sh->clients, &sock, ret );
-  pthread_mutex_unlock( &sh->mutex_on_hash );
-
-  return ret;
-}
-
-/**
- * @brief dap_client_remote_ready_to_read
- * @param sc
- * @param isReady
- */
-void  dap_client_remote_ready_to_read( dap_client_remote_t *sc, bool is_ready )
-{
-  if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) )
-    return;
-
-//  log_it( L_ERROR, "remote_ready_to_read() %u efd %X", sc->socket, sc->efd );
-
-  if ( is_ready )
-    sc->flags |= DAP_SOCK_READY_TO_READ;
-  else
-    sc->flags ^= DAP_SOCK_READY_TO_READ;
-
-  int events = EPOLLERR;
-
-  if( sc->flags & DAP_SOCK_READY_TO_READ )
-    events |= EPOLLIN;
-
-  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
-    events |= EPOLLOUT;
-
-  sc->pevent.events = events;
-
-  if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 )
-    log_it( L_ERROR, "epoll_ctl failed 000" );
-}
-
-/**
- * @brief dap_client_remote_ready_to_write
- * @param sc
- * @param isReady
- */
-void  dap_client_remote_ready_to_write( dap_client_remote_t *sc, bool is_ready )
-{
-  if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) )
-    return;
-
-//    log_it( L_ERROR, "remote_ready_to_write() %u efd %X", sc->socket, sc->efd );
-
-  if ( is_ready )
-    sc->flags |= DAP_SOCK_READY_TO_WRITE;
-  else
-    sc->flags ^= DAP_SOCK_READY_TO_WRITE;
-
-  int events = EPOLLERR;
-
-  if( sc->flags & DAP_SOCK_READY_TO_READ )
-    events |= EPOLLIN;
-
-  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
-    events |= EPOLLOUT;
-
-  sc->pevent.events = events;
-
-  if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 )
-    log_it( L_ERROR, "epoll_ctl failed 001" );
-}
-
-/**
- * @brief dap_client_write Write data to the client
- * @param sc Client instance
- * @param data Pointer to data
- * @param data_size Size of data to write
- * @return Number of bytes that were placed into the buffer
- */
-size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size )
-{     
-  if ( sc->buf_out_size + data_size > sizeof(sc->buf_out) ) {
-    log_it( L_WARNING, "Client buffer overflow. Packet loosed" );
-    return 0;
-  }
-
-  memcpy( sc->buf_out + sc->buf_out_size, data, data_size );
-  sc->buf_out_size += data_size;
-  return data_size;
-}
-
-/**
- * @brief dap_client_write_f Write formatted text to the client
- * @param a_client Client instance
- * @param a_format Format
- * @return Number of bytes that were placed into the buffer
- */
-size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format, ... )
-{
-  size_t max_data_size = sizeof( a_client->buf_out ) - a_client->buf_out_size;
-
-  va_list ap;
-  va_start( ap, a_format );
-
-  int ret = vsnprintf( a_client->buf_out + a_client->buf_out_size, max_data_size, a_format, ap );
-
-  va_end( ap );
-
-  if( ret > 0 ) {
-    a_client->buf_out_size += (unsigned long)ret;
-    return (size_t)ret;
-  } 
-  else {
-    log_it( L_ERROR, "Can't write out formatted data '%s'", a_format );
-    return 0;
-  }
-}
-
-/**
- * @brief dap_client_read Read data from input buffer
- * @param a_client Client instasnce
- * @param a_data Pointer to memory where to store the data
- * @param a_data_size Size of data to read
- * @return Actual bytes number that were read
- */
-size_t dap_client_remote_read( dap_client_remote_t *a_client, void *a_data, size_t a_data_size )
-{
-  if ( a_data_size < a_client->buf_in_size ) {
-
-    memcpy( a_data, a_client->buf_in, a_data_size );
-    memmove( a_client->buf_in, a_client->buf_in + a_data_size, a_client->buf_in_size - a_data_size );
-  } 
-  else {
-    if ( a_data_size > a_client->buf_in_size ) {
-      a_data_size = a_client->buf_in_size;
-    }
-    memcpy( a_data, a_client->buf_in, a_data_size );
-  }
-
-  a_client->buf_in_size -= a_data_size;
-
-  return a_data_size;
-}
-
-
-/**
- * @brief dap_client_remote_shrink_client_buf_in Shrink input buffer (shift it left)
- * @param a_client Client instance
- * @param a_shrink_size Size on wich we shrink the buffer with shifting it left
- */
-void dap_client_remote_shrink_buf_in( dap_client_remote_t *a_client, size_t a_shrink_size )
-{
-#if 0
-    if((a_shrink_size==0)||(a_client->buf_in_size==0) ){
-        return;
-    }else if(a_client->buf_in_size>a_shrink_size){
-        size_t buf_size=a_client->buf_in_size-a_shrink_size;
-        void * buf = malloc(buf_size);
-        memcpy(buf,a_client->buf_in+ a_shrink_size,buf_size );
-        memcpy(a_client->buf_in,buf,buf_size);
-        a_client->buf_in_size=buf_size;
-        free(buf);
-    }else {
-        a_client->buf_in_size=0;
-    }
-#endif
-
-  if ( a_shrink_size == 0 || a_client->buf_in_size == 0 )
-    return;
-
-  if ( a_client->buf_in_size > a_shrink_size ) {
-
-    size_t buf_size = a_client->buf_in_size - a_shrink_size;
-    memmove( a_client->buf_in, a_client->buf_in + a_shrink_size, buf_size );
-/**
-    void *buf = malloc( buf_size );
-    memcpy( buf, a_client->buf_in + a_shrink_size, buf_size );
-    memcpy( a_client->buf_in, buf, buf_size );
-    // holy shit
-    a_client->buf_in_size = buf_size;
-    free( buf );
-**/
-    a_client->buf_in_size = buf_size;
-  }
-  else {
-    a_client->buf_in_size = 0;
-  }
-}
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <arpa/inet.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#else
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include "dap_common.h"
+#include "dap_server.h"
+#include "dap_client_remote.h"
+
+#define LOG_TAG "dap_client_remote"
+
+/**
+ * @brief dap_client_init Init clients module
+ * @return Zero if ok others if no
+ */
+int dap_client_remote_init( )
+{
+  log_it( L_NOTICE, "Initialized socket client module" );
+
+  return 0;
+}
+
+/**
+ * @brief dap_client_deinit Deinit clients module
+ */
+void dap_client_remote_deinit( )
+{
+
+  return;
+}
+
+/**
+ * @brief _save_ip_and_port
+ * @param cl
+ */
+void _save_ip_and_port( dap_client_remote_t * cl )
+{
+  struct sockaddr_in ip_adr_get;
+  socklen_t ip_adr_len;
+
+  getpeername( cl->socket, (struct sockaddr * restrict)&ip_adr_get, &ip_adr_len );
+
+  cl->port = ntohs( ip_adr_get.sin_port );
+  strcpy( cl->s_ip, inet_ntoa(ip_adr_get.sin_addr) );
+}
+
+/**
+ * @brief dap_client_remote_create Create new client and add it to the list
+ * @param sh Server instance
+ * @param s Client's socket
+ * @return Pointer to the new list's node
+ */
+dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *t )
+{
+  dap_client_remote_t *dsc = DAP_NEW_Z( dap_client_remote_t );
+
+  dap_random_string_fill( dsc->id, CLIENT_ID_SIZE );
+
+  dsc->socket = s;
+  dsc->server = sh;
+  dsc->tn = t->thread_num;
+  dsc->thread = t;
+  dsc->efd = t->epoll_fd;
+  dsc->time_connection = dsc->last_time_active = time( NULL) ;
+
+  dsc->pevent.events = EPOLLIN | EPOLLOUT | EPOLLERR;
+  dsc->pevent.data.ptr = dsc;
+
+  dsc->flags = DAP_SOCK_READY_TO_READ;
+  dsc->buf_out_offset = 0;
+
+  _save_ip_and_port( dsc );
+
+  pthread_mutex_lock( &t->mutex_on_hash );
+  HASH_ADD_INT( t->hclients, socket, dsc );
+  pthread_mutex_unlock( &t->mutex_on_hash );
+
+  if ( sh->client_new_callback )
+    sh->client_new_callback( dsc, NULL ); // Init internal structure
+
+  log_it(L_DEBUG, "Create remote client: ip: %s port %d", dsc->s_ip, dsc->port );
+
+    //log_it(L_DEBUG, "Create new client. ID: %s", dsc->id);
+  return dsc;
+}
+
+/**
+ * @brief safe_client_remove Removes the client from the list
+ * @param sc Client instance
+ */
+void dap_client_remote_remove( dap_client_remote_t *sc )
+{
+  log_it(L_DEBUG, "dap_client_remote_remove [THREAD %u] efd %u", sc->tn , sc->efd );
+
+  dap_server_thread_t *t = sc->thread;
+
+  pthread_mutex_lock( &t->mutex_on_hash );
+  HASH_DEL( t->hclients, sc );
+  pthread_mutex_unlock( &t->mutex_on_hash );
+
+  if( sc->server->client_delete_callback )
+    sc->server->client_delete_callback( sc, NULL ); // Init internal structure
+
+  if( sc->_inheritor )
+    free( sc->_inheritor );
+
+  if( sc->socket )
+    close( sc->socket );
+
+  free( sc );
+}
+
+/**
+ * @brief dap_server_client_find
+ * @param sock
+ * @param sh
+ * @return
+ */
+dap_client_remote_t *dap_client_remote_find( int sock, dap_server_thread_t *t )
+{
+  dap_client_remote_t *ret = NULL;
+
+  pthread_mutex_lock( &t->mutex_on_hash );
+  HASH_FIND_INT( t->hclients, &sock, ret );
+  pthread_mutex_unlock( &t->mutex_on_hash );
+
+  return ret;
+}
+
+/**
+ * @brief dap_client_remote_ready_to_read
+ * @param sc
+ * @param isReady
+ */
+void  dap_client_remote_ready_to_read( dap_client_remote_t *sc, bool is_ready )
+{
+  if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) )
+    return;
+
+//  log_it( L_ERROR, "remote_ready_to_read() %u efd %X", sc->socket, sc->efd );
+
+  if ( is_ready )
+    sc->flags |= DAP_SOCK_READY_TO_READ;
+  else
+    sc->flags ^= DAP_SOCK_READY_TO_READ;
+
+  int events = EPOLLERR;
+
+  if( sc->flags & DAP_SOCK_READY_TO_READ )
+    events |= EPOLLIN;
+
+  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
+    events |= EPOLLOUT;
+
+  sc->pevent.events = events;
+
+  if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 )
+    log_it( L_ERROR, "epoll_ctl failed 000" );
+}
+
+/**
+ * @brief dap_client_remote_ready_to_write
+ * @param sc
+ * @param isReady
+ */
+void  dap_client_remote_ready_to_write( dap_client_remote_t *sc, bool is_ready )
+{
+  if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) )
+    return;
+
+//    log_it( L_ERROR, "remote_ready_to_write() %u efd %X", sc->socket, sc->efd );
+
+  if ( is_ready )
+    sc->flags |= DAP_SOCK_READY_TO_WRITE;
+  else
+    sc->flags ^= DAP_SOCK_READY_TO_WRITE;
+
+  int events = EPOLLERR;
+
+  if( sc->flags & DAP_SOCK_READY_TO_READ )
+    events |= EPOLLIN;
+
+  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
+    events |= EPOLLOUT;
+
+  sc->pevent.events = events;
+
+  if( epoll_ctl(sc->efd, EPOLL_CTL_MOD, sc->socket, &sc->pevent) != 0 )
+    log_it( L_ERROR, "epoll_ctl failed 001" );
+}
+
+/**
+ * @brief dap_client_write Write data to the client
+ * @param sc Client instance
+ * @param data Pointer to data
+ * @param data_size Size of data to write
+ * @return Number of bytes that were placed into the buffer
+ */
+size_t dap_client_remote_write( dap_client_remote_t *sc, const void * data, size_t data_size )
+{     
+  if ( sc->buf_out_size + data_size > sizeof(sc->buf_out) ) {
+    log_it( L_WARNING, "Client buffer overflow. Packet loosed" );
+    return 0;
+  }
+
+  memcpy( sc->buf_out + sc->buf_out_size, data, data_size );
+  sc->buf_out_size += data_size;
+  return data_size;
+}
+
+/**
+ * @brief dap_client_write_f Write formatted text to the client
+ * @param a_client Client instance
+ * @param a_format Format
+ * @return Number of bytes that were placed into the buffer
+ */
+size_t dap_client_remote_write_f( dap_client_remote_t *a_client, const char * a_format, ... )
+{
+  size_t max_data_size = sizeof( a_client->buf_out ) - a_client->buf_out_size;
+
+  va_list ap;
+  va_start( ap, a_format );
+
+  int ret = vsnprintf( a_client->buf_out + a_client->buf_out_size, max_data_size, a_format, ap );
+
+  va_end( ap );
+
+  if( ret > 0 ) {
+    a_client->buf_out_size += (unsigned long)ret;
+    return (size_t)ret;
+  } 
+  else {
+    log_it( L_ERROR, "Can't write out formatted data '%s'", a_format );
+    return 0;
+  }
+}
+
+/**
+ * @brief dap_client_read Read data from input buffer
+ * @param a_client Client instasnce
+ * @param a_data Pointer to memory where to store the data
+ * @param a_data_size Size of data to read
+ * @return Actual bytes number that were read
+ */
+size_t dap_client_remote_read( dap_client_remote_t *a_client, void *a_data, size_t a_data_size )
+{
+  if ( a_data_size < a_client->buf_in_size ) {
+
+    memcpy( a_data, a_client->buf_in, a_data_size );
+    memmove( a_client->buf_in, a_client->buf_in + a_data_size, a_client->buf_in_size - a_data_size );
+  } 
+  else {
+    if ( a_data_size > a_client->buf_in_size ) {
+      a_data_size = a_client->buf_in_size;
+    }
+    memcpy( a_data, a_client->buf_in, a_data_size );
+  }
+
+  a_client->buf_in_size -= a_data_size;
+
+  return a_data_size;
+}
+
+
+/**
+ * @brief dap_client_remote_shrink_client_buf_in Shrink input buffer (shift it left)
+ * @param a_client Client instance
+ * @param a_shrink_size Size on wich we shrink the buffer with shifting it left
+ */
+void dap_client_remote_shrink_buf_in( dap_client_remote_t *a_client, size_t a_shrink_size )
+{
+#if 0
+    if((a_shrink_size==0)||(a_client->buf_in_size==0) ){
+        return;
+    }else if(a_client->buf_in_size>a_shrink_size){
+        size_t buf_size=a_client->buf_in_size-a_shrink_size;
+        void * buf = malloc(buf_size);
+        memcpy(buf,a_client->buf_in+ a_shrink_size,buf_size );
+        memcpy(a_client->buf_in,buf,buf_size);
+        a_client->buf_in_size=buf_size;
+        free(buf);
+    }else {
+        a_client->buf_in_size=0;
+    }
+#endif
+
+  if ( a_shrink_size == 0 || a_client->buf_in_size == 0 )
+    return;
+
+  if ( a_client->buf_in_size > a_shrink_size ) {
+
+    size_t buf_size = a_client->buf_in_size - a_shrink_size;
+    memmove( a_client->buf_in, a_client->buf_in + a_shrink_size, buf_size );
+/**
+    void *buf = malloc( buf_size );
+    memcpy( buf, a_client->buf_in + a_shrink_size, buf_size );
+    memcpy( a_client->buf_in, buf, buf_size );
+    // holy shit
+    a_client->buf_in_size = buf_size;
+    free( buf );
+**/
+    a_client->buf_in_size = buf_size;
+  }
+  else {
+    a_client->buf_in_size = 0;
+  }
+}
diff --git a/src/dap_events.c b/src/dap_events.c
index 5c6e730ce78c5017b2699cc612a6cb180442a0f7..36d981f503a1434d2555a9c2de1fee2b37653fde 100755
--- a/src/dap_events.c
+++ b/src/dap_events.c
@@ -1,596 +1,600 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#define __USE_GNU
-
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-
-#ifndef _WIN32
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <sys/epoll.h>
-
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-
-#if 1
-#include <sys/timerfd.h>
-#elif defined(DAP_OS_ANDROID)
-#define NO_POSIX_SHED
-#define NO_TIMER
-#endif
-
-#else
-
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-
-//#define NO_TIMER
-
-#endif
-
-#include <utlist.h>
-#include <sched.h>
-
-#include "dap_common.h"
-#include "dap_events.h"
-
-#define DAP_MAX_EPOLL_EVENTS    8192
-
-//typedef struct open_connection_info_s {
-//    dap_events_socket_t *es;
-//    struct open_connection_info *prev;
-//    struct open_connection_info *next;
-//} dap_events_socket_info_t;
-
-//dap_events_socket_info_t **s_dap_events_sockets;
-
-static uint32_t s_threads_count = 1;
-static size_t   s_connection_timeout = 600;
-static struct epoll_event *g_epoll_events = NULL;
-
-dap_worker_t *s_workers = NULL;
-dap_thread_t *s_threads = NULL;
-
-#define LOG_TAG "dap_events"
-
-uint32_t s_get_cpu_count( )
-{
-#ifdef _WIN32
-  SYSTEM_INFO si;
-
-  GetSystemInfo( &si );
-  return si.dwNumberOfProcessors;
-#else
-#ifndef NO_POSIX_SHED
-  cpu_set_t cs;
-  CPU_ZERO( &cs );
-  sched_getaffinity( 0, sizeof(cs), &cs );
-
-  uint32_t count = 0;
-  for ( int i = 0; i < 32; i++ ){
-    if ( CPU_ISSET(i, &cs) )
-    count ++;
-  }
-  return count;
-#else
-  return 1;
-#endif
-#endif
-}
-
-/**
- * @brief sa_server_init Init server module
- * @arg a_threads_count  number of events processor workers in parallel threads
- * @return Zero if ok others if no
- */
-int32_t dap_events_init( uint32_t a_threads_count, size_t conn_timeout )
-{
-  s_threads_count = a_threads_count ? a_threads_count : s_get_cpu_count( );
-
-  if ( conn_timeout )
-    s_connection_timeout = conn_timeout;
-
-  s_workers = (dap_worker_t *) calloc( 1, sizeof(dap_worker_t) * s_threads_count );
-  s_threads = (dap_thread_t *) calloc( 1, sizeof(dap_thread_t) * s_threads_count );
-  if ( !s_workers || !s_threads )
-    goto err;
-
-  g_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * DAP_MAX_EPOLL_EVENTS * s_threads_count );
-  if ( !g_epoll_events )
-    goto err;
-
-  if ( dap_events_socket_init() != 0 ) {
-
-    log_it( L_CRITICAL, "Can't init client submodule dap_events_socket_init( )" );
-    goto err;
-  }
-
-  log_it( L_NOTICE, "Initialized socket server module" );
-
-  #ifndef _WIN32
-    signal( SIGPIPE, SIG_IGN );
-  #endif
-  return 0;
-
-err:
-  dap_events_deinit( );
-  return -1;
-}
-
-/**
- * @brief sa_server_deinit Deinit server module
- */
-void dap_events_deinit( )
-{
-  dap_events_socket_deinit( );
-
-  if ( g_epoll_events )
-    free( g_epoll_events );
-
-  if ( s_threads )
-    free( s_threads );
-
-  if ( s_workers )
-    free( s_workers );
-}
-
-/**
- * @brief server_new Creates new empty instance of server_t
- * @return New instance
- */
-dap_events_t * dap_events_new( )
-{
-  dap_events_t *ret = (dap_events_t *)calloc( 1, sizeof(dap_events_t) );
-
-  pthread_rwlock_init( &ret->sockets_rwlock, NULL );
-  pthread_rwlock_init( &ret->servers_rwlock, NULL );
-
-  return ret;
-}
-
-/**
- * @brief server_delete Delete event processor instance
- * @param sh Pointer to the server instance
- */
-void dap_events_delete( dap_events_t *a_events )
-{
-  dap_events_socket_t *cur, *tmp;
-
-  if ( a_events ) {
-
-    HASH_ITER( hh, a_events->sockets,cur, tmp ) {
-      dap_events_socket_delete( cur, false );
-    }
-
-    if ( a_events->_inheritor )
-      free( a_events->_inheritor );
-
-    pthread_rwlock_destroy( &a_events->servers_rwlock );
-    pthread_rwlock_destroy( &a_events->sockets_rwlock );
-
-    free( a_events );
-  }
-}
-
-void  dap_events_kill_socket( dap_events_socket_t *a_es )
-{
-  if ( !a_es ) {
-    log_it( L_ERROR, "dap_events_kill_socket( NULL )" );
-    return;
-  }
-
-  uint32_t tn = a_es->dap_worker->number_thread;
-
-  dap_worker_t *w = a_es->dap_worker;
-  dap_events_t *d_ev = w->events;
-
-  pthread_mutex_lock( &w->locker_on_count );
-  if ( a_es->kill_signal ) {
-    pthread_mutex_unlock( &w->locker_on_count );
-    return;
-  }
-
-  log_it( L_DEBUG, "KILL %u socket! [ thread %u ]", a_es->socket, tn );
-
-  a_es->kill_signal = true;
-  DL_LIST_ADD_NODE_HEAD( d_ev->to_kill_sockets, a_es, kprev, knext, w->event_to_kill_count );
-
-  pthread_mutex_unlock( &w->locker_on_count );
-}
-
-
-/**
- * @brief s_socket_info_all_check_activity
- * @param n_thread
- * @param sh
- */
-static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *d_ev, time_t cur_time )
-{
-  dap_events_socket_t *a_es, *tmp;
-
-  pthread_mutex_lock( &dap_worker->locker_on_count );
-  DL_FOREACH_SAFE( d_ev->dlsockets, a_es, tmp ) {
-
-    if ( !a_es->kill_signal && cur_time >= a_es->last_time_active + s_connection_timeout && !a_es->close_denied ) {
-
-      log_it( L_INFO, "Socket %u timeout, closing...", a_es->socket );
-
-      if ( epoll_ctl( dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 )
-        log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
-      else
-        log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", dap_worker->number_thread );
-
-      dap_worker->event_sockets_count --;
-      DL_DELETE( d_ev->dlsockets, a_es );
-      dap_events_socket_delete( a_es, false );
-    }
-  }
-  pthread_mutex_unlock( &dap_worker->locker_on_count );
-
-}
-
-/**
- * @brief thread_worker_function
- * @param arg
- * @return
- */
-static void *thread_worker_function( void *arg )
-{
-  dap_events_socket_t *cur, *tmp;
-  dap_worker_t *w = (dap_worker_t *)arg;
-  time_t next_time_timeout_check = time( NULL ) + s_connection_timeout / 2;
-  uint32_t tn = w->number_thread;
-
-  #ifndef _WIN32
-  #ifndef NO_POSIX_SHED
-  cpu_set_t mask;
-  CPU_ZERO( &mask );
-  CPU_SET( tn, &mask );
-
-  if ( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask) != 0 )
-  {
-    log_it(L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", *(int*)arg);
-    abort();
-  }
-  #endif
-  #else
-
-  if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) {
-    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
-    abort();
-  }
-  #endif
-
-  log_it(L_INFO, "Worker %d started, epoll fd %d", w->number_thread, w->epoll_fd);
-
-  struct epoll_event *events = &g_epoll_events[ DAP_MAX_EPOLL_EVENTS * tn ];
-
-//  memset( &ev, 0, sizeof(ev) );
-//  memset( &events, 0, sizeof(events) );
-
-  size_t total_sent; int bytes_sent;
-
-  while( 1 ) {
-
-    int selected_sockets = epoll_wait( w->epoll_fd, events, DAP_MAX_EPOLL_EVENTS, 1000 );
-    if ( selected_sockets == -1 )
-      break;
-
-    time_t cur_time = time( NULL );
-
-    for( int32_t n = 0; n < selected_sockets; n ++ ) {
-
-      cur = (dap_events_socket_t *)events[n].data.ptr;
-
-      if ( !cur ) {
-
-        log_it( L_ERROR,"dap_events_socket NULL" );
-        continue;
-      }
-
-      if ( events[n].events & EPOLLERR ) {
-        log_it( L_ERROR,"Socket error: %s",strerror(errno) );
-        cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-        cur->callbacks->error_callback( cur, NULL ); // Call callback to process error event
-      }
-
-      cur->last_time_active = cur_time;
-
-      if( events[n].events & EPOLLIN ) {
-
-        //log_it(DEBUG,"Comes connection in active read set");
-        if( cur->buf_in_size == sizeof(cur->buf_in) ) {
-           log_it( L_WARNING, "Buffer is full when there is smth to read. Its dropped!" );
-           cur->buf_in_size = 0;
-        }
-
-        int32_t bytes_read = recv( cur->socket, (char *)(cur->buf_in + cur->buf_in_size),
-                                    sizeof(cur->buf_in) - cur->buf_in_size, 0 );
-        if( bytes_read > 0 ) {
-          cur->buf_in_size += bytes_read;
-          //log_it(DEBUG, "Received %d bytes", bytes_read);
-          cur->callbacks->read_callback( cur, NULL ); // Call callback to process read event. At the end of callback buf_in_size should be zero if everything was read well
-        } 
-        else if( bytes_read < 0 ) {
-          log_it( L_ERROR,"Some error occured in recv() function: %s",strerror(errno) );
-          dap_events_socket_set_readable( cur, false );
-          cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-        } 
-        else if ( bytes_read == 0 ) {
-          log_it( L_INFO, "Client socket disconnected" );
-          dap_events_socket_set_readable( cur, false );
-          cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-        }
-      }
-
-      // Socket is ready to write
-      if( ( (events[n].events & EPOLLOUT) || (cur->flags & DAP_SOCK_READY_TO_WRITE) ) && !(cur->flags & DAP_SOCK_SIGNAL_CLOSE) ) {
-        ///log_it(DEBUG, "Main loop output: %u bytes to send",sa_cur->buf_out_size);
-        cur->callbacks->write_callback( cur, NULL ); // Call callback to process write event
-
-        if( cur->flags & DAP_SOCK_READY_TO_WRITE ) {
-
-          static const uint32_t buf_out_zero_count_max = 20;
-          cur->buf_out[cur->buf_out_size] = 0;
-
-          if( !cur->buf_out_size ) {
-
-            log_it(L_WARNING, "Output: nothing to send. Why we are in write socket set?");
-            cur->buf_out_zero_count ++;
-
-            if( cur->buf_out_zero_count > buf_out_zero_count_max ) { // How many time buf_out on write event could be empty
-              log_it( L_ERROR, "Output: nothing to send %u times, remove socket from the write set", buf_out_zero_count_max );
-              dap_events_socket_set_writable( cur, false );
-            }
-          }
-          else
-            cur->buf_out_zero_count = 0;
-        }
-        for ( total_sent = 0; total_sent < cur->buf_out_size; ) { // If after callback there is smth to send - we do it
-
-          bytes_sent = send( cur->socket, (char *)(cur->buf_out + total_sent),
-                             cur->buf_out_size - total_sent, MSG_DONTWAIT | MSG_NOSIGNAL );
-
-          if ( bytes_sent < 0 ) {
-            log_it(L_ERROR,"Some error occured in send() function");
-            cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-            break;
-          }
-          total_sent += bytes_sent;
-          //log_it(L_DEBUG, "Output: %u from %u bytes are sent ", total_sent,sa_cur->buf_out_size);
-        }
-        //log_it(L_DEBUG,"Output: sent %u bytes",total_sent);
-        cur->buf_out_size = 0;
-      }
-
-      if ( (cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !cur->close_denied ) {
-
-        pthread_mutex_lock( &w->locker_on_count );
-
-        if ( cur->kill_signal ) {
-          pthread_mutex_unlock( &w->locker_on_count );
-          continue;
-        }
-
-//        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-//        dap_server_kill_socket( dap_cur );
-//        continue;
-
-        log_it( L_INFO, "Got signal to close %s, sock %u [thread %u]", cur->hostaddr, cur->socket, tn );
-
-        dap_events_socket_remove_and_delete( cur, false );
-        pthread_mutex_unlock( &w->locker_on_count );
-      }
-    } // for
-
-    #ifndef  NO_TIMER
-    if ( cur_time >= next_time_timeout_check ) {
-
-      s_socket_all_check_activity( w, w->events, cur_time );
-      next_time_timeout_check = cur_time + s_connection_timeout / 2;
-    }
-    #endif
-
-    pthread_mutex_lock( &w->locker_on_count );
-    if ( !w->event_to_kill_count ) {
-
-      pthread_mutex_unlock( &w->locker_on_count );
-      continue;
-    }
-
-    cur = w->events->to_kill_sockets;
-
-    do {
-
-//      if ( cur->close_denied ) {
-//        cur = cur->knext;
-//        continue;
-//      }
-
-      log_it( L_INFO, "Kill %u socket .... [ thread %u ]", cur->socket, tn );
-
-      tmp = cur->knext;
-      DL_LIST_REMOVE_NODE( w->events->to_kill_sockets, cur, kprev, knext, w->event_to_kill_count );
-
-      dap_events_socket_remove_and_delete( cur, false );
-      cur = tmp;
-
-    } while ( cur );
-
-    log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, w->event_sockets_count, w->event_to_kill_count );
-    pthread_mutex_unlock( &w->locker_on_count );
-
-  } // while
-
-  return NULL;
-}
-
-/**
- * @brief dap_worker_get_min
- * @return
- */
-dap_worker_t *dap_worker_get_min( )
-{
-  return &s_workers[dap_worker_get_index_min()];
-}
-
-/**
- * @brief dap_worker_get_index_min
- * @return
- */
-uint32_t dap_worker_get_index_min( )
-{
-  uint32_t min = 0;
-  uint32_t i;
-
-  for( i = 1; i < s_threads_count; i++ ) {
-
-    if ( s_workers[min].event_sockets_count > s_workers[i].event_sockets_count )
-      min = i;
-  }
-
-  return min;
-}
-
-/**
- * @brief dap_worker_print_all
- */
-void dap_worker_print_all( )
-{
-  uint32_t i;
-
-  for( i = 0; i < s_threads_count; i ++ ) {
-
-    log_it( L_INFO, "Worker: %d, count open connections: %d",
-            s_workers[i].number_thread, s_workers[i].event_sockets_count );
-  }
-}
-
-/**
- * @brief sa_server_loop Main server loop
- * @param sh Server instance
- * @return Zero if ok others if not
- */
-int dap_events_start( dap_events_t *a_events )
-{
-  for( uint32_t i = 0; i < s_threads_count; i++) {
-
-    s_workers[i].epoll_fd = epoll_create( DAP_MAX_EPOLL_EVENTS );
-    if ( (intptr_t)s_workers[i].epoll_fd == -1 ) {
-      log_it(L_CRITICAL, "Error create epoll fd");
-      return -1;
-    }
-
-    s_workers[i].event_to_kill_count = 0;
-    s_workers[i].event_sockets_count = 0;
-    s_workers[i].number_thread = i;
-    s_workers[i].events = a_events;
-
-    pthread_mutex_init( &s_workers[i].locker_on_count, NULL );
-    pthread_create( &s_threads[i].tid, NULL, thread_worker_function, &s_workers[i] );
-  }
-
-  return 0;
-}
-
-/**
- * @brief dap_events_wait
- * @param sh
- * @return
- */
-int dap_events_wait( dap_events_t *sh )
-{
-  (void) sh;
-
-  for( uint32_t i = 0; i < s_threads_count; i ++ ) {
-    void *ret;
-    pthread_join( s_threads[i].tid, &ret );
-  }
-
-  return 0;
-}
-
-
-
-/**
- * @brief dap_worker_add_events_socket
- * @param a_worker
- * @param a_events_socket
- */
-void dap_worker_add_events_socket( dap_events_socket_t *a_es)
-{
-//  struct epoll_event ev = {0};
-  dap_worker_t *l_worker = dap_worker_get_min( );
-
-  a_es->dap_worker = l_worker;
-  a_es->events = a_es->dap_worker->events;
-}
-
-/**
- * @brief dap_events_socket_delete
- * @param a_es
- */
-void dap_events_socket_remove_and_delete( dap_events_socket_t *a_es,  bool preserve_inheritor )
-{
-  if ( epoll_ctl( a_es->dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 )
-     log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
-  else
-     log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", a_es->dap_worker->number_thread );
-
-  DL_DELETE( a_es->events->dlsockets, a_es );
-  a_es->dap_worker->event_sockets_count --;
-
-  dap_events_socket_delete( a_es, preserve_inheritor );
-}
-
-/**
- * @brief dap_events__thread_wake_up
- * @param th
- */
-void dap_events_thread_wake_up( dap_thread_t *th )
-{
-  (void) th;
- //pthread_kill(th->tid,SIGUSR1);
-}
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#define __USE_GNU
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#ifndef _WIN32
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <sys/epoll.h>
+
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+
+#if 1
+#include <sys/timerfd.h>
+#elif defined(DAP_OS_ANDROID)
+#define NO_POSIX_SHED
+#define NO_TIMER
+#endif
+
+#else
+
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+
+//#define NO_TIMER
+
+#endif
+
+#include <utlist.h>
+#include <sched.h>
+
+#include "dap_common.h"
+#include "dap_events.h"
+
+#define DAP_MAX_EPOLL_EVENTS    8192
+
+//typedef struct open_connection_info_s {
+//    dap_events_socket_t *es;
+//    struct open_connection_info *prev;
+//    struct open_connection_info *next;
+//} dap_events_socket_info_t;
+
+//dap_events_socket_info_t **s_dap_events_sockets;
+
+static uint32_t s_threads_count = 1;
+static size_t   s_connection_timeout = 600;
+static struct epoll_event *g_epoll_events = NULL;
+
+dap_worker_t *s_workers = NULL;
+dap_thread_t *s_threads = NULL;
+
+#define LOG_TAG "dap_events"
+
+uint32_t s_get_cpu_count( )
+{
+#ifdef _WIN32
+  SYSTEM_INFO si;
+
+  GetSystemInfo( &si );
+  return si.dwNumberOfProcessors;
+#else
+#ifndef NO_POSIX_SHED
+  cpu_set_t cs;
+  CPU_ZERO( &cs );
+  sched_getaffinity( 0, sizeof(cs), &cs );
+
+  uint32_t count = 0;
+  for ( int i = 0; i < 32; i++ ){
+    if ( CPU_ISSET(i, &cs) )
+    count ++;
+  }
+  return count;
+#else
+  return 1;
+#endif
+#endif
+}
+
+/**
+ * @brief sa_server_init Init server module
+ * @arg a_threads_count  number of events processor workers in parallel threads
+ * @return Zero if ok others if no
+ */
+int32_t dap_events_init( uint32_t a_threads_count, size_t conn_timeout )
+{
+  s_threads_count = a_threads_count ? a_threads_count : s_get_cpu_count( );
+
+  if ( conn_timeout )
+    s_connection_timeout = conn_timeout;
+
+  s_workers = (dap_worker_t *) calloc( 1, sizeof(dap_worker_t) * s_threads_count );
+  s_threads = (dap_thread_t *) calloc( 1, sizeof(dap_thread_t) * s_threads_count );
+  if ( !s_workers || !s_threads )
+    goto err;
+
+  g_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * DAP_MAX_EPOLL_EVENTS * s_threads_count );
+  if ( !g_epoll_events )
+    goto err;
+
+  if ( dap_events_socket_init() != 0 ) {
+
+    log_it( L_CRITICAL, "Can't init client submodule dap_events_socket_init( )" );
+    goto err;
+  }
+
+  log_it( L_NOTICE, "Initialized socket server module" );
+
+  #ifndef _WIN32
+    signal( SIGPIPE, SIG_IGN );
+  #endif
+  return 0;
+
+err:
+  dap_events_deinit( );
+  return -1;
+}
+
+/**
+ * @brief sa_server_deinit Deinit server module
+ */
+void dap_events_deinit( )
+{
+  dap_events_socket_deinit( );
+
+  if ( g_epoll_events )
+    free( g_epoll_events );
+
+  if ( s_threads )
+    free( s_threads );
+
+  if ( s_workers )
+    free( s_workers );
+}
+
+/**
+ * @brief server_new Creates new empty instance of server_t
+ * @return New instance
+ */
+dap_events_t * dap_events_new( )
+{
+  dap_events_t *ret = (dap_events_t *)calloc( 1, sizeof(dap_events_t) );
+
+  pthread_rwlock_init( &ret->sockets_rwlock, NULL );
+  pthread_rwlock_init( &ret->servers_rwlock, NULL );
+
+  return ret;
+}
+
+/**
+ * @brief server_delete Delete event processor instance
+ * @param sh Pointer to the server instance
+ */
+void dap_events_delete( dap_events_t *a_events )
+{
+  dap_events_socket_t *cur, *tmp;
+
+  if ( a_events ) {
+
+    HASH_ITER( hh, a_events->sockets,cur, tmp ) {
+      dap_events_socket_delete( cur, false );
+    }
+
+    if ( a_events->_inheritor )
+      free( a_events->_inheritor );
+
+    pthread_rwlock_destroy( &a_events->servers_rwlock );
+    pthread_rwlock_destroy( &a_events->sockets_rwlock );
+
+    free( a_events );
+  }
+}
+
+void  dap_events_kill_socket( dap_events_socket_t *a_es )
+{
+  if ( !a_es ) {
+    log_it( L_ERROR, "dap_events_kill_socket( NULL )" );
+    return;
+  }
+
+  uint32_t tn = a_es->dap_worker->number_thread;
+
+  dap_worker_t *w = a_es->dap_worker;
+  dap_events_t *d_ev = w->events;
+
+  pthread_mutex_lock( &w->locker_on_count );
+  if ( a_es->kill_signal ) {
+    pthread_mutex_unlock( &w->locker_on_count );
+    return;
+  }
+
+  log_it( L_DEBUG, "KILL %u socket! [ thread %u ]", a_es->socket, tn );
+
+  a_es->kill_signal = true;
+  DL_LIST_ADD_NODE_HEAD( d_ev->to_kill_sockets, a_es, kprev, knext, w->event_to_kill_count );
+
+  pthread_mutex_unlock( &w->locker_on_count );
+}
+
+
+/**
+ * @brief s_socket_info_all_check_activity
+ * @param n_thread
+ * @param sh
+ */
+static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *d_ev, time_t cur_time )
+{
+  dap_events_socket_t *a_es, *tmp;
+
+  pthread_mutex_lock( &dap_worker->locker_on_count );
+  DL_FOREACH_SAFE( d_ev->dlsockets, a_es, tmp ) {
+
+    if ( !a_es->kill_signal && cur_time >= a_es->last_time_active + s_connection_timeout && !a_es->no_close ) {
+
+      log_it( L_INFO, "Socket %u timeout, closing...", a_es->socket );
+
+      if ( epoll_ctl( dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 )
+        log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
+      else
+        log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", dap_worker->number_thread );
+
+      dap_worker->event_sockets_count --;
+      DL_DELETE( d_ev->dlsockets, a_es );
+      dap_events_socket_delete( a_es, false );
+    }
+  }
+  pthread_mutex_unlock( &dap_worker->locker_on_count );
+
+}
+
+/**
+ * @brief thread_worker_function
+ * @param arg
+ * @return
+ */
+static void *thread_worker_function( void *arg )
+{
+  dap_events_socket_t *cur, *tmp;
+  dap_worker_t *w = (dap_worker_t *)arg;
+  time_t next_time_timeout_check = time( NULL ) + s_connection_timeout / 2;
+  uint32_t tn = w->number_thread;
+
+  #ifndef _WIN32
+  #ifndef NO_POSIX_SHED
+  cpu_set_t mask;
+  CPU_ZERO( &mask );
+  CPU_SET( tn, &mask );
+
+  if ( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask) != 0 )
+  {
+    log_it(L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", *(int*)arg);
+    abort();
+  }
+  #endif
+  #else
+
+  if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) {
+    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
+    abort();
+  }
+  #endif
+
+  log_it(L_INFO, "Worker %d started, epoll fd %d", w->number_thread, w->epoll_fd);
+
+  struct epoll_event *events = &g_epoll_events[ DAP_MAX_EPOLL_EVENTS * tn ];
+
+//  memset( &ev, 0, sizeof(ev) );
+//  memset( &events, 0, sizeof(events) );
+
+  size_t total_sent; int bytes_sent;
+
+  while( 1 ) {
+
+    int selected_sockets = epoll_wait( w->epoll_fd, events, DAP_MAX_EPOLL_EVENTS, 1000 );
+
+    if ( selected_sockets == -1 ) {
+      if ( errno == EINTR )
+        continue;
+      break;
+    }
+
+    time_t cur_time = time( NULL );
+
+    for( int32_t n = 0; n < selected_sockets; n ++ ) {
+
+      cur = (dap_events_socket_t *)events[n].data.ptr;
+
+      if ( !cur ) {
+
+        log_it( L_ERROR,"dap_events_socket NULL" );
+        continue;
+      }
+
+      if ( events[n].events & EPOLLERR ) {
+        log_it( L_ERROR,"Socket error: %s",strerror(errno) );
+        cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+        cur->callbacks->error_callback( cur, NULL ); // Call callback to process error event
+      }
+
+      cur->last_time_active = cur_time;
+
+      if( events[n].events & EPOLLIN ) {
+
+        //log_it(DEBUG,"Comes connection in active read set");
+        if( cur->buf_in_size == sizeof(cur->buf_in) ) {
+           log_it( L_WARNING, "Buffer is full when there is smth to read. Its dropped!" );
+           cur->buf_in_size = 0;
+        }
+
+        int32_t bytes_read = recv( cur->socket, (char *)(cur->buf_in + cur->buf_in_size),
+                                    sizeof(cur->buf_in) - cur->buf_in_size, 0 );
+        if( bytes_read > 0 ) {
+          cur->buf_in_size += bytes_read;
+          //log_it(DEBUG, "Received %d bytes", bytes_read);
+          cur->callbacks->read_callback( cur, NULL ); // Call callback to process read event. At the end of callback buf_in_size should be zero if everything was read well
+        } 
+        else if( bytes_read < 0 ) {
+          log_it( L_ERROR,"Some error occured in recv() function: %s",strerror(errno) );
+          dap_events_socket_set_readable( cur, false );
+          cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+        } 
+        else if ( bytes_read == 0 ) {
+          log_it( L_INFO, "Client socket disconnected" );
+          dap_events_socket_set_readable( cur, false );
+          cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+        }
+      }
+
+      // Socket is ready to write
+      if( ( (events[n].events & EPOLLOUT) || (cur->flags & DAP_SOCK_READY_TO_WRITE) ) && !(cur->flags & DAP_SOCK_SIGNAL_CLOSE) ) {
+        ///log_it(DEBUG, "Main loop output: %u bytes to send",sa_cur->buf_out_size);
+        cur->callbacks->write_callback( cur, NULL ); // Call callback to process write event
+
+        if( cur->flags & DAP_SOCK_READY_TO_WRITE ) {
+
+          static const uint32_t buf_out_zero_count_max = 20;
+          cur->buf_out[cur->buf_out_size] = 0;
+
+          if( !cur->buf_out_size ) {
+
+            log_it(L_WARNING, "Output: nothing to send. Why we are in write socket set?");
+            cur->buf_out_zero_count ++;
+
+            if( cur->buf_out_zero_count > buf_out_zero_count_max ) { // How many time buf_out on write event could be empty
+              log_it( L_ERROR, "Output: nothing to send %u times, remove socket from the write set", buf_out_zero_count_max );
+              dap_events_socket_set_writable( cur, false );
+            }
+          }
+          else
+            cur->buf_out_zero_count = 0;
+        }
+        for ( total_sent = 0; total_sent < cur->buf_out_size; ) { // If after callback there is smth to send - we do it
+
+          bytes_sent = send( cur->socket, (char *)(cur->buf_out + total_sent),
+                             cur->buf_out_size - total_sent, MSG_DONTWAIT | MSG_NOSIGNAL );
+
+          if ( bytes_sent < 0 ) {
+            log_it(L_ERROR,"Some error occured in send() function");
+            cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+            break;
+          }
+          total_sent += bytes_sent;
+          //log_it(L_DEBUG, "Output: %u from %u bytes are sent ", total_sent,sa_cur->buf_out_size);
+        }
+        //log_it(L_DEBUG,"Output: sent %u bytes",total_sent);
+        cur->buf_out_size = 0;
+      }
+
+      if ( (cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !cur->no_close ) {
+
+        pthread_mutex_lock( &w->locker_on_count );
+
+        if ( cur->kill_signal ) {
+          pthread_mutex_unlock( &w->locker_on_count );
+          continue;
+        }
+
+//        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+//        dap_server_kill_socket( dap_cur );
+//        continue;
+
+        log_it( L_INFO, "Got signal to close %s, sock %u [thread %u]", cur->hostaddr, cur->socket, tn );
+
+        dap_events_socket_remove_and_delete( cur, false );
+        pthread_mutex_unlock( &w->locker_on_count );
+      }
+    } // for
+
+    #ifndef  NO_TIMER
+    if ( cur_time >= next_time_timeout_check ) {
+
+      s_socket_all_check_activity( w, w->events, cur_time );
+      next_time_timeout_check = cur_time + s_connection_timeout / 2;
+    }
+    #endif
+
+    pthread_mutex_lock( &w->locker_on_count );
+    if ( !w->event_to_kill_count ) {
+
+      pthread_mutex_unlock( &w->locker_on_count );
+      continue;
+    }
+
+    cur = w->events->to_kill_sockets;
+
+    do {
+
+//      if ( cur->no_close ) {
+//        cur = cur->knext;
+//        continue;
+//      }
+
+      log_it( L_INFO, "Kill %u socket .... [ thread %u ]", cur->socket, tn );
+
+      tmp = cur->knext;
+      DL_LIST_REMOVE_NODE( w->events->to_kill_sockets, cur, kprev, knext, w->event_to_kill_count );
+
+      dap_events_socket_remove_and_delete( cur, false );
+      cur = tmp;
+
+    } while ( cur );
+
+    log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, w->event_sockets_count, w->event_to_kill_count );
+    pthread_mutex_unlock( &w->locker_on_count );
+
+  } // while
+
+  return NULL;
+}
+
+/**
+ * @brief dap_worker_get_min
+ * @return
+ */
+dap_worker_t *dap_worker_get_min( )
+{
+  return &s_workers[dap_worker_get_index_min()];
+}
+
+/**
+ * @brief dap_worker_get_index_min
+ * @return
+ */
+uint32_t dap_worker_get_index_min( )
+{
+  uint32_t min = 0;
+  uint32_t i;
+
+  for( i = 1; i < s_threads_count; i++ ) {
+
+    if ( s_workers[min].event_sockets_count > s_workers[i].event_sockets_count )
+      min = i;
+  }
+
+  return min;
+}
+
+/**
+ * @brief dap_worker_print_all
+ */
+void dap_worker_print_all( )
+{
+  uint32_t i;
+
+  for( i = 0; i < s_threads_count; i ++ ) {
+
+    log_it( L_INFO, "Worker: %d, count open connections: %d",
+            s_workers[i].number_thread, s_workers[i].event_sockets_count );
+  }
+}
+
+/**
+ * @brief sa_server_loop Main server loop
+ * @param sh Server instance
+ * @return Zero if ok others if not
+ */
+int dap_events_start( dap_events_t *a_events )
+{
+  for( uint32_t i = 0; i < s_threads_count; i++) {
+
+    s_workers[i].epoll_fd = epoll_create( DAP_MAX_EPOLL_EVENTS );
+    if ( (intptr_t)s_workers[i].epoll_fd == -1 ) {
+      log_it(L_CRITICAL, "Error create epoll fd");
+      return -1;
+    }
+
+    s_workers[i].event_to_kill_count = 0;
+    s_workers[i].event_sockets_count = 0;
+    s_workers[i].number_thread = i;
+    s_workers[i].events = a_events;
+
+    pthread_mutex_init( &s_workers[i].locker_on_count, NULL );
+    pthread_create( &s_threads[i].tid, NULL, thread_worker_function, &s_workers[i] );
+  }
+
+  return 0;
+}
+
+/**
+ * @brief dap_events_wait
+ * @param sh
+ * @return
+ */
+int dap_events_wait( dap_events_t *sh )
+{
+  (void) sh;
+
+  for( uint32_t i = 0; i < s_threads_count; i ++ ) {
+    void *ret;
+    pthread_join( s_threads[i].tid, &ret );
+  }
+
+  return 0;
+}
+
+
+
+/**
+ * @brief dap_worker_add_events_socket
+ * @param a_worker
+ * @param a_events_socket
+ */
+void dap_worker_add_events_socket( dap_events_socket_t *a_es)
+{
+//  struct epoll_event ev = {0};
+  dap_worker_t *l_worker = dap_worker_get_min( );
+
+  a_es->dap_worker = l_worker;
+  a_es->events = a_es->dap_worker->events;
+}
+
+/**
+ * @brief dap_events_socket_delete
+ * @param a_es
+ */
+void dap_events_socket_remove_and_delete( dap_events_socket_t *a_es,  bool preserve_inheritor )
+{
+  if ( epoll_ctl( a_es->dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &a_es->ev) == -1 )
+     log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
+  else
+     log_it( L_DEBUG,"Removed epoll's event from dap_worker #%u", a_es->dap_worker->number_thread );
+
+  DL_DELETE( a_es->events->dlsockets, a_es );
+  a_es->dap_worker->event_sockets_count --;
+
+  dap_events_socket_delete( a_es, preserve_inheritor );
+}
+
+/**
+ * @brief dap_events__thread_wake_up
+ * @param th
+ */
+void dap_events_thread_wake_up( dap_thread_t *th )
+{
+  (void) th;
+ //pthread_kill(th->tid,SIGUSR1);
+}
diff --git a/src/dap_events_socket.c b/src/dap_events_socket.c
index c5c06040aa28b24511afb37633adac990f743fb6..c90b4139ab69a80d09fa14044e131e168f183d48 100755
--- a/src/dap_events_socket.c
+++ b/src/dap_events_socket.c
@@ -1,367 +1,367 @@
-/*
- * Authors:
- * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2019
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <assert.h>
-
-#ifndef _WIN32
-#include <sys/epoll.h>
-#include <unistd.h>
-#include <fcntl.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include "dap_common.h"
-#include "dap_events.h"
-
-#include "dap_events_socket.h"
-
-#define LOG_TAG "dap_events_socket"
-
-/**
- * @brief dap_events_socket_init Init clients module
- * @return Zero if ok others if no
- */
-int dap_events_socket_init( )
-{
-    log_it(L_NOTICE,"Initialized socket client module");
-    return 0;
-}
-
-/**
- * @brief dap_events_socket_deinit Deinit clients module
- */
-void dap_events_socket_deinit( )
-{
-
-}
-
-
-/**
- * @brief dap_events_socket_wrap
- * @param a_events
- * @param w
- * @param s
- * @param a_callbacks
- * @return
- */
-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 )
-{
-//  assert(a_events);
-  assert(a_callbacks);
-
-  log_it( L_DEBUG,"Dap event socket wrapped around %d sock a_events = %X", a_sock, a_events );
-
-  dap_events_socket_t *ret = DAP_NEW_Z( dap_events_socket_t );
-
-  ret->socket = a_sock;
-  ret->events = a_events;
-  ret->callbacks = a_callbacks;
-  ret->flags = DAP_SOCK_READY_TO_READ;
-  ret->close_denied = true;
-
-  log_it( L_DEBUG,"Dap event socket wrapped around %d sock a_events = %X", a_sock, a_events );
-
-  return ret;
-}
-
-/**
- * @brief dap_events_socket_create_after
- * @param a_es
- */
-void dap_events_socket_create_after( dap_events_socket_t *a_es )
-{
-  if ( a_es->callbacks->new_callback )
-    a_es->callbacks->new_callback( a_es, NULL ); // Init internal structure
-
-  a_es->last_time_active = a_es->last_ping_request = time( NULL );
-
-  dap_worker_add_events_socket( a_es );
-
-  pthread_mutex_lock( &a_es->dap_worker->locker_on_count );
-
-  a_es->dap_worker->event_sockets_count ++;
-  DL_APPEND( a_es->events->dlsockets, a_es );
-
-  pthread_rwlock_wrlock( &a_es->events->sockets_rwlock );
-  HASH_ADD_INT( a_es->events->sockets, socket, a_es );
-  pthread_rwlock_unlock( &a_es->events->sockets_rwlock );
-
-  a_es->ev.events = EPOLLIN | EPOLLERR | EPOLLOUT;
-  a_es->ev.data.ptr = a_es;
-
-  if ( epoll_ctl( a_es->dap_worker->epoll_fd, EPOLL_CTL_ADD, a_es->socket, &a_es->ev ) == 1 )
-    log_it( L_CRITICAL, "Can't add event socket's handler to epoll_fd" );
-
-  pthread_mutex_unlock( &a_es->dap_worker->locker_on_count );
-}
-
-/**
- * @brief dap_events_socket_wrap
- * @param a_events
- * @param w
- * @param s
- * @param a_callbacks
- * @return
- */
-dap_events_socket_t * dap_events_socket_wrap2( dap_server_t *a_server, struct dap_events *a_events,
-                                            int a_sock, dap_events_socket_callbacks_t *a_callbacks )
-{
-  assert( a_events );
-  assert( a_callbacks );
-  assert( a_server );
-
-  log_it( L_DEBUG,"Sap event socket wrapped around %d sock", a_sock );
-  dap_events_socket_t * ret = DAP_NEW_Z( dap_events_socket_t );
-
-  ret->socket = a_sock;
-  ret->events = a_events;
-  ret->callbacks = a_callbacks;
-
-  ret->flags = DAP_SOCK_READY_TO_READ;
-  ret->is_pingable = true;
-  ret->last_time_active = ret->last_ping_request = time( NULL );
-
-  pthread_rwlock_wrlock( &a_events->sockets_rwlock );
-  HASH_ADD_INT( a_events->sockets, socket, ret );
-  pthread_rwlock_unlock( &a_events->sockets_rwlock );
-
-  if( a_callbacks->new_callback )
-    a_callbacks->new_callback( ret, NULL ); // Init internal structure
-
-  return ret;
-}
-
-/**
- * @brief dap_events_socket_find
- * @param sock
- * @param sh
- * @return
- */
-dap_events_socket_t *dap_events_socket_find( int sock, struct dap_events *a_events )
-{
-  dap_events_socket_t *ret = NULL;
-
-  pthread_rwlock_rdlock( &a_events->sockets_rwlock );
-  HASH_FIND_INT( a_events->sockets, &sock, ret );
-  pthread_rwlock_unlock( &a_events->sockets_rwlock );
-
-  return ret;
-}
-
-/**
- * @brief dap_events_socket_ready_to_read
- * @param sc
- * @param isReady
- */
-void dap_events_socket_set_readable( dap_events_socket_t *sc, bool is_ready )
-{
-  if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) )
-    return;
-
-  sc->ev.events = EPOLLERR;
-
-  if ( is_ready )
-    sc->flags |= DAP_SOCK_READY_TO_READ;
-  else
-    sc->flags ^= DAP_SOCK_READY_TO_READ;
-
-  int events = EPOLLERR;
-
-  if( sc->flags & DAP_SOCK_READY_TO_READ )
-    events |= EPOLLIN;
-
-  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
-    events |= EPOLLOUT;
-
-  sc->ev.events = events;
-
-  if ( epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 )
-    log_it( L_ERROR,"Can't update read client socket state in the epoll_fd" );
-  else
-    dap_events_thread_wake_up( &sc->events->proc_thread );
-}
-
-/**
- * @brief dap_events_socket_ready_to_write
- * @param sc
- * @param isReady
- */
-void dap_events_socket_set_writable( dap_events_socket_t *sc, bool is_ready )
-{
-  if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) )
-    return;
-
-  if ( is_ready )
-    sc->flags |= DAP_SOCK_READY_TO_WRITE;
-  else
-    sc->flags ^= DAP_SOCK_READY_TO_WRITE;
-
-  int events = EPOLLERR;
-
-  if( sc->flags & DAP_SOCK_READY_TO_READ )
-    events |= EPOLLIN;
-
-  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
-    events |= EPOLLOUT;
-
-  sc->ev.events = events;
-
-  if ( epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 )
-    log_it(L_ERROR,"Can't update write client socket state in the epoll_fd");
-  else
-    dap_events_thread_wake_up( &sc->events->proc_thread );
-}
-
-
-/**
- * @brief dap_events_socket_remove Removes the client from the list
- * @param sc Connection instance
- */
-void dap_events_socket_delete( dap_events_socket_t *a_es, bool preserve_inheritor )
-{
-  if ( !a_es ) return;
-
-  log_it( L_DEBUG, "es is going to be removed from the lists and free the memory (0x%016X)", a_es );
-
-  pthread_rwlock_wrlock( &a_es->events->sockets_rwlock );
-  HASH_DEL( a_es->events->sockets, a_es );
-  pthread_rwlock_unlock( &a_es->events->sockets_rwlock );
-
-  log_it( L_DEBUG, "dap_events_socket wrapped around %d socket is removed", a_es->socket );
-
-  if( a_es->callbacks->delete_callback )
-    a_es->callbacks->delete_callback( a_es, NULL ); // Init internal structure
-
-  if ( a_es->_inheritor && !preserve_inheritor )
-    free( a_es->_inheritor );
-
-  if ( a_es->socket )
-    close( a_es->socket );
-
-  free( a_es );
-}
-
-/**
- * @brief dap_events_socket_write Write data to the client
- * @param sc Conn instance
- * @param data Pointer to data
- * @param data_size Size of data to write
- * @return Number of bytes that were placed into the buffer
- */
-size_t dap_events_socket_write(dap_events_socket_t *sc, const void * data, size_t data_size)
-{
-    log_it(L_DEBUG,"dap_events_socket_write %u sock data %X size %u", sc->socket, data, data_size );
-
-     data_size = ((sc->buf_out_size+data_size)<(sizeof(sc->buf_out)))?data_size:(sizeof(sc->buf_out)-sc->buf_out_size );
-     memcpy(sc->buf_out+sc->buf_out_size,data,data_size);
-     sc->buf_out_size+=data_size;
-     return data_size;
-}
-
-/**
- * @brief dap_events_socket_write_f Write formatted text to the client
- * @param sc Conn instance
- * @param format Format
- * @return Number of bytes that were placed into the buffer
- */
-size_t dap_events_socket_write_f(dap_events_socket_t *sc, const char * format,...)
-{
-    log_it(L_DEBUG,"dap_events_socket_write_f %u sock", sc->socket );
-
-    size_t max_data_size = sizeof(sc->buf_out)-sc->buf_out_size;
-    va_list ap;
-    va_start(ap,format);
-    int ret=vsnprintf((char*) sc->buf_out+sc->buf_out_size,max_data_size,format,ap);
-    va_end(ap);
-    if(ret>0){
-        sc->buf_out_size+=ret;
-        return ret;
-    }else{
-        log_it(L_ERROR,"Can't write out formatted data '%s'",format);
-        return 0;
-    }
-}
-
-/**
- * @brief dap_events_socket_read Read data from input buffer
- * @param sc Conn instasnce
- * @param data Pointer to memory where to store the data
- * @param data_size Size of data to read
- * @return Actual bytes number that were read
- */
-size_t dap_events_socket_read(dap_events_socket_t *sc, void *data, size_t data_size)
-{
-    log_it(L_DEBUG,"dap_events_socket_read %u sock data %X size %u", sc->socket, data, data_size );
-
-    if(data_size<sc->buf_in_size){
-        memcpy(data,sc->buf_in,data_size);
-        memmove(data,sc->buf_in+data_size,sc->buf_in_size-data_size);
-    }else{
-        if(data_size>sc->buf_in_size)
-            data_size=sc->buf_in_size;
-        memcpy(data,sc->buf_in,data_size);
-    }
-    sc->buf_in_size-=data_size;
-    return data_size;
-}
-
-
-/**
- * @brief dap_events_socket_shrink_client_buf_in Shrink input buffer (shift it left)
- * @param cl Client instance
- * @param shrink_size Size on wich we shrink the buffer with shifting it left
- */
-void dap_events_socket_shrink_buf_in(dap_events_socket_t * cl, size_t shrink_size)
-{
-    if((shrink_size==0)||(cl->buf_in_size==0) ){
-        return;
-    }else if(cl->buf_in_size>shrink_size){
-        size_t buf_size=cl->buf_in_size-shrink_size;
-        void * buf = malloc(buf_size);
-        memcpy(buf,cl->buf_in+ shrink_size,buf_size );
-        memcpy(cl->buf_in,buf,buf_size);
-        cl->buf_in_size=buf_size;
-        if (buf)
-            free(buf);
-    }else{
-        //log_it(WARNING,"Shrinking size of input buffer on amount bigger than actual buffer's size");
-        cl->buf_in_size=0;
-    }
-
-}
+/*
+ * Authors:
+ * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2019
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <assert.h>
+
+#ifndef _WIN32
+#include <sys/epoll.h>
+#include <unistd.h>
+#include <fcntl.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include "dap_common.h"
+#include "dap_events.h"
+
+#include "dap_events_socket.h"
+
+#define LOG_TAG "dap_events_socket"
+
+/**
+ * @brief dap_events_socket_init Init clients module
+ * @return Zero if ok others if no
+ */
+int dap_events_socket_init( )
+{
+    log_it(L_NOTICE,"Initialized socket client module");
+    return 0;
+}
+
+/**
+ * @brief dap_events_socket_deinit Deinit clients module
+ */
+void dap_events_socket_deinit( )
+{
+
+}
+
+
+/**
+ * @brief dap_events_socket_wrap
+ * @param a_events
+ * @param w
+ * @param s
+ * @param a_callbacks
+ * @return
+ */
+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 )
+{
+//  assert(a_events);
+  assert(a_callbacks);
+
+  log_it( L_DEBUG,"Dap event socket wrapped around %d sock a_events = %X", a_sock, a_events );
+
+  dap_events_socket_t *ret = DAP_NEW_Z( dap_events_socket_t );
+
+  ret->socket = a_sock;
+  ret->events = a_events;
+  ret->callbacks = a_callbacks;
+  ret->flags = DAP_SOCK_READY_TO_READ;
+  ret->no_close = true;
+
+  log_it( L_DEBUG,"Dap event socket wrapped around %d sock a_events = %X", a_sock, a_events );
+
+  return ret;
+}
+
+/**
+ * @brief dap_events_socket_create_after
+ * @param a_es
+ */
+void dap_events_socket_create_after( dap_events_socket_t *a_es )
+{
+  if ( a_es->callbacks->new_callback )
+    a_es->callbacks->new_callback( a_es, NULL ); // Init internal structure
+
+  a_es->last_time_active = a_es->last_ping_request = time( NULL );
+
+  dap_worker_add_events_socket( a_es );
+
+  pthread_mutex_lock( &a_es->dap_worker->locker_on_count );
+
+  a_es->dap_worker->event_sockets_count ++;
+  DL_APPEND( a_es->events->dlsockets, a_es );
+
+  pthread_rwlock_wrlock( &a_es->events->sockets_rwlock );
+  HASH_ADD_INT( a_es->events->sockets, socket, a_es );
+  pthread_rwlock_unlock( &a_es->events->sockets_rwlock );
+
+  a_es->ev.events = EPOLLIN | EPOLLERR | EPOLLOUT;
+  a_es->ev.data.ptr = a_es;
+
+  if ( epoll_ctl( a_es->dap_worker->epoll_fd, EPOLL_CTL_ADD, a_es->socket, &a_es->ev ) == 1 )
+    log_it( L_CRITICAL, "Can't add event socket's handler to epoll_fd" );
+
+  pthread_mutex_unlock( &a_es->dap_worker->locker_on_count );
+}
+
+/**
+ * @brief dap_events_socket_wrap
+ * @param a_events
+ * @param w
+ * @param s
+ * @param a_callbacks
+ * @return
+ */
+dap_events_socket_t * dap_events_socket_wrap2( dap_server_t *a_server, struct dap_events *a_events,
+                                            int a_sock, dap_events_socket_callbacks_t *a_callbacks )
+{
+  assert( a_events );
+  assert( a_callbacks );
+  assert( a_server );
+
+  log_it( L_DEBUG,"Sap event socket wrapped around %d sock", a_sock );
+  dap_events_socket_t * ret = DAP_NEW_Z( dap_events_socket_t );
+
+  ret->socket = a_sock;
+  ret->events = a_events;
+  ret->callbacks = a_callbacks;
+
+  ret->flags = DAP_SOCK_READY_TO_READ;
+  ret->is_pingable = true;
+  ret->last_time_active = ret->last_ping_request = time( NULL );
+
+  pthread_rwlock_wrlock( &a_events->sockets_rwlock );
+  HASH_ADD_INT( a_events->sockets, socket, ret );
+  pthread_rwlock_unlock( &a_events->sockets_rwlock );
+
+  if( a_callbacks->new_callback )
+    a_callbacks->new_callback( ret, NULL ); // Init internal structure
+
+  return ret;
+}
+
+/**
+ * @brief dap_events_socket_find
+ * @param sock
+ * @param sh
+ * @return
+ */
+dap_events_socket_t *dap_events_socket_find( int sock, struct dap_events *a_events )
+{
+  dap_events_socket_t *ret = NULL;
+
+  pthread_rwlock_rdlock( &a_events->sockets_rwlock );
+  HASH_FIND_INT( a_events->sockets, &sock, ret );
+  pthread_rwlock_unlock( &a_events->sockets_rwlock );
+
+  return ret;
+}
+
+/**
+ * @brief dap_events_socket_ready_to_read
+ * @param sc
+ * @param isReady
+ */
+void dap_events_socket_set_readable( dap_events_socket_t *sc, bool is_ready )
+{
+  if( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_READ) )
+    return;
+
+  sc->ev.events = EPOLLERR;
+
+  if ( is_ready )
+    sc->flags |= DAP_SOCK_READY_TO_READ;
+  else
+    sc->flags ^= DAP_SOCK_READY_TO_READ;
+
+  int events = EPOLLERR;
+
+  if( sc->flags & DAP_SOCK_READY_TO_READ )
+    events |= EPOLLIN;
+
+  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
+    events |= EPOLLOUT;
+
+  sc->ev.events = events;
+
+  if ( epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 )
+    log_it( L_ERROR,"Can't update read client socket state in the epoll_fd" );
+  else
+    dap_events_thread_wake_up( &sc->events->proc_thread );
+}
+
+/**
+ * @brief dap_events_socket_ready_to_write
+ * @param sc
+ * @param isReady
+ */
+void dap_events_socket_set_writable( dap_events_socket_t *sc, bool is_ready )
+{
+  if ( is_ready == (bool)(sc->flags & DAP_SOCK_READY_TO_WRITE) )
+    return;
+
+  if ( is_ready )
+    sc->flags |= DAP_SOCK_READY_TO_WRITE;
+  else
+    sc->flags ^= DAP_SOCK_READY_TO_WRITE;
+
+  int events = EPOLLERR;
+
+  if( sc->flags & DAP_SOCK_READY_TO_READ )
+    events |= EPOLLIN;
+
+  if( sc->flags & DAP_SOCK_READY_TO_WRITE )
+    events |= EPOLLOUT;
+
+  sc->ev.events = events;
+
+  if ( epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &sc->ev) == -1 )
+    log_it(L_ERROR,"Can't update write client socket state in the epoll_fd");
+  else
+    dap_events_thread_wake_up( &sc->events->proc_thread );
+}
+
+
+/**
+ * @brief dap_events_socket_remove Removes the client from the list
+ * @param sc Connection instance
+ */
+void dap_events_socket_delete( dap_events_socket_t *a_es, bool preserve_inheritor )
+{
+  if ( !a_es ) return;
+
+  log_it( L_DEBUG, "es is going to be removed from the lists and free the memory (0x%016X)", a_es );
+
+  pthread_rwlock_wrlock( &a_es->events->sockets_rwlock );
+  HASH_DEL( a_es->events->sockets, a_es );
+  pthread_rwlock_unlock( &a_es->events->sockets_rwlock );
+
+  log_it( L_DEBUG, "dap_events_socket wrapped around %d socket is removed", a_es->socket );
+
+  if( a_es->callbacks->delete_callback )
+    a_es->callbacks->delete_callback( a_es, NULL ); // Init internal structure
+
+  if ( a_es->_inheritor && !preserve_inheritor )
+    free( a_es->_inheritor );
+
+  if ( a_es->socket )
+    close( a_es->socket );
+
+  free( a_es );
+}
+
+/**
+ * @brief dap_events_socket_write Write data to the client
+ * @param sc Conn instance
+ * @param data Pointer to data
+ * @param data_size Size of data to write
+ * @return Number of bytes that were placed into the buffer
+ */
+size_t dap_events_socket_write(dap_events_socket_t *sc, const void * data, size_t data_size)
+{
+    log_it(L_DEBUG,"dap_events_socket_write %u sock data %X size %u", sc->socket, data, data_size );
+
+     data_size = ((sc->buf_out_size+data_size)<(sizeof(sc->buf_out)))?data_size:(sizeof(sc->buf_out)-sc->buf_out_size );
+     memcpy(sc->buf_out+sc->buf_out_size,data,data_size);
+     sc->buf_out_size+=data_size;
+     return data_size;
+}
+
+/**
+ * @brief dap_events_socket_write_f Write formatted text to the client
+ * @param sc Conn instance
+ * @param format Format
+ * @return Number of bytes that were placed into the buffer
+ */
+size_t dap_events_socket_write_f(dap_events_socket_t *sc, const char * format,...)
+{
+    log_it(L_DEBUG,"dap_events_socket_write_f %u sock", sc->socket );
+
+    size_t max_data_size = sizeof(sc->buf_out)-sc->buf_out_size;
+    va_list ap;
+    va_start(ap,format);
+    int ret=vsnprintf((char*) sc->buf_out+sc->buf_out_size,max_data_size,format,ap);
+    va_end(ap);
+    if(ret>0){
+        sc->buf_out_size+=ret;
+        return ret;
+    }else{
+        log_it(L_ERROR,"Can't write out formatted data '%s'",format);
+        return 0;
+    }
+}
+
+/**
+ * @brief dap_events_socket_read Read data from input buffer
+ * @param sc Conn instasnce
+ * @param data Pointer to memory where to store the data
+ * @param data_size Size of data to read
+ * @return Actual bytes number that were read
+ */
+size_t dap_events_socket_read(dap_events_socket_t *sc, void *data, size_t data_size)
+{
+    log_it(L_DEBUG,"dap_events_socket_read %u sock data %X size %u", sc->socket, data, data_size );
+
+    if(data_size<sc->buf_in_size){
+        memcpy(data,sc->buf_in,data_size);
+        memmove(data,sc->buf_in+data_size,sc->buf_in_size-data_size);
+    }else{
+        if(data_size>sc->buf_in_size)
+            data_size=sc->buf_in_size;
+        memcpy(data,sc->buf_in,data_size);
+    }
+    sc->buf_in_size-=data_size;
+    return data_size;
+}
+
+
+/**
+ * @brief dap_events_socket_shrink_client_buf_in Shrink input buffer (shift it left)
+ * @param cl Client instance
+ * @param shrink_size Size on wich we shrink the buffer with shifting it left
+ */
+void dap_events_socket_shrink_buf_in(dap_events_socket_t * cl, size_t shrink_size)
+{
+    if((shrink_size==0)||(cl->buf_in_size==0) ){
+        return;
+    }else if(cl->buf_in_size>shrink_size){
+        size_t buf_size=cl->buf_in_size-shrink_size;
+        void * buf = malloc(buf_size);
+        memcpy(buf,cl->buf_in+ shrink_size,buf_size );
+        memcpy(cl->buf_in,buf,buf_size);
+        cl->buf_in_size=buf_size;
+        if (buf)
+            free(buf);
+    }else{
+        //log_it(WARNING,"Shrinking size of input buffer on amount bigger than actual buffer's size");
+        cl->buf_in_size=0;
+    }
+
+}
diff --git a/src/dap_memcached.c b/src/dap_memcached.c
index 0b4c441147c3dcae92e30d956b5bb57111067168..924cf41e15f6472629e5dd9d03a35b16f7c7b7ff 100755
--- a/src/dap_memcached.c
+++ b/src/dap_memcached.c
@@ -1,71 +1,71 @@
-
-#include "dap_memcached.h"
-
-#include <libmemcached/memcached.h>
-
-#define LOG_TAG "dap_memcached"
-
-static memcached_st *_memc;
-static bool _is_module_enable = false;
-
-int dap_memcached_init(const char *server_host, uint16_t port)
-{
-    memcached_return rc;
-    memcached_server_st *servers = NULL;
-
-    char *test_key = "test_key";
-    char *test_value = "test_value";
-
-    _memc = memcached_create(NULL);
-
-    servers= memcached_server_list_append(servers, server_host, port, &rc);
-    rc= memcached_server_push(_memc, servers);
-
-    if (rc != MEMCACHED_SUCCESS) {
-        log_it(L_ERROR, "Couldn't add server: %s", memcached_strerror(_memc, rc));
-        return -1;
-    }
-
-    if(dap_memcache_put(test_key, test_value, strlen(test_value), 0) != true) {
-        return -2;
-    }
-
-    _is_module_enable = true;
-    return 0;
-}
-
-bool dap_memcache_is_enable()
-{
-    return _is_module_enable;
-}
-
-bool dap_memcache_put(const char* key, void *value, size_t value_size, time_t expiration)
-{
-    memcached_return rc;
-    rc = memcached_set(_memc, key, strlen(key), value, value_size, expiration, (uint32_t)0);
-    if (rc != MEMCACHED_SUCCESS) {
-        log_it(L_ERROR, "%s", memcached_strerror(_memc, rc));
-        return false;
-    }
-    return true;
-}
-
-bool dap_memcache_get(const char* key, size_t * value_size, void ** result)
-{
-    memcached_return rc;
-    *result = memcached_get(_memc, key, strlen(key), value_size, NULL, &rc);
-    return rc == MEMCACHED_SUCCESS;
-}
-
-bool dap_memcache_delete(const char* key)
-{
-    return memcached_delete(_memc, key, strlen(key), 0) == MEMCACHED_SUCCESS;
-}
-
-/**
- * @brief dap_memcached_deinit
- */
-void dap_memcached_deinit()
-{
-    _is_module_enable = false;
-}
+
+#include "dap_memcached.h"
+
+#include <libmemcached/memcached.h>
+
+#define LOG_TAG "dap_memcached"
+
+static memcached_st *_memc;
+static bool _is_module_enable = false;
+
+int dap_memcached_init(const char *server_host, uint16_t port)
+{
+    memcached_return rc;
+    memcached_server_st *servers = NULL;
+
+    char *test_key = "test_key";
+    char *test_value = "test_value";
+
+    _memc = memcached_create(NULL);
+
+    servers= memcached_server_list_append(servers, server_host, port, &rc);
+    rc= memcached_server_push(_memc, servers);
+
+    if (rc != MEMCACHED_SUCCESS) {
+        log_it(L_ERROR, "Couldn't add server: %s", memcached_strerror(_memc, rc));
+        return -1;
+    }
+
+    if(dap_memcache_put(test_key, test_value, strlen(test_value), 0) != true) {
+        return -2;
+    }
+
+    _is_module_enable = true;
+    return 0;
+}
+
+bool dap_memcache_is_enable()
+{
+    return _is_module_enable;
+}
+
+bool dap_memcache_put(const char* key, void *value, size_t value_size, time_t expiration)
+{
+    memcached_return rc;
+    rc = memcached_set(_memc, key, strlen(key), value, value_size, expiration, (uint32_t)0);
+    if (rc != MEMCACHED_SUCCESS) {
+        log_it(L_ERROR, "%s", memcached_strerror(_memc, rc));
+        return false;
+    }
+    return true;
+}
+
+bool dap_memcache_get(const char* key, size_t * value_size, void ** result)
+{
+    memcached_return rc;
+    *result = memcached_get(_memc, key, strlen(key), value_size, NULL, &rc);
+    return rc == MEMCACHED_SUCCESS;
+}
+
+bool dap_memcache_delete(const char* key)
+{
+    return memcached_delete(_memc, key, strlen(key), 0) == MEMCACHED_SUCCESS;
+}
+
+/**
+ * @brief dap_memcached_deinit
+ */
+void dap_memcached_deinit()
+{
+    _is_module_enable = false;
+}
diff --git a/src/dap_server.c b/src/dap_server.c
index c5f52862bd01596ca87e86cfd5dc75ddb779ae68..cf0f38abb3dd787756755b58e3cb152a99d3672b 100755
--- a/src/dap_server.c
+++ b/src/dap_server.c
@@ -1,817 +1,824 @@
-/*
- Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
-  All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    DAP 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 Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public License
-    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#define __USE_GNU
-
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdint.h>
-
-//#include <errno.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdatomic.h>
-
-#ifndef _WIN32
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/select.h>
-#include <errno.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/epoll.h>
-#include <sys/timerfd.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include <sched.h>
-
-#if 0
-#define NI_NUMERICHOST  1 /* Don't try to look up hostname.  */
-#define NI_NUMERICSERV  2 /* Don't convert port number to name.  */
-#define NI_NOFQDN       4 /* Only return nodename portion.  */
-#define NI_NAMEREQD     8 /* Don't return numeric addresses.  */
-#define NI_DGRAM       16 /* Look up UDP service rather than TCP.  */
-#endif
-
-#include "dap_common.h"
-#include "dap_server.h"
-
-#define LOG_TAG "server"
-
-#define DAP_MAX_THREAD_EVENTS           8192
-#define DAP_MAX_THREADS                 16
-
-#define SOCKET_TIMEOUT_TIME             30
-#define SOCKETS_TIMEOUT_CHECK_PERIOD    15
-
-static uint32_t _count_threads = 0;
-static uint32_t epoll_max_events = 0;
-static bool bQuitSignal = false;
-
-static struct epoll_event  *threads_epoll_events = NULL;
-static dap_server_t *_current_run_server = NULL;
-
-static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents );
-
-dap_server_thread_t dap_server_threads[ DAP_MAX_THREADS ];
-
-/*
-===============================================
-  get_epoll_max_user_watches( )
-
-  return max epoll() event watches
-===============================================
-*/
-static uint32_t  get_epoll_max_user_watches( void )
-{
-  static const char *maxepollpath = "/proc/sys/fs/epoll/max_user_watches";
-  uint32_t  v = 0, len;
-  char  str[32];
-
-  FILE *fp = fopen( maxepollpath, "r" );
-  if ( !fp ) {
-    printf("can't open %s\n", maxepollpath );
-    return v;
-  }
-
-  len = fread( &str[0], 1, 31, fp );
-  if ( !len ) {
-    return v;
-  }
-
-  str[ len ] = 0;
-  v = atoi( str );
-
-  return v;
-}
-
-/*
-===============================================
-  dap_server_init( )
-
-  Init server module
-  return Zero if ok others if no
-===============================================
-*/
-int32_t dap_server_init( uint32_t count_threads )
-{
-  dap_server_thread_t *dap_thread;
-
-  #ifndef _WIN32
-    signal( SIGPIPE, SIG_IGN );
-  #endif
-
-  if ( count_threads > DAP_MAX_THREADS )
-    count_threads = DAP_MAX_THREADS;
-
-  _count_threads = count_threads;
-  log_it( L_NOTICE, "dap_server_init() threads %u", count_threads );
-
-  epoll_max_events = get_epoll_max_user_watches( );
-  if ( epoll_max_events > DAP_MAX_THREAD_EVENTS )
-    epoll_max_events = DAP_MAX_THREAD_EVENTS;
-
-  threads_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * _count_threads * epoll_max_events );
-  if ( !threads_epoll_events )
-    goto err;
-
-  memset( threads_epoll_events, 0, sizeof(struct epoll_event) * _count_threads * epoll_max_events );
-
-  dap_thread = &dap_server_threads[0];
-  memset( dap_thread, 0, sizeof(dap_server_thread_t) * DAP_MAX_THREADS );
-
-  for ( uint32_t i = 0; i < _count_threads; ++i, ++dap_thread ) {
-    #ifndef _WIN32
-      dap_thread->epoll_fd = -1;
-    #else
-      dap_thread->epoll_fd = (void*)-1;
-    #endif
-    dap_thread->thread_num = i;
-    dap_thread->epoll_events = &threads_epoll_events[ i * epoll_max_events ];
-
-    pthread_mutex_init( &dap_thread->mutex_dlist_add_remove, NULL );
-  }
-
-  log_it( L_NOTICE, "Initialized socket server module" );
-
-  dap_client_remote_init( );
-  return 0;
-
-err:;
-
-  dap_server_deinit( );
-  return 1;
-}
-
-/*
-=========================================================
-  dap_server_deinit( )
-
-  Deinit server module
-=========================================================
-*/
-void  dap_server_deinit( void )
-{
-  dap_client_remote_deinit( );
-
-  if ( threads_epoll_events ) {
-    free( threads_epoll_events );
-
-    for ( uint32_t i = 0; i < _count_threads; ++i ) {
-      pthread_mutex_destroy( &dap_server_threads[i].mutex_dlist_add_remove );
-    }
-  }
-}
-
-/*
-=========================================================
-  dap_server_new( )
-
-  Creates new empty instance of dap_server_t
-=========================================================
-*/
-dap_server_t  *dap_server_new( void )
-{
-  return (dap_server_t *)calloc( 1, sizeof(dap_server_t) );
-}
-
-/*
-=========================================================
-  dap_server_new( )
-
-  Delete server instance
-=========================================================
-*/
-void dap_server_delete( dap_server_t *sh )
-{
-  dap_client_remote_t *dap_cur, *tmp;
-
-  if ( !sh ) return;
-
-  if( sh->address )
-    free( sh->address );
-
-  HASH_ITER( hh, sh->clients, dap_cur, tmp )
-    dap_client_remote_remove( dap_cur, sh );
-
-  if( sh->server_delete_callback )
-    sh->server_delete_callback( sh, NULL );
-
-  if ( sh->_inheritor )
-    free( sh->_inheritor );
-
-  pthread_mutex_destroy( &sh->mutex_on_hash );
-
-  free( sh );
-}
-
-/*
-=========================================================
-  set_nonblock_socket( )
-=========================================================
-*/
-int32_t set_nonblock_socket( int32_t fd )
-{
-#ifdef _WIN32
-  unsigned long arg = 1;
-  return ioctlsocket( fd, FIONBIO, &arg );
-#else
-  int32_t flags;
-
-  flags = fcntl( fd, F_GETFL );
-  flags |= O_NONBLOCK;
-
-  return fcntl( fd, F_SETFL, flags );
-#endif
-}
-
-
-/*
-=========================================================
-  get_thread_min_connections( )
-
-  return number thread which has minimum open connections
-=========================================================
-*/
-static inline uint32_t get_thread_index_min_connections( )
-{
-  uint32_t min = 0;
-
-  for( uint32_t i = 1; i < _count_threads; i ++ ) {
-    if ( dap_server_threads[min].connections_count > dap_server_threads[i].connections_count ) {
-      min = i;
-    }
-  }
-
-  return min;
-}
-
-/*
-=========================================================
-  print_online( )
-
-=========================================================
-*/
-static inline void print_online()
-{
-//  for( uint32_t i = 0; i < _count_threads; i ++ )  {
-//    log_it(L_INFO, "Thread number: %d, count: %d", 
-//               thread_inform[i].thread_number, atomic_load(&thread_inform[i].count_open_connections) );
-//  }
-}
-
-void  dap_server_kill_socket( dap_client_remote_t *dcr )
-{
-  if ( !dcr ) {
-    log_it( L_ERROR, "dap_server_kill_socket( NULL )" );
-    return;
-  }
-
-  dap_server_thread_t *dsth = &dap_server_threads[ dcr->tn ];
-
-  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-
-  if ( dcr->kill_signal ) {
-    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-    return;
-  }
-
-  log_it( L_DEBUG, "KILL %u socket! [ thread %u ]", dcr->socket, dcr->tn );
-
-  dcr->kill_signal = true;
-
-  DL_LIST_ADD_NODE_HEAD( dsth->dap_clients_to_kill, dcr, kprev, knext, dsth->to_kill_count );
-  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-
-  return;
-}
-
-/*
-=========================================================
-  dap_server_add_socket( )
-
-=========================================================
-*/
-dap_client_remote_t  *dap_server_add_socket( int32_t fd, int32_t forced_thread_n )
-{
-  uint32_t tn = (forced_thread_n == -1) ? get_thread_index_min_connections( ) : forced_thread_n;
-  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
-  dap_client_remote_t *dcr = dap_client_remote_create( _current_run_server, fd, dsth );
-
-  if ( !dcr ) {
-    log_it( L_ERROR, "accept %d dap_client_remote_create() == NULL", fd );
-//    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-    return dcr;
-  }
-
-  log_it( L_DEBUG, "accept %d Client, thread %d", fd, tn );
-
-  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-
-  DL_APPEND( dsth->dap_remote_clients, dcr );
-  dsth->connections_count ++;
-  if ( epoll_ctl( dsth->epoll_fd, EPOLL_CTL_ADD, fd, &dcr->pevent) != 0 ) {
-    log_it( L_ERROR, "epoll_ctl failed 005" );
-  }
-  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-
-  return dcr;
-}
-
-/*
-=========================================================
-  dap_server_remove_socket( )
-
-=========================================================
-*/
-void  dap_server_remove_socket( dap_client_remote_t *dcr )
-{
-  if ( !dcr ) {
-    log_it( L_ERROR, "dap_server_remove_socket( NULL )" );
-    return;
-  }
-
-  uint32_t tn = dcr->tn;
-  log_it( L_DEBUG, "dap_server_remove_socket %u thread %u", dcr->socket, tn );
-
-  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
-
-  if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 )
-    log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
-
-//  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-  DL_DELETE( dsth->dap_remote_clients, dcr );
-  dsth->connections_count --;
-
-//  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-
-  log_it( L_DEBUG, "dcr = %X", dcr );
-}
-
-static void s_socket_all_check_activity( uint32_t tn, time_t cur_time )
-{
-  dap_client_remote_t *dcr, *tmp;
-  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
-
-//  log_it( L_INFO,"s_socket_info_all_check_activity() on thread %u", tn );
-
-  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-
-  DL_FOREACH_SAFE( dsth->dap_remote_clients, dcr, tmp ) {
-
-    if ( !dcr->kill_signal && cur_time >= dcr->last_time_active + SOCKET_TIMEOUT_TIME && !dcr->close_denied ) {
-
-      log_it( L_INFO, "Socket %u timeout, closing...", dcr->socket );
-
-      if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 )
-        log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
-
-      DL_DELETE( dsth->dap_remote_clients, dcr );
-      dsth->connections_count --;
-
-      dap_client_remote_remove( dcr, _current_run_server );
-    }
-  }
-  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-}
-
-/*
-=========================================================
-  read_write_cb( )
-
-=========================================================
-*/
-static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents )
-{
-//  log_it( L_NOTICE, "[THREAD %u] read_write_cb fd %u revents %u", dap_cur->tn, dap_cur->socket, revents );
-//  sleep( 5 ); // ?????????
-
-  if( !dap_cur ) {
-
-    log_it( L_ERROR, "read_write_cb: dap_client_remote NULL" );
-    return;
-  }
-
-  if ( revents & EPOLLIN ) {
-
-//    log_it( L_DEBUG, "[THREAD %u] socket read %d ", dap_cur->tn, dap_cur->socket );
-
-    int32_t bytes_read = recv( dap_cur->socket,
-                                  dap_cur->buf_in + dap_cur->buf_in_size,
-                                  sizeof(dap_cur->buf_in) - dap_cur->buf_in_size,
-                                  0 );
-    if ( bytes_read > 0 ) {
-//      log_it( L_DEBUG, "[THREAD %u] read %u socket client said: %s", dap_cur->tn, bytes_read, dap_cur->buf_in + dap_cur->buf_in_size );
-
-      dap_cur->buf_in_size += (size_t)bytes_read;
-      dap_cur->upload_stat.buf_size_total += (size_t)bytes_read;
-
-//      log_it( L_DEBUG, "[THREAD %u] read %u socket read callback()", dap_cur->tn, bytes_read );
-      _current_run_server->client_read_callback( dap_cur ,NULL );
-    }
-    else if ( bytes_read < 0 ) {
-      log_it( L_ERROR,"Bytes read Error %s",strerror(errno) );
-      if ( strcmp(strerror(errno),"Resource temporarily unavailable") != 0 )
-      dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-    }
-    else { // bytes_read == 0
-      dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-      log_it( L_DEBUG, "0 bytes read" );
-    }
-  }
-
-  if( ( (revents & EPOLLOUT) || (dap_cur->flags & DAP_SOCK_READY_TO_WRITE) ) && !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) ) {
-
-//    log_it(L_DEBUG, "[THREAD %u] socket write %d ", dap_cur->tn, dap_cur->socket );
-    _current_run_server->client_write_callback( dap_cur, NULL ); // Call callback to process write event
-
-    if( dap_cur->buf_out_size == 0 ) {
-     log_it(L_DEBUG, "dap_cur->buf_out_size = 0, set ev_read watcher " );
-
-      dap_cur->pevent.events = EPOLLIN | EPOLLERR;
-      if( epoll_ctl(dap_cur->efd, EPOLL_CTL_MOD, dap_cur->socket, &dap_cur->pevent) != 0 ) {
-        log_it( L_ERROR, "epoll_ctl failed 003" );
-      }
-    }
-    else {
-//      log_it(L_DEBUG, "[THREAD %u] send dap_cur->buf_out_size = %u , %s", dap_cur->tn, dap_cur->buf_out_size, dap_cur->buf_out );
-
-      size_t total_sent = dap_cur->buf_out_offset;
-
-      while ( total_sent < dap_cur->buf_out_size ) {
-        //log_it(DEBUG, "Output: %u from %u bytes are sent ", total_sent, dap_cur->buf_out_size);
-        ssize_t bytes_sent = send( dap_cur->socket,
-                                   dap_cur->buf_out + total_sent,
-                                   dap_cur->buf_out_size - total_sent,
-                                   MSG_DONTWAIT | MSG_NOSIGNAL );
-        if( bytes_sent < 0 ) {
-          log_it(L_ERROR,"[THREAD %u] Error occured in send() function %s", dap_cur->tn, strerror(errno) );
-          dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-          break;
-        }
-
-        total_sent += (size_t)bytes_sent;
-        dap_cur->download_stat.buf_size_total += (size_t)bytes_sent;
-      }
-
-//      log_it( L_ERROR, "check !" );
-
-      if( total_sent == dap_cur->buf_out_size ) {
-        dap_cur->buf_out_offset = dap_cur->buf_out_size  = 0;
-      }
-      else {
-        dap_cur->buf_out_offset = total_sent;
-      }
-    } // else
-  } // write
-
-
-//  log_it(L_ERROR,"OPA !") ;
-//  Sleep(200);
-
-//  if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->close_denied ) {
-//    log_it(L_ERROR,"Close signal" );
-
-//    dap_server_remove_socket( dap_cur );
-//    dap_client_remote_remove( dap_cur, _current_run_server );
-//  }
-
-}
-
-
-/*
-=========================================================
-  dap_server_listen( )
-
-  Create server_t instance and start to listen tcp port with selected address
-
-=========================================================
-*/
-dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type )
-{
-  dap_server_t* sh = dap_server_new( );
-
-  sh->socket_listener = -111;
-
-  if( type == DAP_SERVER_TCP )
-    sh->socket_listener = socket( AF_INET, SOCK_STREAM, 0 );
-  else {
-    dap_server_delete( sh );
-    return NULL;
-  }
-  
-  if ( set_nonblock_socket(sh->socket_listener) == -1 ) {
-    log_it( L_WARNING, "error server socket nonblock" );
-    dap_server_delete( sh );
-    return NULL;
-  }
-
-  if ( sh->socket_listener < 0 ) {
-    log_it ( L_ERROR,"Socket error %s", strerror(errno) );
-    dap_server_delete( sh );
-    return NULL;
-  }
-
-  log_it( L_NOTICE," Socket created..." );
-
-  int32_t reuse = 1;
-
-  if ( reuse ) 
-    if ( setsockopt( sh->socket_listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0 )
-      log_it( L_WARNING, "Can't set up REUSEADDR flag to the socket" );
-
-  sh->listener_addr.sin_family = AF_INET;
-  sh->listener_addr.sin_port = htons( port );
-  inet_pton( AF_INET, addr, &(sh->listener_addr.sin_addr) );
-
-  if( bind(sh->socket_listener, (struct sockaddr *)&(sh->listener_addr), sizeof(sh->listener_addr)) < 0 ) {
-    log_it( L_ERROR,"Bind error: %s",strerror(errno) );
-    dap_server_delete( sh );
-    return NULL;
-  }
-
-  log_it( L_INFO,"Binded %s:%u", addr, port );
-  listen( sh->socket_listener, DAP_MAX_THREAD_EVENTS * _count_threads );
-
-  log_it( L_INFO,"pthread_mutex_init" );
-  pthread_mutex_init( &sh->mutex_on_hash, NULL );
-
-  return sh;
-}
-
-
-/*
-=========================================================
-  thread_loop( )
-
-  Server listener thread loop
-=========================================================
-*/
-void  *thread_loop( void *arg )
-{
-  dap_client_remote_t *dap_cur, *tmp;
-  dap_server_thread_t *dsth = (dap_server_thread_t *)arg;
-  uint32_t tn  = dsth->thread_num;
-  EPOLL_HANDLE efd = dsth->epoll_fd;
-  struct epoll_event  *events = dsth->epoll_events;
-  time_t next_time_timeout_check = time( NULL ) + SOCKETS_TIMEOUT_CHECK_PERIOD;
-
-  log_it(L_NOTICE, "Start loop listener socket thread %u efd %u", tn, efd );
-
-  #ifndef _WIN32
-  cpu_set_t mask;
-  CPU_ZERO( &mask );
-  CPU_SET( tn, &mask );
-
-  if ( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask) != 0 ) {
-    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
-    abort();
-  }
-  #else
-
-  if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) {
-    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
-    abort();
-  }
-
-  #endif
-
-  do {
-
-    int32_t n = epoll_wait( efd, events, DAP_MAX_THREAD_EVENTS, 1000 );
-
-//    log_it(L_WARNING,"[THREAD %u] epoll events %u", tn, n  );
-//    Sleep(300);
-
-    if ( n == -1 || bQuitSignal )
-      break;
-
-    time_t cur_time = time( NULL );
-
-    for ( int32_t i = 0; i < n; ++ i ) {
-
-//      log_it(L_ERROR,"[THREAD %u] process epoll event %u", tn, i  );
-      dap_cur = (dap_client_remote_t *)events[i].data.ptr;
-
-      if ( !dap_cur ) {
-        log_it( L_ERROR,"dap_client_remote_t NULL" );
-        continue;
-      }
-
-      dap_cur->last_time_active = cur_time;
-
-      if( events[i].events & EPOLLERR ) {
-          log_it( L_ERROR,"Socket error: %u, remove it" , dap_cur->socket );
-          dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
-      }
-
-      if ( !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) || dap_cur->close_denied )
-        read_write_cb( dap_cur, events[i].events );
-
-      if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->close_denied ) {
-
-        pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-
-        if ( dap_cur->kill_signal ) {
-          pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-          continue;
-        }
-
-//        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-//        dap_server_kill_socket( dap_cur );
-//        continue;
-
-        log_it( L_INFO, "Got signal to close %u socket, closing...[ %u ]", dap_cur->socket, tn );
-
-        dap_server_remove_socket( dap_cur );
-        dap_client_remote_remove( dap_cur, _current_run_server );
-
-        log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, dsth->connections_count, dsth->to_kill_count  );
-        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-      }
-
-    } // for
-
-    if ( cur_time >= next_time_timeout_check ) {
-
-      s_socket_all_check_activity( tn, cur_time );
-      next_time_timeout_check = cur_time + SOCKETS_TIMEOUT_CHECK_PERIOD;
-    }
-
-    pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
-    if ( !dsth->to_kill_count ) {
-
-      pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-      continue;
-    }
-
-    dap_cur = dsth->dap_clients_to_kill;
-
-    do {
-
-      if ( dap_cur->close_denied ) {
-        dap_cur = dap_cur->knext;
-        continue;
-      }
-
-      log_it( L_INFO, "Kill %u socket ...............[ thread %u ]", dap_cur->socket, tn );
-
-      tmp = dap_cur->knext;
-      DL_LIST_REMOVE_NODE( dsth->dap_clients_to_kill, dap_cur, kprev, knext, dsth->to_kill_count );
-
-      dap_server_remove_socket( dap_cur );
-      dap_client_remote_remove( dap_cur, _current_run_server );
-      dap_cur = tmp;
-
-    } while ( dap_cur );
-
-    log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, dsth->connections_count, dsth->to_kill_count  );
-    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
-
-  } while( !bQuitSignal ); 
-
-  return NULL;
-}
-
-/*
-=========================================================
-  dap_server_loop( )
-
-  Main server loop
-
-  @param a_server Server instance
-  @return Zero if ok others if not
-=========================================================
-*/
-int32_t dap_server_loop( dap_server_t *d_server )
-{
-  static uint32_t pickthread = 0;  // just for test
-  pthread_t thread_listener[ DAP_MAX_THREADS ];
-
-  if ( !d_server ) return 1;
-
-  for( uint32_t i = 0; i < _count_threads; ++i ) {
-
-    EPOLL_HANDLE efd = epoll_create1( 0 );
-//    log_it( L_ERROR, "EPOLL_HANDLE efd %u for thread %u created", efd, i );
-    if ( (intptr_t)efd == -1 ) {
-      log_it( L_ERROR, "Server wakeup no events / error" );
-        goto error;
-    }
-    dap_server_threads[ i ].epoll_fd = efd;
-    dap_server_threads[ i ].thread_num = i;
-  }
-
-  for( uint32_t i = 0; i < _count_threads; ++i ) {
-    pthread_create( &thread_listener[i], NULL, thread_loop, &dap_server_threads[i] );
-  }
-
-  _current_run_server = d_server;
-
-  EPOLL_HANDLE efd = epoll_create1( 0 );
-  if ( (intptr_t)efd == -1 )
-    goto error;
-
-  struct epoll_event  pev;
-  struct epoll_event  events[ 16 ];
-
-  memset(&pev, 0, sizeof(struct epoll_event));
-  pev.events = EPOLLIN | EPOLLERR;
-  pev.data.fd = d_server->socket_listener;
-
-  if( epoll_ctl( efd, EPOLL_CTL_ADD, d_server->socket_listener, &pev) != 0 ) {
-    log_it( L_ERROR, "epoll_ctl failed 004" );
-    goto error;
-  }
-
-  while( 1 ) {
-
-    int32_t n = epoll_wait( efd, &events[0], 16, -1 );
-
-    if ( n <= 0 ) {
-      if(errno == EINTR)
-        continue;
-      log_it( L_ERROR, "Server wakeup no events / error" );
-      break;
-    }
-    for( int32_t i = 0; i < n; ++ i ) {
-
-      if ( events[i].events & EPOLLIN ) {
-
-        int client_fd = accept( events[i].data.fd, 0, 0 );
-
-        if ( client_fd < 0 ) {
-          log_it( L_ERROR, "accept_cb: error accept socket");
-          continue;
-        }
-
-        set_nonblock_socket( client_fd );
-        dap_server_add_socket( client_fd, -1 );
-      }
-      else if( events[i].events & EPOLLERR ) {
-        log_it( L_ERROR, "Server socket error event" );
-        goto exit;
-      }
-
-    } // for
-
-  } // while
-
-exit:;
-
-  #ifndef _WIN32
-    close( efd );
-  #else
-    epoll_close( efd );
-  #endif
-error:;
-
-  bQuitSignal = true;
-
-  for( uint32_t i = 0; i < _count_threads; ++i ) {
-    if ( (intptr_t)dap_server_threads[ i ].epoll_fd != -1 ) {
-      #ifndef _WIN32
-        close( dap_server_threads[ i ].epoll_fd );
-      #else
-        epoll_close( dap_server_threads[ i ].epoll_fd );
-      #endif
-    }
-  }
-
-  return 0;
-}
+/*
+ Copyright (c) 2017-2018 (c) Project "DeM Labs Inc" https://github.com/demlabsinc
+  All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Lesser General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    DAP 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 Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public License
+    along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define __USE_GNU
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+
+//#include <errno.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdatomic.h>
+
+#ifndef _WIN32
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <errno.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include <sched.h>
+
+#if 0
+#define NI_NUMERICHOST  1 /* Don't try to look up hostname.  */
+#define NI_NUMERICSERV  2 /* Don't convert port number to name.  */
+#define NI_NOFQDN       4 /* Only return nodename portion.  */
+#define NI_NAMEREQD     8 /* Don't return numeric addresses.  */
+#define NI_DGRAM       16 /* Look up UDP service rather than TCP.  */
+#endif
+
+#include "dap_common.h"
+#include "dap_server.h"
+
+#define LOG_TAG "server"
+
+#define DAP_MAX_THREAD_EVENTS           8192
+#define DAP_MAX_THREADS                 16
+
+#define SOCKET_TIMEOUT_TIME             30
+#define SOCKETS_TIMEOUT_CHECK_PERIOD    15
+
+static uint32_t _count_threads = 0;
+static uint32_t epoll_max_events = 0;
+static bool bQuitSignal = false;
+
+static struct epoll_event  *threads_epoll_events = NULL;
+static dap_server_t *_current_run_server = NULL;
+
+static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents );
+
+dap_server_thread_t dap_server_threads[ DAP_MAX_THREADS ];
+
+/*
+===============================================
+  get_epoll_max_user_watches( )
+
+  return max epoll() event watches
+===============================================
+*/
+static uint32_t  get_epoll_max_user_watches( void )
+{
+  static const char *maxepollpath = "/proc/sys/fs/epoll/max_user_watches";
+  uint32_t  v = 0, len;
+  char  str[32];
+
+  FILE *fp = fopen( maxepollpath, "r" );
+  if ( !fp ) {
+    printf("can't open %s\n", maxepollpath );
+    return v;
+  }
+
+  len = fread( &str[0], 1, 31, fp );
+  if ( !len ) {
+    return v;
+  }
+
+  str[ len ] = 0;
+  v = atoi( str );
+
+  return v;
+}
+
+/*
+===============================================
+  dap_server_init( )
+
+  Init server module
+  return Zero if ok others if no
+===============================================
+*/
+int32_t dap_server_init( uint32_t count_threads )
+{
+  dap_server_thread_t *dap_thread;
+
+  #ifndef _WIN32
+    signal( SIGPIPE, SIG_IGN );
+  #endif
+
+  if ( count_threads > DAP_MAX_THREADS )
+    count_threads = DAP_MAX_THREADS;
+
+  _count_threads = count_threads;
+  log_it( L_NOTICE, "dap_server_init() threads %u", count_threads );
+
+  epoll_max_events = get_epoll_max_user_watches( );
+  if ( epoll_max_events > DAP_MAX_THREAD_EVENTS )
+    epoll_max_events = DAP_MAX_THREAD_EVENTS;
+
+  threads_epoll_events = (struct epoll_event *)malloc( sizeof(struct epoll_event) * _count_threads * epoll_max_events );
+  if ( !threads_epoll_events )
+    goto err;
+
+  memset( threads_epoll_events, 0, sizeof(struct epoll_event) * _count_threads * epoll_max_events );
+
+  dap_thread = &dap_server_threads[0];
+  memset( dap_thread, 0, sizeof(dap_server_thread_t) * DAP_MAX_THREADS );
+
+  for ( uint32_t i = 0; i < _count_threads; ++i, ++dap_thread ) {
+    #ifndef _WIN32
+      dap_thread->epoll_fd = -1;
+    #else
+      dap_thread->epoll_fd = (void*)-1;
+    #endif
+    dap_thread->thread_num = i;
+    dap_thread->epoll_events = &threads_epoll_events[ i * epoll_max_events ];
+
+    pthread_mutex_init( &dap_thread->mutex_dlist_add_remove, NULL );
+    pthread_mutex_init( &dap_thread->mutex_on_hash, NULL );
+  }
+
+  log_it( L_NOTICE, "Initialized socket server module" );
+
+  dap_client_remote_init( );
+  return 0;
+
+err:;
+
+  dap_server_deinit( );
+  return 1;
+}
+
+/*
+=========================================================
+  dap_server_deinit( )
+
+  Deinit server module
+=========================================================
+*/
+void  dap_server_deinit( void )
+{
+  dap_client_remote_t *dap_cur, *tmp;
+  dap_server_thread_t *t = &dap_server_threads[0];
+
+  dap_client_remote_deinit( );
+
+  if ( threads_epoll_events ) {
+    free( threads_epoll_events );
+
+    for ( uint32_t i = 0; i < _count_threads; ++i, ++t ) {
+
+      HASH_ITER( hh, t->hclients, dap_cur, tmp )
+        dap_client_remote_remove( dap_cur );
+
+      pthread_mutex_destroy( &dap_server_threads[i].mutex_on_hash );
+      pthread_mutex_destroy( &dap_server_threads[i].mutex_dlist_add_remove );
+    }
+  }
+}
+
+/*
+=========================================================
+  dap_server_new( )
+
+  Creates new empty instance of dap_server_t
+=========================================================
+*/
+dap_server_t  *dap_server_new( void )
+{
+  return (dap_server_t *)calloc( 1, sizeof(dap_server_t) );
+}
+
+/*
+=========================================================
+  dap_server_new( )
+
+  Delete server instance
+=========================================================
+*/
+void dap_server_delete( dap_server_t *sh )
+{
+  if ( !sh ) return;
+
+  if( sh->address )
+    free( sh->address );
+
+  if( sh->server_delete_callback )
+    sh->server_delete_callback( sh, NULL );
+
+  if ( sh->_inheritor )
+    free( sh->_inheritor );
+
+  free( sh );
+}
+
+/*
+=========================================================
+  set_nonblock_socket( )
+=========================================================
+*/
+int32_t set_nonblock_socket( int32_t fd )
+{
+#ifdef _WIN32
+  unsigned long arg = 1;
+  return ioctlsocket( fd, FIONBIO, &arg );
+#else
+  int32_t flags;
+
+  flags = fcntl( fd, F_GETFL );
+  flags |= O_NONBLOCK;
+
+  return fcntl( fd, F_SETFL, flags );
+#endif
+}
+
+
+/*
+=========================================================
+  get_thread_min_connections( )
+
+  return number thread which has minimum open connections
+=========================================================
+*/
+static inline uint32_t get_thread_index_min_connections( )
+{
+  uint32_t min = 0;
+
+  for( uint32_t i = 1; i < _count_threads; i ++ ) {
+    if ( dap_server_threads[min].connections_count > dap_server_threads[i].connections_count ) {
+      min = i;
+    }
+  }
+
+  return min;
+}
+
+/*
+=========================================================
+  print_online( )
+
+=========================================================
+*/
+static inline void print_online()
+{
+  for( uint32_t i = 0; i < _count_threads; i ++ )  {
+    log_it( L_INFO, "Thread number: %u, count: %u", i, dap_server_threads[i].connections_count );
+  }
+}
+
+void  dap_server_kill_socket( dap_client_remote_t *dcr )
+{
+  if ( !dcr ) {
+    log_it( L_ERROR, "dap_server_kill_socket( NULL )" );
+    return;
+  }
+
+  dap_server_thread_t *dsth = &dap_server_threads[ dcr->tn ];
+
+  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+
+  if ( dcr->kill_signal ) {
+    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+    return;
+  }
+
+  log_it( L_DEBUG, "KILL %u socket! [ thread %u ]", dcr->socket, dcr->tn );
+
+  dcr->kill_signal = true;
+
+  DL_LIST_ADD_NODE_HEAD( dsth->dap_clients_to_kill, dcr, kprev, knext, dsth->to_kill_count );
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+
+  return;
+}
+
+/*
+=========================================================
+  dap_server_add_socket( )
+
+=========================================================
+*/
+dap_client_remote_t  *dap_server_add_socket( int32_t fd, int32_t forced_thread_n )
+{
+  uint32_t tn = (forced_thread_n == -1) ? get_thread_index_min_connections( ) : forced_thread_n;
+  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
+  dap_client_remote_t *dcr = dap_client_remote_create( _current_run_server, fd, dsth );
+
+  if ( !dcr ) {
+    log_it( L_ERROR, "accept %d dap_client_remote_create() == NULL", fd );
+//    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+    return dcr;
+  }
+
+  log_it( L_DEBUG, "accept %d Client, thread %d", fd, tn );
+
+  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+
+  DL_APPEND( dsth->dap_remote_clients, dcr );
+  dsth->connections_count ++;
+  if ( epoll_ctl( dsth->epoll_fd, EPOLL_CTL_ADD, fd, &dcr->pevent) != 0 ) {
+    log_it( L_ERROR, "epoll_ctl failed 005" );
+  }
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+
+  return dcr;
+}
+
+/*
+=========================================================
+  dap_server_remove_socket( )
+
+=========================================================
+*/
+void  dap_server_remove_socket( dap_client_remote_t *dcr )
+{
+  if ( !dcr ) {
+    log_it( L_ERROR, "dap_server_remove_socket( NULL )" );
+    return;
+  }
+
+  uint32_t tn = dcr->tn;
+  log_it( L_DEBUG, "dap_server_remove_socket %u thread %u", dcr->socket, tn );
+
+  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
+
+  if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 )
+    log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
+
+//  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+  DL_DELETE( dsth->dap_remote_clients, dcr );
+  dsth->connections_count --;
+
+//  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+
+  log_it( L_DEBUG, "dcr = %X", dcr );
+}
+
+static void s_socket_all_check_activity( uint32_t tn, time_t cur_time )
+{
+  dap_client_remote_t *dcr, *tmp;
+  dap_server_thread_t *dsth = &dap_server_threads[ tn ];
+
+//  log_it( L_INFO,"s_socket_info_all_check_activity() on thread %u", tn );
+
+  pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+
+  DL_FOREACH_SAFE( dsth->dap_remote_clients, dcr, tmp ) {
+
+    if ( !dcr->kill_signal && cur_time >= dcr->last_time_active + SOCKET_TIMEOUT_TIME && !dcr->no_close ) {
+
+      log_it( L_INFO, "Socket %u timeout, closing...", dcr->socket );
+
+      if ( epoll_ctl( dcr->efd, EPOLL_CTL_DEL, dcr->socket, &dcr->pevent ) == -1 )
+        log_it( L_ERROR,"Can't remove event socket's handler from the epoll_fd" );
+
+      DL_DELETE( dsth->dap_remote_clients, dcr );
+      dsth->connections_count --;
+
+      dap_client_remote_remove( dcr );
+    }
+  }
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+}
+
+/*
+=========================================================
+  read_write_cb( )
+
+=========================================================
+*/
+static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents )
+{
+//  log_it( L_NOTICE, "[THREAD %u] read_write_cb fd %u revents %u", dap_cur->tn, dap_cur->socket, revents );
+//  sleep( 5 ); // ?????????
+
+  if( !dap_cur ) {
+
+    log_it( L_ERROR, "read_write_cb: dap_client_remote NULL" );
+    return;
+  }
+
+  if ( revents & EPOLLIN ) {
+
+//    log_it( L_DEBUG, "[THREAD %u] socket read %d ", dap_cur->tn, dap_cur->socket );
+
+    int32_t bytes_read = recv( dap_cur->socket,
+                                  dap_cur->buf_in + dap_cur->buf_in_size,
+                                  sizeof(dap_cur->buf_in) - dap_cur->buf_in_size,
+                                  0 );
+    if ( bytes_read > 0 ) {
+//      log_it( L_DEBUG, "[THREAD %u] read %u socket client said: %s", dap_cur->tn, bytes_read, dap_cur->buf_in + dap_cur->buf_in_size );
+
+      dap_cur->buf_in_size += (size_t)bytes_read;
+      dap_cur->upload_stat.buf_size_total += (size_t)bytes_read;
+
+//      log_it( L_DEBUG, "[THREAD %u] read %u socket read callback()", dap_cur->tn, bytes_read );
+      _current_run_server->client_read_callback( dap_cur ,NULL );
+    }
+    else if ( bytes_read < 0 ) {
+      log_it( L_ERROR,"Bytes read Error %s",strerror(errno) );
+      if ( strcmp(strerror(errno),"Resource temporarily unavailable") != 0 )
+      dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+    }
+    else { // bytes_read == 0
+      dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+      log_it( L_DEBUG, "0 bytes read" );
+    }
+  }
+
+  if( ( (revents & EPOLLOUT) || (dap_cur->flags & DAP_SOCK_READY_TO_WRITE) ) && !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) ) {
+
+//    log_it(L_DEBUG, "[THREAD %u] socket write %d ", dap_cur->tn, dap_cur->socket );
+    _current_run_server->client_write_callback( dap_cur, NULL ); // Call callback to process write event
+
+    if( dap_cur->buf_out_size == 0 ) {
+     log_it(L_DEBUG, "dap_cur->buf_out_size = 0, set ev_read watcher " );
+
+      dap_cur->pevent.events = EPOLLIN | EPOLLERR;
+      if( epoll_ctl(dap_cur->efd, EPOLL_CTL_MOD, dap_cur->socket, &dap_cur->pevent) != 0 ) {
+        log_it( L_ERROR, "epoll_ctl failed 003" );
+      }
+    }
+    else {
+//      log_it(L_DEBUG, "[THREAD %u] send dap_cur->buf_out_size = %u , %s", dap_cur->tn, dap_cur->buf_out_size, dap_cur->buf_out );
+
+      size_t total_sent = dap_cur->buf_out_offset;
+
+      while ( total_sent < dap_cur->buf_out_size ) {
+        //log_it(DEBUG, "Output: %u from %u bytes are sent ", total_sent, dap_cur->buf_out_size);
+        ssize_t bytes_sent = send( dap_cur->socket,
+                                   dap_cur->buf_out + total_sent,
+                                   dap_cur->buf_out_size - total_sent,
+                                   MSG_DONTWAIT | MSG_NOSIGNAL );
+        if( bytes_sent < 0 ) {
+          log_it(L_ERROR,"[THREAD %u] Error occured in send() function %s", dap_cur->tn, strerror(errno) );
+          dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+          break;
+        }
+
+        total_sent += (size_t)bytes_sent;
+        dap_cur->download_stat.buf_size_total += (size_t)bytes_sent;
+      }
+
+//      log_it( L_ERROR, "check !" );
+
+      if( total_sent == dap_cur->buf_out_size ) {
+        dap_cur->buf_out_offset = dap_cur->buf_out_size  = 0;
+      }
+      else {
+        dap_cur->buf_out_offset = total_sent;
+      }
+    } // else
+  } // write
+
+
+//  log_it(L_ERROR,"OPA !") ;
+//  Sleep(200);
+
+//  if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->no_close ) {
+//    log_it(L_ERROR,"Close signal" );
+
+//    dap_server_remove_socket( dap_cur );
+//    dap_client_remote_remove( dap_cur, _current_run_server );
+//  }
+
+}
+
+
+/*
+=========================================================
+  dap_server_listen( )
+
+  Create server_t instance and start to listen tcp port with selected address
+
+=========================================================
+*/
+dap_server_t *dap_server_listen( const char *addr, uint16_t port, dap_server_type_t type )
+{
+  dap_server_t* sh = dap_server_new( );
+
+  sh->socket_listener = -111;
+
+  if( type == DAP_SERVER_TCP )
+    sh->socket_listener = socket( AF_INET, SOCK_STREAM, 0 );
+  else {
+    dap_server_delete( sh );
+    return NULL;
+  }
+  
+  if ( set_nonblock_socket(sh->socket_listener) == -1 ) {
+    log_it( L_WARNING, "error server socket nonblock" );
+    dap_server_delete( sh );
+    return NULL;
+  }
+
+  if ( sh->socket_listener < 0 ) {
+    log_it ( L_ERROR,"Socket error %s", strerror(errno) );
+    dap_server_delete( sh );
+    return NULL;
+  }
+
+  log_it( L_NOTICE," Socket created..." );
+
+  int32_t reuse = 1;
+
+  if ( reuse ) 
+    if ( setsockopt( sh->socket_listener, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0 )
+      log_it( L_WARNING, "Can't set up REUSEADDR flag to the socket" );
+
+  sh->listener_addr.sin_family = AF_INET;
+  sh->listener_addr.sin_port = htons( port );
+  inet_pton( AF_INET, addr, &(sh->listener_addr.sin_addr) );
+
+  if( bind(sh->socket_listener, (struct sockaddr *)&(sh->listener_addr), sizeof(sh->listener_addr)) < 0 ) {
+    log_it( L_ERROR,"Bind error: %s",strerror(errno) );
+    dap_server_delete( sh );
+    return NULL;
+  }
+
+  log_it( L_INFO,"Binded %s:%u", addr, port );
+  listen( sh->socket_listener, DAP_MAX_THREAD_EVENTS * _count_threads );
+
+  return sh;
+}
+
+
+/*
+=========================================================
+  thread_loop( )
+
+  Server listener thread loop
+=========================================================
+*/
+void  *thread_loop( void *arg )
+{
+  dap_client_remote_t *dap_cur, *tmp;
+  dap_server_thread_t *dsth = (dap_server_thread_t *)arg;
+  uint32_t tn  = dsth->thread_num;
+  EPOLL_HANDLE efd = dsth->epoll_fd;
+  struct epoll_event  *events = dsth->epoll_events;
+  time_t next_time_timeout_check = time( NULL ) + SOCKETS_TIMEOUT_CHECK_PERIOD;
+
+  log_it(L_NOTICE, "Start loop listener socket thread %u efd %u", tn, efd );
+
+  #ifndef _WIN32
+  cpu_set_t mask;
+  CPU_ZERO( &mask );
+  CPU_SET( tn, &mask );
+
+  if ( pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &mask) != 0 ) {
+    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
+    abort();
+  }
+  #else
+
+  if ( !SetThreadAffinityMask( GetCurrentThread(), (DWORD_PTR)(1 << tn) ) ) {
+    log_it( L_CRITICAL, "Error pthread_setaffinity_np() You really have %d or more core in CPU?", tn );
+    abort();
+  }
+
+  #endif
+
+  do {
+
+    int32_t n = epoll_wait( efd, events, DAP_MAX_THREAD_EVENTS, 1000 );
+
+//    log_it(L_WARNING,"[THREAD %u] epoll events %u", tn, n  );
+//    Sleep(300);
+
+    if ( bQuitSignal )
+      break;
+
+    if ( n < 0 ) {
+      if ( errno == EINTR )
+        continue;
+      break;
+    }
+
+    time_t cur_time = time( NULL );
+
+    for ( int32_t i = 0; i < n; ++ i ) {
+
+//      log_it(L_ERROR,"[THREAD %u] process epoll event %u", tn, i  );
+      dap_cur = (dap_client_remote_t *)events[i].data.ptr;
+
+      if ( !dap_cur ) {
+        log_it( L_ERROR,"dap_client_remote_t NULL" );
+        continue;
+      }
+
+      dap_cur->last_time_active = cur_time;
+
+      if( events[i].events & EPOLLERR ) {
+          log_it( L_ERROR,"Socket error: %u, remove it" , dap_cur->socket );
+          dap_cur->flags |= DAP_SOCK_SIGNAL_CLOSE;
+      }
+
+      if ( !(dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) || dap_cur->no_close )
+        read_write_cb( dap_cur, events[i].events );
+
+      if ( (dap_cur->flags & DAP_SOCK_SIGNAL_CLOSE) && !dap_cur->no_close ) {
+
+        pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+
+        if ( dap_cur->kill_signal ) {
+          pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+          continue;
+        }
+
+//        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+//        dap_server_kill_socket( dap_cur );
+//        continue;
+
+        log_it( L_INFO, "Got signal to close %u socket, closing...[ %u ]", dap_cur->socket, tn );
+
+        dap_server_remove_socket( dap_cur );
+        dap_client_remote_remove( dap_cur );
+
+        log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, dsth->connections_count, dsth->to_kill_count  );
+        pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+      }
+
+    } // for
+
+    if ( cur_time >= next_time_timeout_check ) {
+
+      s_socket_all_check_activity( tn, cur_time );
+      next_time_timeout_check = cur_time + SOCKETS_TIMEOUT_CHECK_PERIOD;
+    }
+
+    pthread_mutex_lock( &dsth->mutex_dlist_add_remove );
+    if ( !dsth->to_kill_count ) {
+
+      pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+      continue;
+    }
+
+    dap_cur = dsth->dap_clients_to_kill;
+
+    do {
+
+      if ( dap_cur->no_close ) {
+        dap_cur = dap_cur->knext;
+        continue;
+      }
+
+      log_it( L_INFO, "Kill %u socket ...............[ thread %u ]", dap_cur->socket, tn );
+
+      tmp = dap_cur->knext;
+      DL_LIST_REMOVE_NODE( dsth->dap_clients_to_kill, dap_cur, kprev, knext, dsth->to_kill_count );
+
+      dap_server_remove_socket( dap_cur );
+      dap_client_remote_remove( dap_cur );
+      dap_cur = tmp;
+
+    } while ( dap_cur );
+
+    log_it( L_INFO, "[ Thread %u ] coneections: %u, to kill: %u", tn, dsth->connections_count, dsth->to_kill_count  );
+    pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+
+  } while( !bQuitSignal ); 
+
+  return NULL;
+}
+
+/*
+=========================================================
+  dap_server_loop( )
+
+  Main server loop
+
+  @param a_server Server instance
+  @return Zero if ok others if not
+=========================================================
+*/
+int32_t dap_server_loop( dap_server_t *d_server )
+{
+  static uint32_t pickthread = 0;  // just for test
+  pthread_t thread_listener[ DAP_MAX_THREADS ];
+
+  if ( !d_server ) return 1;
+
+  for( uint32_t i = 0; i < _count_threads; ++i ) {
+
+    EPOLL_HANDLE efd = epoll_create1( 0 );
+//    log_it( L_ERROR, "EPOLL_HANDLE efd %u for thread %u created", efd, i );
+    if ( (intptr_t)efd == -1 ) {
+      log_it( L_ERROR, "Server wakeup no events / error" );
+        goto error;
+    }
+    dap_server_threads[ i ].epoll_fd = efd;
+    dap_server_threads[ i ].thread_num = i;
+  }
+
+  for( uint32_t i = 0; i < _count_threads; ++i ) {
+    pthread_create( &thread_listener[i], NULL, thread_loop, &dap_server_threads[i] );
+  }
+
+  _current_run_server = d_server;
+
+  EPOLL_HANDLE efd = epoll_create1( 0 );
+  if ( (intptr_t)efd == -1 )
+    goto error;
+
+  struct epoll_event  pev;
+  struct epoll_event  events[ 16 ];
+
+  pev.events = EPOLLIN | EPOLLERR;
+  pev.data.fd = d_server->socket_listener;
+
+  if( epoll_ctl( efd, EPOLL_CTL_ADD, d_server->socket_listener, &pev) != 0 ) {
+    log_it( L_ERROR, "epoll_ctl failed 004" );
+    goto error;
+  }
+
+  while( !bQuitSignal ) {
+
+    int32_t n = epoll_wait( efd, &events[0], 16, -1 );
+
+    if ( bQuitSignal )
+      break;
+
+    if ( n <= 0 ) {
+      if ( errno == EINTR )
+        continue;
+      log_it( L_ERROR, "Server wakeup no events / error" );
+      break;
+    }
+
+    for( int32_t i = 0; i < n; ++ i ) {
+
+      if ( events[i].events & EPOLLIN ) {
+
+        int client_fd = accept( events[i].data.fd, 0, 0 );
+
+        if ( client_fd < 0 ) {
+          log_it( L_ERROR, "accept_cb: error accept socket");
+          continue;
+        }
+
+        set_nonblock_socket( client_fd );
+        dap_server_add_socket( client_fd, -1 );
+      }
+      else if( events[i].events & EPOLLERR ) {
+        log_it( L_ERROR, "Server socket error event" );
+        goto exit;
+      }
+
+    } // for
+
+  } // while
+
+exit:;
+
+  #ifndef _WIN32
+    close( efd );
+  #else
+    epoll_close( efd );
+  #endif
+error:;
+
+  bQuitSignal = true;
+
+  for( uint32_t i = 0; i < _count_threads; ++i ) {
+    if ( (intptr_t)dap_server_threads[ i ].epoll_fd != -1 ) {
+      #ifndef _WIN32
+        close( dap_server_threads[ i ].epoll_fd );
+      #else
+        epoll_close( dap_server_threads[ i ].epoll_fd );
+      #endif
+    }
+  }
+
+  return 0;
+}
diff --git a/src/dap_traffic_track.c b/src/dap_traffic_track.c
index 6024833c3552dece12d5cfeac8c8aa738c878c4b..60e7822ab3ff1d1742745dcdf691827a047aabbf 100755
--- a/src/dap_traffic_track.c
+++ b/src/dap_traffic_track.c
@@ -1,230 +1,232 @@
-/*
- * Authors:
- * Anatoliy Kurotich <anatoliy.kurotich@demlabs.net>
- * DeM Labs Inc.   https://demlabs.net
- * Kelvin Project https://github.com/kelvinblockchain
- * Copyright  (c) 2017-2018
- * All rights reserved.
-
- This file is part of DAP (Deus Applications Prototypes) the open source project
-
-    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-
-#ifndef _WIN32
-#include <pthread.h>
-#include <ev.h>
-#else
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x0600
-#include <winsock2.h>
-#include <windows.h>
-#include <mswsock.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include "wrappers.h"
-#include <wepoll.h>
-#include <pthread.h>
-#endif
-
-#include "dap_traffic_track.h"
-#include "dap_common.h"
-#include "dap_cpu_monitor.h"
-
-#define LOG_TAG "dap_traffic_track"
-
-#define BITS_IN_BYTE    8
-#define ALLOC_STEP      100
-
-static dap_traffic_callback_t _callback = NULL;
-static dap_server_t *_dap_server;
-
-#ifndef _WIN32
-static ev_timer _timeout_watcher;
-static struct ev_loop *loop;
-#else
-static HANDLE _timeout_watcher;
-#endif
-static size_t timertimeout = 1;
-
-static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
-static pthread_t worker_thread;
-static bool _stop_worker_signal = false;
-
-
-/**
- * @brief calculate_mbits_speed
- * @param count_bytes
- * @details timeout we gots from _timeout_watcher.repeat
- * @return mbit/second speed
- */
-static double _calculate_mbits_speed( size_t count_bytes )
-{
-  size_t bits_per_second = (count_bytes / timertimeout) * BITS_IN_BYTE;
-  //    log_it(L_DEBUG, "TIMEOUT: %d, bits_per_second: %d mbits: %f",
-  //           (size_t)_timeout_watcher.repeat, bits_per_second, bits_per_second / 1000000.0);
-  return (double)bits_per_second / 1000000.0; // convert to mbits
-}
-
-void *_worker_run( void *a )
-{
-  (void)a;
-
-  pthread_mutex_lock( &_mutex );
-
-  while( true ) {
-    pthread_cond_wait( &_cond, &_mutex );
-    if ( _stop_worker_signal ) {
-      log_it(L_INFO, "Dap traffic track worker stopped");
-      _stop_worker_signal = false;
-      break;
-    }
-    _callback( _dap_server );
-  }
-
-  pthread_mutex_unlock( &_mutex );
-  pthread_exit( NULL );
-
-  return NULL;
-}
-
-void _worker_start( )
-{
-  pthread_mutex_init( &_mutex, NULL );
-  pthread_cond_init( &_cond, NULL );
-  pthread_create( &worker_thread, NULL, _worker_run, NULL );
-}
-
-void _worker_stop()
-{
-  pthread_mutex_lock( &_mutex );
-  _stop_worker_signal = true;
-  pthread_cond_signal( &_cond );
-  pthread_mutex_unlock( &_mutex );
-
-  // wait for exit worker_thread
-  pthread_join( worker_thread, NULL );
-
-  pthread_mutex_destroy( &_mutex );
-  pthread_cond_destroy( &_cond );
-  _callback = NULL;
-}
-
-#ifndef _WIN32
-static void _timeout_cb( )
-#else
-VOID CALLBACK _timeout_cb( void *lpParameter, BOOL TimerOrWaitFired )
-#endif
-{
-  pthread_mutex_lock( &_dap_server->mutex_on_hash );
-
-  size_t count_users = HASH_COUNT(_dap_server->clients );
-
-  if ( count_users ) {
-//    size_t idx = 0;
-    dap_client_remote_t *dap_cur, *tmp;
-    HASH_ITER( hh, _dap_server->clients, dap_cur, tmp ) {
-
-      dap_cur->upload_stat.speed_mbs = _calculate_mbits_speed( dap_cur->upload_stat.buf_size_total -
-                                       dap_cur->upload_stat.buf_size_total_old );
-
-      dap_cur->upload_stat.buf_size_total_old = dap_cur->upload_stat.buf_size_total;
-
-      dap_cur->download_stat.speed_mbs = _calculate_mbits_speed( dap_cur->download_stat.buf_size_total -
-                                           dap_cur->download_stat.buf_size_total_old );
-
-      dap_cur->download_stat.buf_size_total_old = dap_cur->download_stat.buf_size_total;
-
-//      idx ++;
-    }
-  }
-
-  /* TODO find some better solution and place for this line */
-  _dap_server->cpu_stats = dap_cpu_get_stats( );
-
-  pthread_mutex_unlock( &_dap_server->mutex_on_hash );
-
-  if ( _callback != NULL ) {
-    pthread_mutex_lock( &_mutex );
-    pthread_cond_signal( &_cond );
-    pthread_mutex_unlock( &_mutex );
-  }
-}
-
-void dap_traffic_track_init( dap_server_t * server,
-                            time_t timeout )
-{
-  dap_cpu_monitor_init( );
-
-  _dap_server = server;
-#ifndef _WIN32
-  _timeout_watcher.repeat = timeout;
-
-  loop = EV_DEFAULT;
-
-  ev_init( &_timeout_watcher, _timeout_cb );
-  ev_timer_again( loop, &_timeout_watcher );
-#else
-
-  timertimeout = timeout;
-
-  CreateTimerQueueTimer( &_timeout_watcher, NULL, (WAITORTIMERCALLBACK)_timeout_cb, NULL, timertimeout, timertimeout, 0 );
-
-#endif
-
-  log_it(L_NOTICE, "Initialized traffic track module");
-}
-
-void dap_traffic_track_deinit()
-{
-  if ( _callback != NULL )
-    _worker_stop();
-
-#ifndef _WIN32
-  ev_timer_stop( loop, &_timeout_watcher );
-  ev_loop_destroy( loop );
-#else
-  DeleteTimerQueueTimer( NULL, _timeout_watcher, NULL );
-#endif
-
-  log_it( L_NOTICE, "Deinitialized traffic track module" );
-  dap_cpu_monitor_deinit( );
-}
-
-void dap_traffic_callback_stop() {
-
-  if ( _callback == NULL ) {
-    log_it( L_WARNING, "worker not running" );
-    return;
-  }
-  _worker_stop();
-}
-
-void dap_traffic_callback_set(dap_traffic_callback_t cb)
-{
-  if( _callback == NULL ) {
-    _callback = cb;
-    _worker_start();
-    return;
-  }
-
-  log_it( L_WARNING, "Callback already setted" );
-}
+/*
+ * Authors:
+ * Anatoliy Kurotich <anatoliy.kurotich@demlabs.net>
+ * DeM Labs Inc.   https://demlabs.net
+ * Kelvin Project https://github.com/kelvinblockchain
+ * Copyright  (c) 2017-2018
+ * All rights reserved.
+
+ This file is part of DAP (Deus Applications Prototypes) the open source project
+
+    DAP (Deus Applicaions Prototypes) 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 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 based project.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#ifndef _WIN32
+#include <pthread.h>
+#include <ev.h>
+#else
+#undef _WIN32_WINNT
+#define _WIN32_WINNT 0x0600
+#include <winsock2.h>
+#include <windows.h>
+#include <mswsock.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include "wrappers.h"
+#include <wepoll.h>
+#include <pthread.h>
+#endif
+
+#include "dap_traffic_track.h"
+#include "dap_common.h"
+#include "dap_cpu_monitor.h"
+
+#define LOG_TAG "dap_traffic_track"
+
+#define BITS_IN_BYTE    8
+#define ALLOC_STEP      100
+
+static dap_traffic_callback_t _callback = NULL;
+static dap_server_t *_dap_server;
+
+#ifndef _WIN32
+static ev_timer _timeout_watcher;
+static struct ev_loop *loop;
+#else
+static HANDLE _timeout_watcher;
+#endif
+static size_t timertimeout = 1;
+
+static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t _cond = PTHREAD_COND_INITIALIZER;
+static pthread_t worker_thread;
+static bool _stop_worker_signal = false;
+
+
+/**
+ * @brief calculate_mbits_speed
+ * @param count_bytes
+ * @details timeout we gots from _timeout_watcher.repeat
+ * @return mbit/second speed
+ */
+static double _calculate_mbits_speed( size_t count_bytes )
+{
+  size_t bits_per_second = (count_bytes / timertimeout) * BITS_IN_BYTE;
+  //    log_it(L_DEBUG, "TIMEOUT: %d, bits_per_second: %d mbits: %f",
+  //           (size_t)_timeout_watcher.repeat, bits_per_second, bits_per_second / 1000000.0);
+  return (double)bits_per_second / 1000000.0; // convert to mbits
+}
+
+void *_worker_run( void *a )
+{
+  (void)a;
+
+  pthread_mutex_lock( &_mutex );
+
+  while( true ) {
+    pthread_cond_wait( &_cond, &_mutex );
+    if ( _stop_worker_signal ) {
+      log_it(L_INFO, "Dap traffic track worker stopped");
+      _stop_worker_signal = false;
+      break;
+    }
+    _callback( _dap_server );
+  }
+
+  pthread_mutex_unlock( &_mutex );
+  pthread_exit( NULL );
+
+  return NULL;
+}
+
+void _worker_start( )
+{
+  pthread_mutex_init( &_mutex, NULL );
+  pthread_cond_init( &_cond, NULL );
+  pthread_create( &worker_thread, NULL, _worker_run, NULL );
+}
+
+void _worker_stop()
+{
+  pthread_mutex_lock( &_mutex );
+  _stop_worker_signal = true;
+  pthread_cond_signal( &_cond );
+  pthread_mutex_unlock( &_mutex );
+
+  // wait for exit worker_thread
+  pthread_join( worker_thread, NULL );
+
+  pthread_mutex_destroy( &_mutex );
+  pthread_cond_destroy( &_cond );
+  _callback = NULL;
+}
+
+#ifndef _WIN32
+static void _timeout_cb( )
+#else
+VOID CALLBACK _timeout_cb( void *lpParameter, BOOL TimerOrWaitFired )
+#endif
+{
+#if 0
+  pthread_mutex_lock( &_dap_server->mutex_on_hash );
+
+  size_t count_users = HASH_COUNT(_dap_server->clients );
+
+  if ( count_users ) {
+//    size_t idx = 0;
+    dap_client_remote_t *dap_cur, *tmp;
+    HASH_ITER( hh, _dap_server->clients, dap_cur, tmp ) {
+
+      dap_cur->upload_stat.speed_mbs = _calculate_mbits_speed( dap_cur->upload_stat.buf_size_total -
+                                       dap_cur->upload_stat.buf_size_total_old );
+
+      dap_cur->upload_stat.buf_size_total_old = dap_cur->upload_stat.buf_size_total;
+
+      dap_cur->download_stat.speed_mbs = _calculate_mbits_speed( dap_cur->download_stat.buf_size_total -
+                                           dap_cur->download_stat.buf_size_total_old );
+
+      dap_cur->download_stat.buf_size_total_old = dap_cur->download_stat.buf_size_total;
+
+//      idx ++;
+    }
+  }
+
+  /* TODO find some better solution and place for this line */
+  _dap_server->cpu_stats = dap_cpu_get_stats( );
+
+  pthread_mutex_unlock( &_dap_server->mutex_on_hash );
+#endif
+
+  if ( _callback != NULL ) {
+    pthread_mutex_lock( &_mutex );
+    pthread_cond_signal( &_cond );
+    pthread_mutex_unlock( &_mutex );
+  }
+}
+
+void dap_traffic_track_init( dap_server_t * server,
+                            time_t timeout )
+{
+  dap_cpu_monitor_init( );
+
+  _dap_server = server;
+#ifndef _WIN32
+  _timeout_watcher.repeat = timeout;
+
+  loop = EV_DEFAULT;
+
+  ev_init( &_timeout_watcher, _timeout_cb );
+  ev_timer_again( loop, &_timeout_watcher );
+#else
+
+  timertimeout = timeout;
+
+  CreateTimerQueueTimer( &_timeout_watcher, NULL, (WAITORTIMERCALLBACK)_timeout_cb, NULL, timertimeout, timertimeout, 0 );
+
+#endif
+
+  log_it(L_NOTICE, "Initialized traffic track module");
+}
+
+void dap_traffic_track_deinit()
+{
+  if ( _callback != NULL )
+    _worker_stop();
+
+#ifndef _WIN32
+  ev_timer_stop( loop, &_timeout_watcher );
+  ev_loop_destroy( loop );
+#else
+  DeleteTimerQueueTimer( NULL, _timeout_watcher, NULL );
+#endif
+
+  log_it( L_NOTICE, "Deinitialized traffic track module" );
+  dap_cpu_monitor_deinit( );
+}
+
+void dap_traffic_callback_stop() {
+
+  if ( _callback == NULL ) {
+    log_it( L_WARNING, "worker not running" );
+    return;
+  }
+  _worker_stop();
+}
+
+void dap_traffic_callback_set(dap_traffic_callback_t cb)
+{
+  if( _callback == NULL ) {
+    _callback = cb;
+    _worker_start();
+    return;
+  }
+
+  log_it( L_WARNING, "Callback already setted" );
+}
diff --git a/test/dap_traffic_track_test.c b/test/dap_traffic_track_test.c
index 9a0cdfc9e2d6e65e4c76e429754b87dd1cb22d64..a7f70ddcf478f7f2ab9aa6d961381a8aed5c051d 100755
--- a/test/dap_traffic_track_test.c
+++ b/test/dap_traffic_track_test.c
@@ -2,11 +2,12 @@
 #include <unistd.h>
 #include <ev.h>
 #include <math.h>
+#if 0
 
 static struct ev_loop *loop;
 
 static struct moc_dap_clients_remote {
-	dap_client_remote_t ** clients;
+  dap_client_remote_t ** clients;
     size_t count;
 } moc_dap_clients_remote;
 
@@ -46,13 +47,13 @@ void init_test_case() {
                                             sizeof(dap_client_remote_t *));
     for(size_t i = 0, j = 0; (i < moc_dap_clients_remote.count) && (j = i + 1); i++) {
         moc_dap_clients_remote.clients[i] =
-        		dap_client_remote_create(_dap_server, j, NULL);
+            dap_client_remote_create(_dap_server, j, NULL);
     }
 }
 
 void cleanup_test_case() {
     for(size_t i = 0; i < moc_dap_clients_remote.count; i++)
-    	dap_client_remote_remove(moc_dap_clients_remote.clients[i], _dap_server);
+      dap_client_remote_remove(moc_dap_clients_remote.clients[i], _dap_server);
     ev_loop_destroy(loop);
     DAP_DELETE(moc_dap_clients_remote.clients);
     DAP_DELETE(_dap_server);
@@ -65,3 +66,4 @@ void dap_traffic_track_tests_run(void) {
     test_callback();
     cleanup_test_case();
 }
+#endif