diff --git a/dap_client_remote.c b/dap_client_remote.c
index 2c0172df82f85a6b2112e8afa3cc4366af0f04de..6eb8ce433102bff5dc5168dbe6f7c1c7681ffc51 100755
--- a/dap_client_remote.c
+++ b/dap_client_remote.c
@@ -23,15 +23,27 @@
 */
 #include <stdlib.h>
 #include <stdio.h>
-#include <unistd.h>
 #include <string.h>
-#include <ev.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_client_remote.h"
 #include "dap_server.h"
-
+#include "dap_client_remote.h"
 
 #define LOG_TAG "dap_client_remote"
 
@@ -39,33 +51,35 @@
  * @brief dap_client_init Init clients module
  * @return Zero if ok others if no
  */
-int dap_client_remote_init()
+int dap_client_remote_init( )
 {
-    log_it(L_NOTICE,"Initialized socket client module");
-    return 0;
+  log_it( L_NOTICE, "Initialized socket client module" );
+
+  return 0;
 }
 
 /**
  * @brief dap_client_deinit Deinit clients module
  */
-void dap_client_remote_deinit()
+void dap_client_remote_deinit( )
 {
 
+  return;
 }
 
 /**
  * @brief _save_ip_and_port
  * @param cl
  */
-void _save_ip_and_port(dap_client_remote_t * cl)
+void _save_ip_and_port( dap_client_remote_t * cl )
 {
-    struct sockaddr_in ip_adr_get;
-    socklen_t ip_adr_len;
+  struct sockaddr_in ip_adr_get;
+  socklen_t ip_adr_len;
 
-    getpeername(cl->socket, &ip_adr_get, &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));
+  cl->port = ntohs( ip_adr_get.sin_port );
+  strcpy( cl->s_ip, inet_ntoa(ip_adr_get.sin_addr) );
 }
 
 /**
@@ -74,49 +88,64 @@ void _save_ip_and_port(dap_client_remote_t * cl)
  * @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, ev_io* w_client)
+dap_client_remote_t *dap_client_remote_create( dap_server_t *sh, int s, dap_server_thread_t *dsth )
 {
-    pthread_mutex_lock(&sh->mutex_on_hash);
-
-    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->watcher_client = w_client;
-    dsc->_ready_to_read = true;
-    dsc->buf_out_offset = 0;
-    _save_ip_and_port(dsc);
-
-    HASH_ADD_INT(sh->clients, socket, dsc);
-    if(sh->client_new_callback)
-        sh->client_new_callback(dsc, NULL); // Init internal structure
-
-    pthread_mutex_unlock(&sh->mutex_on_hash);
-    log_it(L_DEBUG, "Connected client ip: %s port %d", dsc->s_ip, dsc->port);
+  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->_ready_to_read = true;
+  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;
+  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)
+void dap_client_remote_remove( dap_client_remote_t *sc, struct dap_server * sh )
 {
-    pthread_mutex_lock(&sh->mutex_on_hash);
+  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
 
-    log_it(L_DEBUG, "Client structure remove");
-    HASH_DEL(sc->server->clients,sc);
+  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->server->client_delete_callback )
+    sc->server->client_delete_callback( sc, NULL ); // Init internal structure
 
-    if(sc->socket)
-        close(sc->socket);
-    free(sc);
-    pthread_mutex_unlock(&sh->mutex_on_hash);
+  if( sc->_inheritor )
+    free( sc->_inheritor );
+
+  if( sc->socket )
+    close( sc->socket );
+
+  free( sc );
 }
 
 /**
@@ -125,13 +154,15 @@ void dap_client_remote_remove(dap_client_remote_t *sc, struct dap_server * sh)
  * @param sh
  * @return
  */
-dap_client_remote_t * dap_client_remote_find(int sock, struct dap_server * sh)
+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;
+  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;
 }
 
 /**
@@ -139,20 +170,29 @@ dap_client_remote_t * dap_client_remote_find(int sock, struct dap_server * sh)
  * @param sc
  * @param isReady
  */
-void dap_client_remote_ready_to_read(dap_client_remote_t * sc,bool is_ready)
+void  dap_client_remote_ready_to_read( dap_client_remote_t *sc, bool is_ready )
 {
-    if(is_ready != sc->_ready_to_read) {
-        int events = 0;
-        sc->_ready_to_read=is_ready;
+  if( is_ready != sc->_ready_to_read ) {
 
-        if(sc->_ready_to_read)
-            events |= EV_READ;
+//    log_it( L_ERROR, "remote_ready_to_read() %u efd %X", sc->socket, sc->efd );
 
-        if(sc->_ready_to_write)
-            events |= EV_WRITE;
+    int events = EPOLLERR;
+    sc->_ready_to_read = is_ready;
 
-        ev_io_set(sc->watcher_client, sc->socket, events );
+    if( sc->_ready_to_read ) {
+      events |= EPOLLIN;
     }
+
+    if( sc->_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" );
+    }
+  }
 }
 
 /**
@@ -160,20 +200,29 @@ void dap_client_remote_ready_to_read(dap_client_remote_t * sc,bool is_ready)
  * @param sc
  * @param isReady
  */
-void dap_client_remote_ready_to_write(dap_client_remote_t * sc,bool is_ready)
+void  dap_client_remote_ready_to_write( dap_client_remote_t *sc, bool is_ready )
 {
-    if(is_ready != sc->_ready_to_write) {
-        int events = 0;
-        sc->_ready_to_write=is_ready;
+  if ( is_ready != sc->_ready_to_write ) {
+
+//    log_it( L_ERROR, "remote_ready_to_write() %u efd %X", sc->socket, sc->efd );
 
-        if(sc->_ready_to_read)
-            events |= EV_READ;
+    int events = EPOLLERR;
+    sc->_ready_to_write = is_ready;
 
-        if(sc->_ready_to_write)
-            events |= EV_WRITE;
+    if ( sc->_ready_to_read ) {
+      events |= EPOLLIN;
+    }
 
-        ev_io_set(sc->watcher_client, sc->socket, events );
+    if ( sc->_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" );
+    }
+  }
 }
 
 /**
@@ -183,15 +232,16 @@ void dap_client_remote_ready_to_write(dap_client_remote_t * sc,bool is_ready)
  * @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)
+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;
+  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;
 }
 
 /**
@@ -200,20 +250,25 @@ size_t dap_client_remote_write(dap_client_remote_t *sc, const void * data, size_
  * @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 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;
-    }
+  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;
+  }
 }
 
 /**
@@ -223,19 +278,23 @@ size_t dap_client_remote_write_f(dap_client_remote_t *a_client, const char * a_f
  * @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)
+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_data, 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);
+  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;
     }
-    a_client->buf_in_size -= a_data_size;
-    return a_data_size;
+    memcpy( a_data, a_client->buf_in, a_data_size );
+  }
+
+  a_client->buf_in_size -= a_data_size;
+
+  return a_data_size;
 }
 
 
@@ -244,8 +303,9 @@ size_t dap_client_remote_read(dap_client_remote_t *a_client, void * a_data, size
  * @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)
+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){
@@ -258,5 +318,26 @@ void dap_client_remote_shrink_buf_in(dap_client_remote_t * a_client, size_t a_sh
     }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/dap_client_remote.h b/dap_client_remote.h
index 15acea86907dc7ef9db5653ddd5c70e116f42e24..4bd1d45f162e9b666bb5f99a108ba7a70bcc8759 100755
--- a/dap_client_remote.h
+++ b/dap_client_remote.h
@@ -27,80 +27,102 @@
 #include <stddef.h>
 #include <stdbool.h>
 #include "uthash.h"
-#include <ev.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
+
+  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 {
 
-typedef struct dap_client_remote{
-    int socket;
-    dap_server_client_id id;
+  int socket;
+  dap_server_client_id id;
 
-    bool signal_close;
-    bool _ready_to_write;
-    bool _ready_to_read;
+  bool signal_close;
+  bool _ready_to_write;
+  bool _ready_to_read;
 
-    uint16_t port;
-    str_ip s_ip;
+  uint16_t port;
+  str_ip s_ip;
 
-    uint32_t buf_out_zero_count;
-    char buf_in[DAP_CLIENT_REMOTE_BUF+1]; // Internal buffer for input data
+  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
+  size_t buf_in_size; // size of data that is in the input buffer
 
-    traffic_stats_t upload_stat;
-    traffic_stats_t download_stat;
+  traffic_stats_t upload_stat;
+  traffic_stats_t download_stat;
 
-    char buf_out[DAP_CLIENT_REMOTE_BUF+1]; // Internal buffer for output data
-    size_t buf_out_offset;
+  char buf_out[DAP_CLIENT_REMOTE_BUF]; // Internal buffer for output data
+  size_t buf_out_offset;
 
-    char hostaddr[1024]; // Address
-    char service[128];
+  char hostaddr[1024]; // Address
+  char service[128];
 
-    size_t buf_out_size; // size of data that is in the output buffer
-    ev_io* watcher_client;
+  size_t buf_out_size; // size of data that is in the output buffer
+  struct epoll_event  pevent;
 
-    struct dap_server * server;
+  EPOLL_HANDLE efd;            // Epoll fd
+  int tn;             // working thread index
 
-    UT_hash_handle hh;
+  time_t time_connection;
+  time_t last_time_active;
 
-    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
+  struct dap_server *server;
 
+  UT_hash_handle hh;
+  struct dap_client_remote *next, *prev;
 
+  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
+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(struct dap_server * sh, int s, ev_io* w_client); // Create new client and add it to the list
-dap_client_remote_t * dap_client_remote_find(int sock, struct dap_server * sh); // Find client by socket
+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);
+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);
+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, 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);
+void dap_client_remote_shrink_buf_in( dap_client_remote_t * cl, size_t shrink_size );
 
diff --git a/dap_events.c b/dap_events.c
index 5e13b238f285ab16a0230e3b53328abb4a385796..a46737bd977fed283136657a620a0a8383aa9d04 100755
--- a/dap_events.c
+++ b/dap_events.c
@@ -23,6 +23,15 @@
 */
 #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>
@@ -34,18 +43,9 @@
 #include <netdb.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <string.h>
-#include <time.h>
-
-#include <stdio.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
 #include <errno.h>
 #include <signal.h>
 
-
-
 #if 1
 #include <sys/timerfd.h>
 #elif defined(DAP_OS_ANDROID)
@@ -53,147 +53,167 @@
 #define NO_TIMER
 #endif
 
-#include <utlist.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>
+
+//#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;
 
-typedef struct open_connection_info {
-    dap_events_socket_t *es;
-    struct open_connection_info *next;
-} dap_events_socket_info_t;
+//dap_events_socket_info_t **s_dap_events_sockets;
 
-dap_events_socket_info_t **s_dap_events_sockets;
-static uint8_t s_threads_count = 1;
-static size_t s_connection_timeout = 600;
+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;
+dap_worker_t *s_workers = NULL;
+dap_thread_t *s_threads = NULL;
 
 #define LOG_TAG "dap_events"
-#define MAX_EPOLL_EVENTS 255
 
-size_t s_get_cpu_count()
+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);
-
-    size_t count = 0;
-    for (int i = 0; i < 32; i++){
-        if (CPU_ISSET(i, &cs))
-        count++;
-    }
-    return count;
+  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;
+  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
  */
-int dap_events_init(size_t a_threads_count,size_t conn_timeout)
+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();
+  s_threads_count = a_threads_count ? a_threads_count : s_get_cpu_count( );
 
-    if(conn_timeout)s_connection_timeout=conn_timeout;
+  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 );
+  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;
 
