{$ifdef VER1_0}\r
     linux,\r
   {$else}\r
-    baseunix,unix,unixutil,\r
+    baseunix,unix,unixutil,sockets,\r
   {$endif}\r
   fd_utils;\r
 var\r
   {$ifndef nosignal}\r
     lsignal,\r
   {$endif}\r
-  ltimevalstuff;
+  ltimevalstuff;\r
 \r
 {$include unixstuff.inc}\r
 \r
 const\r
-  absoloutemaxs_select = (sizeof(fdset)*8)-1;\r
+  absolutemaxs_select = (sizeof(fdset)*8)-1;\r
 \r
 var\r
-  fdreverse:array[0..absoloutemaxs_select] of tlasio;\r
+  fdreverse:array[0..absolutemaxs_select] of tlasio;\r
 type\r
   tselecteventcore=class(teventcore)\r
     public\r
 \r
 procedure processtimers;inline;\r
 var\r
-  tv           ,tvnow     : ttimeval ;\r
+  tvnow     : ttimeval ;\r
   currenttimer            : tltimer   ;\r
   temptimer               : tltimer  ;\r
 \r
 begin\r
-  gettimeofday(tvnow);\r
+  gettimemonotonic(tvnow);\r
   currenttimer := firsttimer;\r
   while assigned(currenttimer) do begin\r
     //writeln(currenttimer.enabled);\r
 procedure processasios(var fdsr,fdsw:fdset);//inline;\r
 var\r
   currentsocket : tlasio  ;\r
-  tempsocket    : tlasio  ;\r
-  socketcount   : integer ; // for debugging perposes :)\r
+  socketcount   : integer ; // for debugging purposes :)\r
   dw,bt:integer;\r
+  currentfdword:fdword;\r
+  fd : integer;\r
 begin\r
+  //writeln('entering processasios');\r
 {  inc(lcoretestcount);}\r
 \r
-    //the message loop will exit if all lasio's and ltimer's and lsignal's are destroyed\r
+    //the message loop will exit if all lasios and ltimers and lsignals are destroyed\r
     //if (not assigned(firstasin)) and (not assigned(firsttimer)) and (not assigned(firstsignal)) then exit;\r
 \r
 \r
   {------- test optimised loop}\r
   socketcount := 0;\r
-  for dw := (maxs shr 5) downto 0 do if (fdsr[dw] or fdsw[dw]) <> 0 then begin\r
-    for bt := 0 to 31 do if (fdsr[dw] or fdsw[dw]) and (1 shl bt) <> 0 then begin\r
+  for dw := (maxs shr fdwordshift) downto 0 do if (fdsr[dw] or fdsw[dw]) <> 0 then begin\r
+    currentfdword := (fdsr[dw] or fdsw[dw]);\r
+    for bt := fdwordmaxbit downto 0 do if currentfdword and (1 shl bt) <> 0 then begin\r
       inc(socketcount);\r
-      currentsocket := fdreverse[dw shl 5 or bt];\r
+      fd := dw shl fdwordshift or bt;\r
+      //writeln('reversing fd ',fd);\r
+      currentsocket := fdreverse[fd];\r
       {if not assigned(currentsocket) then raise exception.create('currentsocket not assigned');\r
       if currentsocket.fdhandlein < 0 then raise exception.create('currentsocket.fdhandlein out of range');}\r
       {i've seen the out of range case actually happening, so it can happen. test: just close the fd - beware}\r
       if not assigned(currentsocket) then begin\r
-        fdclose(dw shl 5 or bt);\r
+        fdclose(fd);\r
         continue\r
       end;\r
       if currentsocket.fdhandlein < 0 then begin\r
-        fdclose(dw shl 5 or bt);\r
+        fdclose(fd);\r
         continue\r
       end;\r
       try\r
-        currentsocket.handlefdtrigger(fd_isset(currentsocket.fdhandlein,fdsr),fd_isset(currentsocket.fdhandleout,fdsw));\r
+        currentsocket.handlefdtrigger(fd_isset(fd,fdsr),fd_isset(fd,fdsw));\r
       except\r
         on E: exception do begin\r
           currentsocket.HandleBackGroundException(e);\r
   - sockets which are released may not be freed because theyre never processed by the loop\r
   made new code for handling this, using asinreleaseflag\r
 \r
-  - when/why does the mustrefreshfds select apply, sheck if i did it correctly?\r
+  - when/why does the mustrefreshfds select apply, check if i did it correctly?\r
 \r
   - what happens if calling handlefdtrigger for a socket which does not have an event\r
   }\r
     end;\r
   end; *)\r
 {  debugout('socketcount='+inttostr(socketcount));}\r
+  //writeln('leaving processasios');\r
 end;\r
 \r
 procedure tselecteventcore.processmessages;\r
     prepsigpipe;\r
   {$endif}\r
   selectresult := select(maxs+1,@fdsr,@fdsw,nil,0);\r
-  while (selectresult>0) or assigned(firsttask) or assigned(currenttask) do begin;\r
+  while (selectresult>0) or assigned(firsttask) do begin;\r
 \r
     processtasks;\r
     processtimers;\r
 end;\r
 \r
 \r
