fix slow send speed, new fifo allows get of entire buffer
[lcore.git] / lcoreselect.pas
old mode 100755 (executable)
new mode 100644 (file)
index 0d99f6a..ad81600
@@ -21,7 +21,7 @@ uses
   {$ifdef VER1_0}\r
     linux,\r
   {$else}\r
-    baseunix,unix,unixutil,\r
+    baseunix,unix,unixutil,sockets,\r
   {$endif}\r
   fd_utils;\r
 var\r
@@ -31,22 +31,24 @@ var
 function getfdsrmaster : fdset; {$ifdef useinline}inline;{$endif}\r
 function getfdswmaster : fdset; {$ifdef useinline}inline;{$endif}\r
 \r
+procedure lcoreinit;\r
+\r
 implementation\r
 uses\r
   lcore,sysutils,\r
   classes,pgtypes,bfifo,\r
   {$ifndef nosignal}\r
-    lsignal;\r
+    lsignal,\r
   {$endif}\r
+  ltimevalstuff;\r
 \r
 {$include unixstuff.inc}\r
-{$include ltimevalstuff.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
@@ -62,12 +64,12 @@ type
 \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
@@ -82,42 +84,46 @@ begin
     end;\r
     temptimer := currenttimer;\r
     currenttimer := currenttimer.nexttimer;\r
-    if temptimer.released then temptimer.free;\r
   end;\r
 end;\r
 \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
@@ -133,23 +139,12 @@ begin
     end;\r
   end;\r
 \r
-  if asinreleaseflag then begin\r
-    asinreleaseflag := false;\r
-    currentsocket := firstasin;\r
-    while assigned(currentsocket) do begin\r
-      tempsocket := currentsocket;\r
-      currentsocket := currentsocket.nextasin;\r
-      if tempsocket.released then begin\r
-        tempsocket.free;\r
-      end;\r
-    end;\r
-  end;\r
   {\r
   !!! issues:\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
@@ -182,6 +177,7 @@ begin
     end;\r
   end; *)\r
 {  debugout('socketcount='+inttostr(socketcount));}\r
+  //writeln('leaving processasios');\r
 end;\r
 \r
 procedure tselecteventcore.processmessages;\r
@@ -194,7 +190,7 @@ begin
     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
@@ -253,7 +249,7 @@ begin
     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
@@ -292,26 +288,7 @@ begin
 \r
   repeat\r
 \r
-    //the message loop will exit if all lasio's and ltimer's and lsignal's are destroyed\r
-    if (not assigned(firstasin)) and (not assigned(firsttimer)) {$ifndef nosignal} and (not assigned(firstsignal)){$endif} then exit;\r
-    {fd_zero(FDSR);\r
-    fd_zero(FDSW);\r
-    currentsocket := firstasin;\r
-    if not assigned(currentsocket) then exit; //the message loop will exit if all lsockets are destroyed\r
-\r
-    repeat\r
-      if (not currentsocket.released) and (currentsocket.state<>wsclosed) then fd_set(currentsocket.fdhandlein,fdsr);\r
-      if (not currentsocket.released) and (currentsocket.state=wsconnecting) then fd_set(currentsocket.fdhandleout,fdsw);\r
-      if currentsocket is tlsocket then begin\r
-         if (not currentsocket.released) and (currentsocket.state=wsconnected) and(tlsocket(currentsocket).sendq <> '') then fd_set(currentsocket.fdhandleout,fdsw);\r
-      end;\r
-      tempsocket := currentsocket;\r
-      currentsocket := currentsocket.nextasin;\r
-      if tempsocket.released then begin\r
-        tempsocket.free;\r
-      end;\r
-    until not assigned(currentsocket);\r
-    }\r
+    //the message loop will exit if all lasios and ltimers and lsignals are destroyed\r
     processtasks;\r
     //currenttask := nil;\r
     {beware}\r
@@ -332,8 +309,8 @@ begin
       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
@@ -356,7 +333,8 @@ end;
 \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
@@ -365,6 +343,7 @@ end;
 \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
@@ -373,7 +352,8 @@ end;
 \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
@@ -383,6 +363,7 @@ end;
 \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
@@ -392,14 +373,20 @@ begin
   fdreverse[fd] := reverseto;\r
 end;\r
 \r
+var\r
+  inited:boolean;\r
 \r
-\r
+procedure lcoreinit;\r
 begin\r
+  if inited then exit;\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
   fd_zero(fdswmaster);\r
+end;\r
+\r
 end.\r