-    if(dap_events_socket_init() != 0 )
-    {
-        log_it(L_CRITICAL, "Can't init client submodule");
-        return -1;
-    }
+  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" );
 
-    s_dap_events_sockets = malloc(sizeof(dap_events_socket_info_t *) * s_threads_count );
-    for(int i = 0; i < s_threads_count; i++)
-        s_dap_events_sockets[i] = NULL; // i == index == thread number
+  #ifndef _WIN32
+    signal( SIGPIPE, SIG_IGN );
+  #endif
+  return 0;
 
- //   *open_connection_info = malloc(sizeof(open_connection_info) * my_config.threads_cnt);
-    log_it(L_NOTICE,"Initialized socket server module");
-    signal(SIGPIPE, SIG_IGN);
-    return 0;
+err:
+  dap_events_deinit( );
+  return -1;
 }
 
 /**
  * @brief sa_server_deinit Deinit server module
  */
-void dap_events_deinit()
+void dap_events_deinit( )
 {
-    dap_events_socket_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 * 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);
+  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;
+  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)
+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->sockets_rwlock);
-        pthread_rwlock_destroy(&a_events->servers_rwlock);
-        free(a_events);
-    }
-}
+  dap_events_socket_t *cur, *tmp;
 
-/**
- * @brief dap_events_socket_info_remove
- * @param cl
- * @param n_thread
- * @return
- */
-static bool dap_events_socket_info_remove(dap_events_socket_t* cl, uint8_t n_thread)
-{
-    if(  n_thread >= s_threads_count ){
-        log_it(L_WARNING, "Number thread %u not exists. remove client from list error", n_thread);
-        return false;
-    }
-    dap_events_socket_info_t *el, *tmp;
-
-    LL_FOREACH_SAFE(s_dap_events_sockets[n_thread], el, tmp)
-    {
-        if( el->es == cl )
-        {
-            LL_DELETE(s_dap_events_sockets[n_thread], el);
-            log_it(L_DEBUG, "Removed event socket from the thread's list");
-            return true;
-        }
+  if ( a_events ) {
+
+   // TODO REPLACE TO DLIST
+    HASH_ITER( hh, a_events->sockets,cur, tmp ) {
+      dap_events_socket_delete( cur, false );
     }
+   // TODO REPLACE TO DLIST
+
+    if ( a_events->_inheritor )
+      free( a_events->_inheritor );
 
-    log_it(L_WARNING, "Try remove client from list but not find."
-                    " Thread: %d client socket %d", n_thread, cl->socket);
-    return false;
+    pthread_rwlock_destroy( &a_events->servers_rwlock );
+    pthread_rwlock_destroy( &a_events->sockets_rwlock );
+
+    free( a_events );
+  }
 }
 
 /**
@@ -201,29 +221,54 @@ static bool dap_events_socket_info_remove(dap_events_socket_t* cl, uint8_t n_thr
  * @param n_thread
  * @param sh
  */
-static void s_socket_info_all_check_activity(uint8_t n_thread, dap_events_t *sh)
+static void s_socket_all_check_activity( dap_worker_t *dap_worker, dap_events_t *d_ev, time_t cur_time )
 {
-//    log_it(L_INFO, "========================================================= Socket check");
-//    return; /// TODO debug and make thats shit working, bitch!
-    dap_events_socket_info_t *ei;
-    LL_FOREACH(s_dap_events_sockets[n_thread], ei){
-        if( ei->es->is_pingable ){
-            if(( time(NULL) - ei->es->last_ping_request ) > (time_t) s_connection_timeout ){ // conn timeout
-                log_it(L_INFO, "Connection on socket %d close by timeout", ei->es->socket);
-
-                dap_events_socket_t * cur = dap_events_socket_find(ei->es->socket, sh);
-                if ( cur != NULL ){
-                    dap_events_socket_remove_and_delete( cur );
-                } else {
-                    log_it(L_ERROR, "Trying close socket but not find on client hash!");
-                    close(ei->es->socket);
-                }
-            } else if(( time(NULL) - ei->es->last_ping_request ) > (time_t) s_connection_timeout/3 ){
-                log_it(L_INFO, "Connection on socket %d last chance to remain alive", ei->es->socket);
+  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 ( cur_time >= a_es->last_time_active + s_connection_timeout ) {
+
+      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, true );
+    }
+  }
+  pthread_mutex_unlock( &dap_worker->locker_on_count );
+
+/**
+  LL_FOREACH( s_dap_events_sockets[n_thread], ei ) {
+
+    if( ei->es->is_pingable ){
+
+      if ( (time(NULL) - ei->es->last_ping_request) > (time_t)s_connection_timeout ) { // conn timeout
+
+        log_it( L_INFO, "Connection on socket %d close by timeout", ei->es->sockets );
+
+         dap_events_socket_t * cur = dap_events_socket_find( ei->es->socket, sh );
+          if ( cur != NULL ){
+            dap_events_socket_remove_and_delete( cur );
+          } 
+          else {
+            log_it(L_ERROR, "Trying close socket but not find on client hash!");
+            close(ei->es->socket);
+          }
+      } 
+      else if(( time(NULL) - ei->es->last_ping_request ) > (time_t) s_connection_timeout/3 ) {
+        log_it(L_INFO, "Connection on socket %d last chance to remain alive", ei->es->socket);
+      }
     }
+  }
+**/
+
 }
 
 /**
@@ -231,201 +276,190 @@ static void s_socket_info_all_check_activity(uint8_t n_thread, dap_events_t *sh)
  * @param arg
  * @return
  */
-static void* thread_worker_function(void *arg)
+static void *thread_worker_function( void *arg )
 {
-    dap_worker_t* w = (dap_worker_t*) arg;
-    dap_events_socket_t* cur;
+  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 NO_POSIX_SHED
-    cpu_set_t mask;
-    CPU_ZERO(&mask);
-    CPU_SET(*(int*)arg, &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
+  #ifndef _WIN32
+  #ifndef NO_POSIX_SHED
+  cpu_set_t mask;
+  CPU_ZERO( &mask );
+  CPU_SET( tn, &mask );
 
-    struct epoll_event ev, events[MAX_EPOLL_EVENTS];
-    memzero(&ev,sizeof(ev));
-    memzero(&events,sizeof(events));
-#ifndef NO_TIMER
-    int timerfd;
-    if ((timerfd = timerfd_create(CLOCK_MONOTONIC, 0)) < 0)
-    {
-        log_it(L_CRITICAL, "Failed to create timer");
-        abort();
-    }
-#endif
-    log_it(L_INFO, "Worker 0x%x %d started, epoll fd %d timerfd %d", w, w->number_thread, w->epoll_fd, timerfd);
+  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
 
-    struct itimerspec timerValue;
-    memzero(&timerValue, sizeof(timerValue));
+  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
 
-    timerValue.it_value.tv_sec = 10;
-    timerValue.it_value.tv_nsec = 0;
-    timerValue.it_interval.tv_sec = s_connection_timeout / 2;
-    timerValue.it_interval.tv_nsec = 0;
 
+  log_it(L_INFO, "Worker %d started, epoll fd %d", w->number_thread, w->epoll_fd);
 
-#ifndef NO_TIMER
-    ev.events = EPOLLIN;
-    ev.data.fd = timerfd;
-    epoll_ctl(w->epoll_fd, EPOLL_CTL_ADD, timerfd, &ev);
+  struct epoll_event *events = &g_epoll_events[ DAP_MAX_EPOLL_EVENTS * tn ];
 
-    if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
-        log_it(L_CRITICAL, "Could not start timer");
-        abort();
-    }
-#endif
+//  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, MAX_EPOLL_EVENTS, -1);
-        //log_it(L_INFO, "Epoll pwait trigered worker %d", w->number_thread);
-        for(int n = 0; n < selected_sockets; n++) {
-#ifndef  NO_TIMER
-            if (events[n].data.fd == timerfd) {
-                static uint64_t val;
-                /* if we not reading data from socket, he triggered again */
-                read(events[n].data.fd, &val, 8);
-                s_socket_info_all_check_activity(w->number_thread, w->events);
-            } else
-#endif
-            if (  ( cur = dap_events_socket_find(events[n].data.fd, w->events) ) != NULL  ) {
-                //log_it(L_DEBUG, "Epoll event n=%d/%d fd=%d events=%d cur=%d", n, selected_sockets, events[n].data.fd, events[n].events, cur);
-                if( events[n].events & EPOLLERR ) {
-                    log_it(L_ERROR,"Socket error: %s",strerror(errno));
-                    cur->signal_close=true;
-                    cur->callbacks->error_callback(cur,NULL); // Call callback to process error event
-                } else {
-                    if( events[n].events & EPOLLIN ) {
-                        log_it(L_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;
-                        }
-
-                        int bytes_read = recv(cur->socket,
-                                              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(L_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));
-                            cur->signal_close = true;
-                        } else if (bytes_read == 0) {
-                            log_it(L_INFO, "Client socket disconnected");
-                            cur->signal_close = true;
-                        }
-                    }
-
-                    // Socket is ready to write
-                    if( ( events[n].events & EPOLLOUT  ||  cur->_ready_to_write  )
-                            &&  ( !cur->signal_close )  ) {
-                        //log_it(L_DEBUG, "Main loop output: %u bytes to send", cur->buf_out_size);
-                        cur->callbacks->write_callback(cur, NULL); // Call callback to process write event
-
-                        if(cur->_ready_to_write)
-                        {
-                            cur->buf_out[cur->buf_out_size]='\0';
-                            static const uint32_t buf_out_zero_count_max = 20;
-                            if(cur->buf_out_size == 0)
-                            {
-                                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,
-                                                  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");
-                                break;
-                            }
-                            total_sent+= bytes_sent;
-                            //log_it(L_DEBUG, "Output: %u from %u bytes are sent ", total_sent,cur->buf_out_size);
-                        }
-
-                        //log_it(L_DEBUG,"Output: sent %u bytes",total_sent);
-                        cur->buf_out_size = 0;
-                    }
-                }
-
-                if(cur->signal_close)
-                {
-                    log_it(L_INFO, "Got signal to close from the client %s", cur->hostaddr);
-                    dap_events_socket_remove_and_delete(cur);
-                }
-            }  else {
-                log_it(L_ERROR,"Socket %d is not present in epoll set", events[n].data.fd);
-                ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
-                ev.data.fd=events[n].data.fd;
-
-                if (epoll_ctl(w->epoll_fd, EPOLL_CTL_DEL, events[n].data.fd, &ev) == -1)
-                    log_it(L_ERROR,"Can't remove not presented socket from the epoll_fd");
+  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 ++ ) {
+
+      //dap_events_socket_t *cur = dap_events_socket_find( events[n].data.fd, w->events );
+      dap_events_socket_t *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->signal_close = true;
+        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) );
+          cur->signal_close = true;
+        } 
+        else if ( bytes_read == 0 ) {
+          log_it( L_INFO, "Client socket disconnected" );
+          cur->signal_close = true;
+        }
+      }
+
+      // Socket is ready to write
+      if( ( events[n].events & EPOLLOUT || cur->_ready_to_write ) && !cur->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->_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");
+             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->signal_close ) {
+        log_it( L_INFO, "Got signal to close from the client %s", cur->hostaddr );
+        dap_events_socket_remove_and_delete( cur, false );
+      }
+    } // 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;
     }