+{\r
+select in linux/sysV subtracts from timeout for time spent in it, but in BSD it doesn't\r
+enabling select_no_autotv here makes doSelect mimic the decrement behavior, in case the caller needs it\r
+the caller here in lcoreselect does not need it, and enabling it would have a slight perf hit.\r
+it is safe for this to be enabled even if the OS does it too (it will not subtract twice)\r
+it is currently disabled but can be enabled if needed\r
+}\r
+{$ifndef linux}{-$define select_no_autotv}{$endif}\r
+\r
 Function  doSelect(timeOut:PTimeVal):longint;//inline;\r
 var\r
   localtimeval : ttimeval;\r
   maxslocal    : integer;\r
+  {$ifdef select_no_autotv}\r
+  timeoutcopy,tvstart,tvend : ttimeval;\r
+  {$endif}\r
 begin\r
   //unblock signals\r
   //zeromemory(@sset,sizeof(sset));\r
   {$ifndef nosignal}\r
     sigprocmask(SIG_UNBLOCK,@blockset,nil);\r
   {$endif}\r
+\r
+  {$ifdef select_no_autotv}\r
+  if assigned(timeout) then begin\r
+    timeoutcopy.tv_sec := timeOut.tv_sec;\r
+    timeoutcopy.tv_usec := timeOut.tv_usec;\r
+    gettimemonotonic(tvstart);\r
+  end;\r
+  {$endif}\r
+\r
   result := select(maxslocal+1,@FDSR,@FDSW,nil,timeout);\r
   if result <= 0 then begin\r
     fd_zero(FDSR);\r
     fd_zero(FDSW);\r
     if result=-1 then begin\r
       if linuxerror = SYS_EINTR then begin\r
-        // we received a signal it's not a problem\r
+        // we received a signal it is not a problem\r
       end else begin\r
         raise esocketexception.create('select returned error '+inttostr(linuxerror));\r
       end;\r
+    end\r
+  {$ifdef select_no_autotv}\r
+    else if (result = 0) and assigned(timeout) then begin\r
+      //timeout reached: zero the timeval\r
+      timeout.tv_sec := 0;\r
+      timeout.tv_usec := 0;\r
     end;\r
+  end else if assigned(timeout) then begin\r
+    //successful result: subtract elapsed time\r
+    gettimemonotonic(tvend);\r
+    tv_subtract(tvend,tvstart);\r
+    tv_subtract(timeoutcopy,tvend);\r
+    timeout.tv_sec := timeoutcopy.tv_sec;\r
+    timeout.tv_usec := timeoutcopy.tv_usec;\r
+    if (timeout.tv_sec < 0) then begin\r
+      timeout.tv_sec := 0;\r
+      timeout.tv_usec := 0;\r
+    end;\r
+  {$endif} //select_no_autotv\r
   end;\r
+\r
   {$ifndef nosignal}\r
     sigprocmask(SIG_BLOCK,@blockset,nil);\r
   {$endif}\r
 \r
   repeat\r
 \r
-    //the message loop will exit if all lasio's and ltimer's and lsignal's are destroyed\r
+    //the message loop will exit if all lasios and ltimers and lsignals are destroyed\r
     processtasks;\r
     //currenttask := nil;\r
     {beware}\r
       selectresult := doselect(nil);\r
 \r
     end else begin\r
-      gettimeofday(tvnow);\r
-      tv_substract(tv,tvnow);\r
+      gettimemonotonic(tvnow);\r
+      tv_subtract(tv,tvnow);\r
 \r
       //writeln('timers active');\r
       if tv.tv_sec < 0 then begin\r
 \r
 procedure tselecteventcore.rmasterset(fd : integer;islistensocket : boolean);\r
 begin\r
-  if fd > absoloutemaxs then raise esocketexception.create('file discriptor out of range');\r
+  //writeln('rmasterset called with fd ',fd);\r
+  if fd > absolutemaxs then raise esocketexception.create('file descriptor out of range');\r
   if fd > maxs then maxs := fd;\r
   if fd_isset(fd,fdsrmaster) then exit;\r
   fd_set(fd,fdsrmaster);\r
 \r
 procedure tselecteventcore.rmasterclr(fd: integer);\r
 begin\r
+  //writeln('rmasterclr called with fd ',fd);\r
   if not fd_isset(fd,fdsrmaster) then exit;\r
   fd_clr(fd,fdsrmaster);\r
 \r
 \r
 procedure tselecteventcore.wmasterset(fd : integer);\r
 begin\r
-  if fd > absoloutemaxs then raise esocketexception.create('file discriptor out of range');\r
+  //writeln('wmasterset called with fd ',fd);\r
+  if fd > absolutemaxs then raise esocketexception.create('file descriptor out of range');\r
   if fd > maxs then maxs := fd;\r
 \r
   if fd_isset(fd,fdswmaster) then exit;\r
 \r
 procedure tselecteventcore.wmasterclr(fd: integer);\r
 begin\r
+  //writeln('wmasterclr called with fd ',fd);\r
   if not fd_isset(fd,fdswmaster) then exit;\r
   fd_clr(fd,fdswmaster);\r
 end;\r
   inited := true;\r
   eventcore := tselecteventcore.create;\r
 \r
-  absoloutemaxs := absoloutemaxs_select;\r
+  absolutemaxs := absolutemaxs_select;\r
 \r
   maxs := 0;\r
   fd_zero(fdsrmaster);\r