-    return NULL;
+    #endif
+  } // while
+
+  return NULL;
 }
 
 /**
  * @brief dap_worker_get_min
  * @return
  */
-dap_worker_t * dap_worker_get_min()
+dap_worker_t *dap_worker_get_min( )
 {
-    return &s_workers[dap_worker_get_index_min()];
+  return &s_workers[dap_worker_get_index_min()];
 }
 
 /**
  * @brief dap_worker_get_index_min
  * @return
  */
-uint8_t dap_worker_get_index_min()
+uint32_t dap_worker_get_index_min( )
 {
-    uint8_t min = 0;
-    uint8_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;
-    }
+  uint32_t min = 0;
+  uint32_t i;
+
+  for( i = 1; i < s_threads_count; i++ ) {
 
-    return min;
+    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()
+void dap_worker_print_all( )
 {
-    uint8_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);
-    }
+  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 );
+  }
 }
 
 /**
@@ -433,24 +467,25 @@ void dap_worker_print_all()
  * @param sh Server instance
  * @return Zero if ok others if not
  */
-int dap_events_start(dap_events_t * a_events)
+int dap_events_start( dap_events_t *a_events )
 {
-    int i;
-    for(i = 0; i < s_threads_count; i++)
-    {
-        if ( (s_workers[i].epoll_fd = epoll_create(MAX_EPOLL_EVENTS)) == -1 )
-        {
-            log_it(L_CRITICAL, "Error create epoll fd");
-            return -1;
-        }
-        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]);
+  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;
     }
 
-    return 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;
 }
 
 /**
@@ -458,15 +493,16 @@ int dap_events_start(dap_events_t * a_events)
  * @param sh
  * @return
  */
-int dap_events_wait(dap_events_t * sh)
+int dap_events_wait( dap_events_t *sh )
 {
-    (void) sh;
-    int i;
-    for(i = 0; i < s_threads_count; i++){
-        void * ret;
-        pthread_join(s_threads[i].tid,&ret);
-    }
-   return 0;
+  (void) sh;
+
+  for( uint32_t i = 0; i < s_threads_count; i ++ ) {
+    void *ret;
+    pthread_join( s_threads[i].tid, &ret );
+  }
+
+  return 0;
 }
 
 
@@ -476,61 +512,45 @@ int dap_events_wait(dap_events_t * sh)
  * @param a_worker
  * @param a_events_socket
  */
-void dap_worker_add_events_socket(dap_events_socket_t * 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();
-
-    ev.events = EPOLLIN | EPOLLERR;// | EPOLLOUT;
-    ev.data.fd = a_events_socket->socket;
+//  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;
 
-    pthread_mutex_lock(&l_worker->locker_on_count);
-    l_worker->event_sockets_count++;
-    pthread_mutex_unlock(&l_worker->locker_on_count);
-
-    dap_events_socket_info_t * l_es_info = DAP_NEW_Z(dap_events_socket_info_t);
-    l_es_info->es = a_events_socket;
-    a_events_socket->dap_worker = l_worker;
-    LL_APPEND(s_dap_events_sockets[l_worker->number_thread], l_es_info);
-
-    if ( epoll_ctl(l_worker->epoll_fd, EPOLL_CTL_ADD, a_events_socket->socket, &ev) == 1 )
-        log_it(L_CRITICAL,"Can't add event socket's handler to epoll_fd");
-
+  pthread_mutex_lock( &l_worker->locker_on_count );
+  l_worker->event_sockets_count ++;
+  DL_APPEND( a_es->events->dlsockets, a_es );
+  pthread_mutex_unlock( &l_worker->locker_on_count );
 }
 
 /**
  * @brief dap_events_socket_delete
  * @param a_es
  */
-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 )
 {
+  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 );
 
-    struct epoll_event ev={0};
-    ev.events = EPOLLIN | EPOLLOUT | EPOLLERR;
-    ev.data.fd=a_es->socket;
-
-    if (epoll_ctl(a_es->dap_worker->epoll_fd, EPOLL_CTL_DEL, a_es->socket, &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);
-
-    pthread_mutex_lock(&a_es->dap_worker->locker_on_count);
-    a_es->dap_worker->event_sockets_count--;
-    pthread_mutex_unlock(&a_es->dap_worker->locker_on_count);
-
-    dap_events_socket_info_remove(a_es, a_es->dap_worker->number_thread);
-    dap_events_socket_delete(a_es,true);
+  pthread_mutex_lock( &a_es->dap_worker->locker_on_count );
+  a_es->dap_worker->event_sockets_count --;
+  DL_DELETE( a_es->events->dlsockets, a_es );
+  pthread_mutex_unlock( &a_es->dap_worker->locker_on_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 dap_events_thread_wake_up( dap_thread_t *th )
 {
-    (void) th;
-
-   //pthread_kill(th->tid,SIGUSR1);
+  (void) th;
+ //pthread_kill(th->tid,SIGUSR1);
 }
diff --git a/dap_events.h b/dap_events.h
index 942b588a6b9a10ad263bc39cc11d6ba75ffbe347..7708fb091164364d8376067ef47d8ca5bce0b105 100755
--- a/dap_events.h
+++ b/dap_events.h
@@ -22,59 +22,67 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 #pragma once
-#include <sys/types.h>
+
+#ifndef WIN32
 #include <netinet/in.h>
 
 #include <stdint.h>
 #include <pthread.h>
-#include "uthash.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 void (*dap_events_callback_t) (struct dap_events *, void *arg); // Callback for specific server's operations
 
-typedef struct dap_thread{
-    pthread_t tid;
+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
-    pthread_rwlock_t sockets_rwlock;
 
-    void * _inheritor;  // Pointer to the internal data, HTTP for example
+typedef struct dap_events {
+
+  dap_events_socket_t *sockets; // Hashmap of event sockets
+  dap_events_socket_t *dlsockets; // 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_thread_t proc_thread;
-    pthread_rwlock_t servers_rwlock;
 } dap_events_t;
 
 typedef struct dap_worker
 {
-    int event_sockets_count;
-    int epoll_fd;
-    uint8_t number_thread;
-    pthread_mutex_t locker_on_count;
-    dap_events_t * events;
-} dap_worker_t;
+  uint32_t event_sockets_count;
+  EPOLL_HANDLE epoll_fd;
+  uint32_t number_thread;
+  pthread_mutex_t locker_on_count;
+  dap_events_t *events;
 
+} dap_worker_t;
 
-int dap_events_init(size_t a_threads_count,size_t conn_t); // Init server module
-void dap_events_deinit(); // Deinit server module
+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_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 );
 
-int dap_events_start(dap_events_t * sh);
-int dap_events_wait(dap_events_t * sh);
+int32_t dap_events_start( dap_events_t *sh );
+int32_t dap_events_wait( dap_events_t *sh );
 
-uint8_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();
+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/dap_events_socket.c b/dap_events_socket.c
index 86dcec2fdffbac0a98af188475eb19e67f11ca40..56c7a8c7ad87aa0b854f018d2734a71ddaa0db19 100755
--- a/dap_events_socket.c
+++ b/dap_events_socket.c
@@ -22,15 +22,29 @@
     along with any DAP based project.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <sys/epoll.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
-#include <unistd.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"
 
@@ -42,7 +56,7 @@
  * @brief dap_events_socket_init Init clients module
  * @return Zero if ok others if no
  */
-int dap_events_socket_init()
+int dap_events_socket_init( )
 {
     log_it(L_NOTICE,"Initialized socket client module");
     return 0;
@@ -51,7 +65,7 @@ int dap_events_socket_init()
 /**
  * @brief dap_events_socket_deinit Deinit clients module
  */
-void dap_events_socket_deinit()
+void dap_events_socket_deinit( )
 {
 
 }
@@ -65,44 +79,47 @@ void dap_events_socket_deinit()
  * @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)
+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_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->_ready_to_read=true;
-    return ret;
+//  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->_ready_to_read = true;
+
+  return ret;
 }
 
 /**
  * @brief dap_events_socket_create_after
  * @param a_es
  */
-void dap_events_socket_create_after(dap_events_socket_t * 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
+  if ( a_es->callbacks->new_callback )
+    a_es->callbacks->new_callback( a_es, NULL ); // Init internal structure
 
-/*
-    pthread_rwlock_wrlock(&a_es->events->sockets_rwlock);
-    a_es->last_ping_request = time(NULL);
-    HASH_ADD_INT(a_es->events->sockets, socket, a_es);
-    pthread_rwlock_unlock(&a_es->events->sockets_rwlock);
+  a_es->last_time_active = a_es->last_ping_request = time( NULL );
 
-    dap_worker_add_events_socket(a_es);
-*/
-    dap_worker_add_events_socket(a_es);
+  dap_worker_add_events_socket( 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" );
 
-    a_es->events = a_es->dap_worker->events;
-    pthread_rwlock_wrlock(&a_es->events->sockets_rwlock);
-    a_es->last_ping_request = time(NULL);
-    HASH_ADD_INT(a_es->events->sockets, socket, a_es);
-    pthread_rwlock_unlock(&a_es->events->sockets_rwlock);
 }
 
 /**
@@ -113,28 +130,32 @@ void dap_events_socket_create_after(dap_events_socket_t * a_es)
  * @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)
+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,"Dap 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->_ready_to_read=true;
-    ret->is_pingable = true;
-
-    pthread_rwlock_wrlock(&a_events->sockets_rwlock);
-    ret->last_ping_request = time(NULL);
-    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;
+  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->_ready_to_read = true;
+  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;
 }
 
 /**
@@ -143,13 +164,15 @@ dap_events_socket_t * dap_events_socket_wrap2(dap_server_t * a_server, struct da
  * @param sh
  * @return
  */
-dap_events_socket_t * dap_events_socket_find(int sock, struct dap_events * a_events)
+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;
+  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;
 }
 
 /**
@@ -157,23 +180,23 @@ dap_events_socket_t * dap_events_socket_find(int sock, struct dap_events * a_eve
  * @param sc
  * @param isReady
  */
-void dap_events_socket_set_readable(dap_events_socket_t * sc,bool is_ready)
+void dap_events_socket_set_readable( dap_events_socket_t *sc, bool is_ready )
 {
-    if(is_ready != sc->_ready_to_read){
-        struct epoll_event ev={0};
-        ev.events = EPOLLERR;
-        sc->_ready_to_read=is_ready;
-        if(sc->_ready_to_read)
-            ev.events  |= EPOLLIN;
-        if(sc->_ready_to_write)
-            ev.events |= EPOLLOUT;
-
-        ev.data.fd=sc->socket;
-        if (epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &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);
-    }
+  if ( is_ready != sc->_ready_to_read ) {
+
+    sc->ev.events = EPOLLERR;
+    sc->_ready_to_read = is_ready;
+
+    if ( sc->_ready_to_read )
+      sc->ev.events  |= EPOLLIN;
+    if ( sc->_ready_to_write )
+      sc->ev.events |= EPOLLOUT;
+
+    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 );
+  }
 }
 
 /**
@@ -181,23 +204,23 @@ void dap_events_socket_set_readable(dap_events_socket_t * sc,bool is_ready)
  * @param sc
  * @param isReady
  */
-void dap_events_socket_set_writable(dap_events_socket_t * sc,bool is_ready)
+void dap_events_socket_set_writable( dap_events_socket_t *sc, bool is_ready )
 {
-    if(is_ready != sc->_ready_to_write){
-        struct epoll_event ev={0};
-        ev.events = EPOLLERR ;
-        sc->_ready_to_write=is_ready;
-        if(sc->_ready_to_read)
-            ev.events |= EPOLLIN;
-        if(sc->_ready_to_write)
-            ev.events |= EPOLLOUT;
-        ev.data.fd=sc->socket;
-        if (epoll_ctl(sc->dap_worker->epoll_fd, EPOLL_CTL_MOD, sc->socket, &ev) == -1) {
-            log_it(L_ERROR,"Can't update write client socket state in the epoll_fd=%d socket=0x%x",sc->dap_worker->epoll_fd, sc->socket);
-        }else
-            dap_events_thread_wake_up(&sc->events->proc_thread);
-    }
+  if ( is_ready != sc->_ready_to_write ) {
+
+    sc->ev.events = EPOLLERR;
+    sc->_ready_to_write = is_ready;
+
+    if ( sc->_ready_to_read )
+      sc->ev.events |= EPOLLIN;
+    if ( sc->_ready_to_write )
+      sc->ev.events |= EPOLLOUT;
 
+    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 );
+  }
 }
 
 
@@ -205,29 +228,30 @@ void dap_events_socket_set_writable(dap_events_socket_t * sc,bool is_ready)
  * @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)
+void dap_events_socket_delete( dap_events_socket_t *a_es, bool preserve_inheritor )
 {
-    if (a_es){
-        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->socket )
-            close( 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)
-//        if(a_es->_inheritor)
-            free(a_es->_inheritor);
-
-        if(a_es->socket){
-            close(a_es->socket);
-        }
-        free(a_es);
-	}
+  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 );
+
+//a_es->ev
+
+  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 );
 }
 
 /**
@@ -239,6 +263,8 @@ void dap_events_socket_delete(dap_events_socket_t *a_es, bool preserve_inheritor
  */
 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;
@@ -253,6 +279,8 @@ size_t dap_events_socket_write(dap_events_socket_t *sc, const void * data, size_
  */
 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);
@@ -274,8 +302,10 @@ size_t dap_events_socket_write_f(dap_events_socket_t *sc, const char * format,..
  * @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)
+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);
@@ -305,7 +335,7 @@ void dap_events_socket_shrink_buf_in(dap_events_socket_t * cl, size_t shrink_siz
         memcpy(cl->buf_in,buf,buf_size);
         cl->buf_in_size=buf_size;
         if (buf)
-        	free(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/dap_events_socket.h b/dap_events_socket.h
index 09e8cb3f323ec5239460a6053f5dada417a903c4..2f9dec38357dab785015811f88b7d5925c49dba2 100755
--- a/dap_events_socket.h
+++ b/dap_events_socket.h
@@ -22,16 +22,24 @@
     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{
+
+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
@@ -40,10 +48,11 @@ typedef struct dap_events_socket_callbacks{
 
 } dap_events_socket_callbacks_t;
 
-
 #define DAP_EVENTS_SOCKET_BUF 100000
 
-typedef struct dap_events_socket{
+#if 0
+typedef struct dap_events_socket {
+
     int socket;
     bool signal_close;
 
@@ -64,9 +73,9 @@ typedef struct dap_events_socket{
 
     size_t buf_out_size; // size of data that is in the output buffer
 
-    struct dap_events * events;
+    struct dap_events *events;
 
-    struct dap_worker* dap_worker;
+    struct dap_worker *dap_worker;
     dap_events_socket_callbacks_t *callbacks;
 
     time_t time_connection;
@@ -77,8 +86,47 @@ typedef struct dap_events_socket{
 
     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;
+
+  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;
+  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;
+
+  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
diff --git a/dap_memcached.c b/dap_memcached.c
index 451c11e8190e6b11a71f35a2259f4915b75d2fea..0b4c441147c3dcae92e30d956b5bb57111067168 100755
--- a/dap_memcached.c
+++ b/dap_memcached.c
@@ -1,6 +1,7 @@
+
 #include "dap_memcached.h"
-#include <libmemcached/memcached.h>
 
+#include <libmemcached/memcached.h>
 
 #define LOG_TAG "dap_memcached"
 
diff --git a/dap_server.c b/dap_server.c
index 31658ae8016110bbc38c1f4f2a2f97c078df8820..da61e955e52cafa9c9e4a8646e3d170bc07df8e5 100755
--- a/dap_server.c
+++ b/dap_server.c
@@ -18,400 +18,713 @@
     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>
-
-#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.  */
-
+#include <errno.h>
 #include <netdb.h>
 #include <unistd.h>
 #include <fcntl.h>
-#include <string.h>
-#include <time.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdatomic.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"
-#include <ev.h>
 
 #define LOG_TAG "server"
 
-static void read_write_cb (struct ev_loop* loop, struct ev_io* watcher, int revents);
+#define DAP_MAX_THREAD_EVENTS           8192
+#define DAP_MAX_THREADS                 16
 
-static struct ev_loop** listener_clients_loops;
+#define SOCKET_TIMEOUT_TIME             30
+#define SOCKETS_TIMEOUT_CHECK_PERIOD    15
 
-static ev_async* async_watchers;
-static dap_server_t * _current_run_server;
-static size_t _count_threads = 0;
+static uint32_t _count_threads = 0;
+static uint32_t epoll_max_events = 0;
+static bool bQuitSignal = false;
 
-typedef struct ev_async_data
+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 )
 {
-    int client_fd;
-    int thread_number;
-} ev_async_data_t;
+  static const char *maxepollpath = "/proc/sys/fs/epoll/max_user_watches";
+  uint32_t  v = 0, len;
+  char  str[32];
 
-static struct thread_information {
-    int thread_number;
-    atomic_size_t count_open_connections;
-} *thread_inform;
+  FILE *fp = fopen( maxepollpath, "r" );
+  if ( !fp ) {
+    printf("can't open %s\n", maxepollpath );
+    return v;
+  }
 
-static pthread_mutex_t mutex_set_client_thread_cb;
-static pthread_mutex_t mutex_on_cnt_connections;
+  len = fread( &str[0], 1, 31, fp );
+  if ( !len ) {
+    return v;
+  }
 
-#define DAP_EV_DATA(a) ((ev_async_data_t*)a->data)
+  str[ len ] = 0;
+  v = atoi( str );
 
-/**
- * @brief dap_server_init Init server module
- * @return Zero if ok others if no
- */
-int dap_server_init(size_t count_threads)
+  return v;
+}
+
+/*
+===============================================
+  dap_server_init( )
+
+  Init server module
+  return Zero if ok others if no
+===============================================
+*/
+int32_t dap_server_init( uint32_t count_threads )
 {
-    _count_threads = count_threads;
+  dap_server_thread_t *dap_thread;
 
-    signal(SIGPIPE, SIG_IGN);
+  #ifndef _WIN32
+    signal( SIGPIPE, SIG_IGN );
+  #endif
 
-    async_watchers = malloc(sizeof(ev_async) * _count_threads);
-    listener_clients_loops = malloc(sizeof(struct ev_loop*) * _count_threads);
-    thread_inform = malloc (sizeof(struct thread_information) * _count_threads);
+  if ( count_threads > DAP_MAX_THREADS )
+    count_threads = DAP_MAX_THREADS;
 
-    for(size_t i = 0; i < _count_threads; i++)
-    {
-        thread_inform[i].thread_number = (int)i;
-        atomic_init(&thread_inform[i].count_open_connections, 0);
-        async_watchers[i].data = malloc(sizeof(ev_async_data_t));
-    }
+  _count_threads = count_threads;
+  log_it( L_NOTICE, "dap_server_init() threads %u", count_threads );
 
-    pthread_mutex_init(&mutex_set_client_thread_cb, NULL);
-    pthread_mutex_init(&mutex_on_cnt_connections, NULL);
+  epoll_max_events = get_epoll_max_user_watches( );
+  if ( epoll_max_events > DAP_MAX_THREAD_EVENTS )
+    epoll_max_events = DAP_MAX_THREAD_EVENTS;
 
-    log_it(L_NOTICE,"Initialized socket server module");
-    dap_client_remote_init();
-    return 0;
+  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;
 }
 
-/**
- * @brief dap_server_deinit Deinit server module
- */
-void dap_server_deinit()
+/*
+=========================================================
+  dap_server_deinit( )
+
+  Deinit server module
+=========================================================
+*/
+void  dap_server_deinit( void )
 {
-    dap_client_remote_deinit();
-    for(size_t i = 0; i < _count_threads; i++)
-        free (async_watchers[i].data);
+  dap_client_remote_deinit( );
+
+  if ( threads_epoll_events ) {
+    free( threads_epoll_events );
 
-    free(async_watchers);
-    free(listener_clients_loops);
-    free(thread_inform);
+    for ( uint32_t i = 0; i < _count_threads; ++i )
+      pthread_mutex_destroy( &dap_server_threads[i].mutex_dlist_add_remove );
+  }
 }
 
+/*
+=========================================================
+  dap_server_new( )
 
-/**
- * @brief server_new Creates new empty instance of server_t
- * @return New instance
- */
-dap_server_t * 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));
+  return (dap_server_t *)calloc( 1, sizeof(dap_server_t) );
 }
 
-/**
- * @brief server_delete Deete server instance
- * @param sh Pointer to the server instance
- */
-void dap_server_delete(dap_server_t * sh)
+/*
+=========================================================
+  dap_server_new( )
+
+  Delete server instance
+=========================================================
+*/
+void dap_server_delete( dap_server_t *sh )
 {
-    dap_client_remote_t * dap_cur, * tmp;
-    if(sh->address)
-        free(sh->address);
+  dap_client_remote_t *dap_cur, *tmp;
 
-    HASH_ITER(hh,sh->clients,dap_cur,tmp)
-        dap_client_remote_remove(dap_cur, sh);
+  if ( !sh ) return;
 
-    if(sh->server_delete_callback)
-        sh->server_delete_callback(sh,NULL);
-    free(sh->_inheritor);
-    free(sh);
-}
+  if( sh->address )
+    free( sh->address );
 
-int set_nonblock_socket(int fd)
-{
-    int flags;
-    flags = fcntl(fd, F_GETFL);
-    flags |= O_NONBLOCK;
-    return fcntl(fd, F_SETFL, flags);
+  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 );
 }
 
-static void set_client_thread_cb (EV_P_ ev_async *w, int revents)
+/*
+=========================================================
+  set_nonblock_socket( )
+=========================================================
+*/
+int32_t set_nonblock_socket( int32_t fd )
 {
-    pthread_mutex_lock(&mutex_set_client_thread_cb);
+#ifdef _WIN32
+  unsigned long arg = 1;
+  return ioctlsocket( fd, FIONBIO, &arg );
+#else
+  int32_t flags;
 
-    int fd = DAP_EV_DATA(w)->client_fd;
+  flags = fcntl( fd, F_GETFL );
+  flags |= O_NONBLOCK;
+
+  return fcntl( fd, F_SETFL, flags );
+#endif
+}
 
-    struct ev_io* w_client = (struct ev_io*) malloc (sizeof(struct ev_io));
 
-    ev_io_init(w_client, read_write_cb, fd, EV_READ);
-    ev_io_set(w_client, fd, EV_READ  | EV_WRITE);
-    w_client->data = malloc(sizeof(ev_async_data_t));
+/*
+=========================================================
+  get_thread_min_connections( )
 
-    memcpy(w_client->data, w->data, sizeof(ev_async_data_t));
+  return number thread which has minimum open connections
+=========================================================
+*/
+static inline uint32_t get_thread_index_min_connections( )
+{
+  uint32_t min = 0;
 
-    dap_client_remote_create(_current_run_server, fd, w_client);
+//  for( uint32_t i = 1; i < _count_threads; i ++ ) {
 
-    ev_io_start(listener_clients_loops[DAP_EV_DATA(w)->thread_number], w_client);
+//    if ( atomic_load(&thread_inform[min].count_open_connections ) >
+//             atomic_load(&thread_inform[i].count_open_connections) ) {
+//      min = i;
+//    }
+//  }
 
-    pthread_mutex_unlock(&mutex_set_client_thread_cb);
+  return min;
 }
 
-static void read_write_cb (struct ev_loop* loop, struct ev_io* watcher, int revents)
+/*
+=========================================================
+  print_online( )
+
+=========================================================
+*/
+static inline void print_online()
 {
-    dap_client_remote_t* dap_cur = dap_client_remote_find(watcher->fd, _current_run_server);
-
-    if ( revents & EV_READ )
-    {
-    //    log_it(INFO, "socket read %d thread %d", watcher->fd, thread);
-        if(dap_cur)
-        {
-            ssize_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)
-            {
-                dap_cur->buf_in_size += (size_t)bytes_read;
-                dap_cur->upload_stat.buf_size_total += (size_t)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->signal_close = true;
-            }
-            else if (bytes_read == 0)
-            {
-                dap_cur->signal_close = true;
-            }
-        }
-    }
+//  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) );
+//  }
+}
 
-    if( ( (revents & EV_WRITE) || dap_cur->_ready_to_write ) &&
-            dap_cur->signal_close == false ) {
+/*
+=========================================================
+  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 );
 
-        _current_run_server->client_write_callback(dap_cur, NULL); // Call callback to process write event
+  if ( !dcr ) {
+    log_it( L_ERROR, "accept %d dap_client_remote_create() == NULL", fd );
+    return dcr;
+  }
 
-        if(dap_cur->buf_out_size == 0)
-        {
-            ev_io_set(watcher, watcher->fd, EV_READ);
-        }
-        else
-        {
-            size_t total_sent = dap_cur->buf_out_offset;
-            for(; 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,"Error occured in send() function %s", strerror(errno));
-                    break;
-                }
-                total_sent += (size_t)bytes_sent;
-                dap_cur->download_stat.buf_size_total += (size_t)bytes_sent;
-            }
-
-            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;
-            }
+  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 );
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
 
-    if(dap_cur->signal_close)
-    {
-        log_it(L_INFO, "Close Socket %d", watcher->fd);
+  if ( epoll_ctl( dsth->epoll_fd, EPOLL_CTL_ADD, fd, &dcr->pevent) != 0 ) {
+    log_it( L_ERROR, "epoll_ctl failed 005" );
+  }
 
-        atomic_fetch_sub(&thread_inform[DAP_EV_DATA(watcher)->thread_number].count_open_connections, 1);
-        ev_io_stop(listener_clients_loops[DAP_EV_DATA(watcher)->thread_number], watcher);
-        dap_client_remote_remove(dap_cur, _current_run_server);
-        free(watcher->data); free(watcher);
-        return;
-    }
+  return dcr;
 }
 
-/**
- * @brief get_thread_min_connections
- * @return number thread which has minimum open connections
- */
-static inline uint8_t get_thread_index_min_connections()
+/*
+=========================================================
+  dap_server_remove_socket( )
+
+=========================================================
+*/
+void  dap_server_remove_socket( dap_client_remote_t *dcr )
 {
-    uint8_t min = 0;
-    for(uint8_t i = 1; i < _count_threads; i++)
-    {
-        if (atomic_load(&thread_inform[min].count_open_connections) >
-             atomic_load(&thread_inform[i].count_open_connections))
-        {
-            min = i;
-        }
-    }
-    return min;
+  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 );
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
+
+  log_it( L_DEBUG, "dcr = %X", dcr );
 }
 
-static inline void print_online()
+static void s_socket_all_check_activity( uint32_t tn, time_t cur_time )
 {
-    for(uint8_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));
+  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 ( cur_time >= dcr->last_time_active + SOCKET_TIMEOUT_TIME  ) {
+
+      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 );
+      dap_client_remote_remove( dcr, _current_run_server );
     }
+  }
+  pthread_mutex_unlock( &dsth->mutex_dlist_add_remove );
 }
 
-static void accept_cb (struct ev_loop* loop, struct ev_io* watcher, int revents)
+/*
+=========================================================
+  read_write_cb( )
+
+=========================================================
+*/
+static void read_write_cb( dap_client_remote_t *dap_cur, int32_t revents )
 {
-    int client_fd = accept(watcher->fd, 0, 0);
-    if( client_fd < 0 ) {
-        log_it(L_ERROR, "error accept socket");
-        return;
+//  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->signal_close = true;
+    }
+    else { // bytes_read == 0
+      dap_cur->signal_close = true;
+      log_it( L_DEBUG, "0 bytes read" );
     }
+  }
 
-    log_it(L_INFO, "Client accept socket %d", client_fd);
-    set_nonblock_socket(client_fd);
+  if( ( (revents & EPOLLOUT) || dap_cur->_ready_to_write ) && dap_cur->signal_close == false ) {
 
-    uint8_t indx_min = get_thread_index_min_connections();
-    ev_async_data_t *ev_data = async_watchers[indx_min].data;
-    ev_data->client_fd = client_fd;
-    ev_data->thread_number = indx_min;
+//    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
 
-    atomic_fetch_add(&thread_inform[ev_data->thread_number].count_open_connections, 1);
+    if( dap_cur->buf_out_size == 0 ) {
+//      log_it(L_DEBUG, "dap_cur->buf_out_size = 0, set ev_read watcher " );
 
-    log_it(L_DEBUG, "Client send to thread %d", ev_data->thread_number);
-    if ( ev_async_pending(&async_watchers[ev_data->thread_number]) == false ) { //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
-        log_it(L_INFO, "ev_async_pending");
-        ev_async_send(listener_clients_loops[ev_data->thread_number], &async_watchers[ev_data->thread_number]); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
+      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 {
-        atomic_fetch_sub(&thread_inform[DAP_EV_DATA(watcher)->thread_number].count_open_connections, 1);
-        log_it(L_ERROR, "Ev async error pending");
-    }
+//      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->signal_close = true;
+          break;
+        }
+
+        total_sent += (size_t)bytes_sent;
+        dap_cur->download_stat.buf_size_total += (size_t)bytes_sent;
+      }
+
+      if( total_sent == dap_cur->buf_out_size ) {
+        dap_cur->buf_out_offset = dap_cur->buf_out_size  = 0;
+        //dap_cur->signal_close = true; // REMOVE ME!!!!!!!!!!!!!!11
+      }
+      else {
+        dap_cur->buf_out_offset = total_sent;
+      }
+    } // else
+  } // write
+
+  if ( dap_cur->signal_close ) {
+    log_it(L_ERROR,"Close signal" );
+
+    dap_server_remove_socket( dap_cur );
+    dap_client_remote_remove( dap_cur, _current_run_server );
+  }
+
 }
 
-/**
- * @brief server_listen Create server_t instance and start to listen tcp port with selected address
- * @param addr address
- * @param port port
- * @return
- */
-dap_server_t* dap_server_listen(const char * addr, uint16_t port, dap_server_type_t type)
+
+/*
+=========================================================
+  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();
+  dap_server_t* sh = dap_server_new( );
 
-    sh->socket_listener = -111;
+  sh->socket_listener = -111;
 
-    if(type == DAP_SERVER_TCP)
-        sh->socket_listener = socket (AF_INET, SOCK_STREAM, 0);
+  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 (-1 == set_nonblock_socket(sh->socket_listener)) {
-        log_it(L_WARNING,"error server socket nonblock");
-        exit(EXIT_FAILURE);
-    }
+  if ( sh->socket_listener < 0 ) {
+    log_it ( L_ERROR,"Socket error %s", strerror(errno) );
+    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..." );
 
-    log_it(L_NOTICE,"Socket created...");
+  int32_t reuse = 1;
 
-    int 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" );
 
-    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");
-#ifdef SO_REUSEPORT
-    if (setsockopt(sh->socket_listener, SOL_SOCKET, SO_REUSEPORT, (const char*)&reuse, sizeof(reuse)) < 0)
-        log_it(L_WARNING, "Can't set up REUSEPORT flag to the socket");
-#endif
+  sh->listener_addr.sin_family = AF_INET;
+  sh->listener_addr.sin_port = htons( port );
+  inet_pton( AF_INET, addr, &(sh->listener_addr.sin_addr) );
 
-    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;
-    }else {
-        log_it(L_INFO,"Binded %s:%u", addr, port);
-        listen(sh->socket_listener, 100000);
-        pthread_mutex_init(&sh->mutex_on_hash, NULL);
-        return sh;
-    }
+  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;
 }
 
-/**
- * @brief thread_loop
- * @param arg
- * @return
- */
-void* thread_loop(void * arg)
+
+/*
+=========================================================
+  thread_loop( )
+
+  Server listener thread loop
+=========================================================
+*/
+void  *thread_loop( void *arg )
 {
-    log_it(L_NOTICE, "Start loop listener socket thread %d", *(int*)arg);
+  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 );
 
-    cpu_set_t mask;
-    CPU_ZERO(&mask);
-    CPU_SET(*(int*)arg, &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 (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();
+  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  );
+
+    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_client_remote_t *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->signal_close = true;
+      }
+
+      if ( dap_cur->signal_close ) {
+        //log_it( L_INFO, "Got signal to close from the client %s", dap_cur->hostaddr );
+
+        dap_server_remove_socket( dap_cur );
+        dap_client_remote_remove( dap_cur, _current_run_server );
+        continue;
+      }
+
+      read_write_cb( dap_cur, events[i].events );
     }
 
-    ev_loop(listener_clients_loops[*(int*)arg], 0);
-    return NULL;
+    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;
+    }
+
+  } while( !bQuitSignal ); 
+
+  return NULL;
 }
 
-/**
- * @brief dap_server_loop Main server loop
- * @param a_server Server instance
- * @return Zero if ok others if not
- */
-int dap_server_loop(dap_server_t * a_server)
+/*
+=========================================================
+  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 )
 {
-    int thread_arg[_count_threads];
-    pthread_t thread_listener[_count_threads];
-    struct ev_loop * ev_main_loop = ev_default_loop(0);
-
-    if ( a_server ) {
-        for(size_t i = 0; i < _count_threads; i++)
-        {
-            thread_arg[i] = (int)i;
-            listener_clients_loops[i] = ev_loop_new(0);
-            async_watchers[i].data = a_server;
-            ev_async_init(&async_watchers[i], set_client_thread_cb);
-            ev_async_start(listener_clients_loops[i], &async_watchers[i]);
-            pthread_create(&thread_listener[i], NULL, thread_loop, &thread_arg[i]);
+  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( 1 ) {
+
+    int32_t n = epoll_wait( efd, &events[0], 16, -1 );
+
+    if ( n <= 0 ) {
+      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;
         }
-        _current_run_server = a_server;
-        struct ev_io w_accept; w_accept.data = a_server;
-        ev_io_init(&w_accept, accept_cb, a_server->socket_listener, EV_READ);
-        ev_io_start(ev_main_loop, &w_accept);
+
+        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
     }
-    ev_run(ev_main_loop, 0);
+  }
 
-    return 0;
+  return 0;
 }
diff --git a/dap_server.h b/dap_server.h
index efefac56754b3c1c880fa96d545d1a5b7a81c0d5..98f050c4dddcaea7b97ee0a1150c9ee0d3c8b4d8 100755
--- a/dap_server.h
+++ b/dap_server.h
@@ -17,60 +17,77 @@
     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 _DAP_SERVER_H_
-#define _DAP_SERVER_H_
-
+#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;
 
-struct dap_server;
+typedef struct dap_server_thread_s {
 
-typedef void (*dap_server_callback_t) (struct dap_server *,void * arg); // Callback for specific server's operations
+  EPOLL_HANDLE epoll_fd;
+  uint32_t thread_num;
+  uint32_t connections_count;
 
+  struct epoll_event  *epoll_events;
+  dap_client_remote_t *dap_remote_clients;
 
+  pthread_mutex_t mutex_dlist_add_remove;
 
-typedef struct dap_server{
-    dap_server_type_t type; // Server's type
-    uint16_t port; // Listen port
-    char * address; // Listen address
+} dap_server_thread_t;
 
-    dap_client_remote_t * clients; // Hashmap of clients
+struct dap_server;
 
-    int socket_listener; // Socket for listener
-    int epoll_fd; // Epoll fd
+typedef void (*dap_server_callback_t)( struct dap_server *,void * arg ); // Callback for specific server's operations
 
-    struct sockaddr_in listener_addr; // Kernel structure for listener's binded address
+typedef struct dap_server {
 
-    void * _inheritor;  // Pointer to the internal data, HTTP for example
+  dap_server_type_t type; // Server's type
+  uint16_t port; // Listen port
+  char *address; // Listen address
 
-    pthread_mutex_t mutex_on_hash;
+  dap_client_remote_t *clients; // Hashmap of clients
 
-    dap_cpu_stats_t cpu_stats;
+  int32_t socket_listener; // Socket for listener
+  EPOLL_HANDLE epoll_fd; // Epoll fd
 
-    dap_server_callback_t server_delete_callback;
+  struct sockaddr_in listener_addr; // Kernel structure for listener's binded address
 
-    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
+  void *_inheritor;  // Pointer to the internal data, HTTP for example
 
-} dap_server_t;
+  pthread_mutex_t mutex_on_hash;
+  dap_cpu_stats_t cpu_stats;
 
-int dap_server_init(size_t count_threads); // Init server module
-void dap_server_deinit(void); // Deinit server module
+  dap_server_callback_t server_delete_callback;
 
-dap_server_t* dap_server_listen(const char * addr, uint16_t port, dap_server_type_t type);
+  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
 
-int dap_server_loop(dap_server_t * sh);
+} dap_server_t;
 
-#endif
+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 );
diff --git a/dap_traffic_track.c b/dap_traffic_track.c
index db3b04b359b769a02718e0b6fbb89bb1568e999c..6024833c3552dece12d5cfeac8c8aa738c878c4b 100755
--- a/dap_traffic_track.c
+++ b/dap_traffic_track.c
@@ -22,155 +22,209 @@
     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"
 
-#include <pthread.h>
-
 #define LOG_TAG "dap_traffic_track"
-#define BITS_IN_BYTE 8
-#define ALLOC_STEP 100
+
+#define BITS_IN_BYTE    8
+#define ALLOC_STEP      100
 
 static dap_traffic_callback_t _callback = NULL;
-static dap_server_t * _dap_server;
+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)
+static double _calculate_mbits_speed( size_t count_bytes )
 {
-    size_t bits_per_second = (count_bytes / (size_t)_timeout_watcher.repeat) * 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 bits_per_second / 1000000.0; // convert to mbits
+  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 *_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);
+  (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;
     }
-    pthread_mutex_unlock(&_mutex);
-    pthread_exit(NULL);
+    _callback( _dap_server );
+  }
+
+  pthread_mutex_unlock( &_mutex );
+  pthread_exit( NULL );
+
+  return NULL;
 }
 
-void _worker_start()
+void _worker_start( )
 {
-    pthread_mutex_init(&_mutex, NULL);
-    pthread_cond_init(&_cond, NULL);
-    pthread_create(&worker_thread, NULL, _worker_run, NULL);
+  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);
+  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);
+  // wait for exit worker_thread
+  pthread_join( worker_thread, NULL );
 
-    pthread_mutex_destroy(&_mutex);
-    pthread_cond_destroy(&_cond);
-    _callback = NULL;
+  pthread_mutex_destroy( &_mutex );
+  pthread_cond_destroy( &_cond );
+  _callback = NULL;
 }
 
-static void _timeout_cb()
+#ifndef _WIN32
+static void _timeout_cb( )
+#else
+VOID CALLBACK _timeout_cb( void *lpParameter, BOOL TimerOrWaitFired )
+#endif
 {
-    pthread_mutex_lock(&_dap_server->mutex_on_hash);
+  pthread_mutex_lock( &_dap_server->mutex_on_hash );
+
+  size_t count_users = HASH_COUNT(_dap_server->clients );
 
-    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 ) {
 
-    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.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->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.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;
+      dap_cur->download_stat.buf_size_total_old = dap_cur->download_stat.buf_size_total;
 
-            idx++;
-        }
+//      idx ++;
     }
+  }
 
-    /* TODO find some better solution and place for this line */
-    _dap_server->cpu_stats = dap_cpu_get_stats();
+  /* 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);
+  pthread_mutex_unlock( &_dap_server->mutex_on_hash );
 
-    if(_callback != NULL) {
-        pthread_mutex_lock(&_mutex);
-        pthread_cond_signal(&_cond);
-        pthread_mutex_unlock(&_mutex);
-    }
+  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)
+void dap_traffic_track_init( dap_server_t * server,
+                            time_t timeout )
 {
-    dap_cpu_monitor_init();
-
-    _dap_server = server;
-    _timeout_watcher.repeat = timeout;
-    loop = EV_DEFAULT;
-    ev_init(&_timeout_watcher, _timeout_cb);
-    ev_timer_again (loop, &_timeout_watcher);
-    log_it(L_NOTICE, "Initialized traffic track module");
+  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();
+  if ( _callback != NULL )
+    _worker_stop();
 
-    ev_timer_stop(loop, &_timeout_watcher);
-    ev_loop_destroy(loop);
-    log_it(L_NOTICE, "Deinitialized traffic track module");
-    dap_cpu_monitor_deinit();
+#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();
+
+  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;
-    }
+  if( _callback == NULL ) {
+    _callback = cb;
+    _worker_start();
+    return;
+  }
 
-    log_it(L_WARNING, "Callback already setted");
+  log_it( L_WARNING, "Callback already setted" );
 }
diff --git a/dap_traffic_track.h b/dap_traffic_track.h
index f2dd83caad14deb0bee21e33b5b38b099f16f9d6..1cfae9d22689621d0c99a746f96d07a9321543a3 100755
--- a/dap_traffic_track.h
+++ b/dap_traffic_track.h
@@ -23,28 +23,28 @@
 */
 
 #pragma once
+
 #include "dap_client_remote.h"
 #include "dap_server.h"
 
-typedef void (*dap_traffic_callback_t) (dap_server_t*);
+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);
+void dap_traffic_track_init( dap_server_t *server, time_t timeout );
 
 /**
  * @brief dap_traffic_track_deinit
  */
-void dap_traffic_track_deinit(void);
+void dap_traffic_track_deinit( void );
 
 /**
  * @brief dap_traffic_add_callback
  */
-void dap_traffic_callback_set(dap_traffic_callback_t);
+void dap_traffic_callback_set( dap_traffic_callback_t );
 
-void dap_traffic_callback_stop(void);
+void dap_traffic_callback_stop( void );
 
diff --git a/test/main.c b/test/main.c
index bb9cdaf686733f569532d2f8a803b90589853f6d..8a591c1b73cf69d323131cdc3271745a2f8c1d86 100755
--- a/test/main.c
+++ b/test/main.c
@@ -3,7 +3,7 @@
 
 int main(void) {
     // switch off debug info from library
-    set_log_level(L_CRITICAL);
-    dap_traffic_track_tests_run();
+//    set_log_level(L_CRITICAL);
+//    dap_traffic_track_tests_run();
     return 0;
 }