X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/6cb6b7ede2d178e03fa817bc28474c175f5a93b9..42a61c59a81b03130f61e805474198eada033cd8:/httpserver_20080306/lcoreselect.pas?ds=sidebyside diff --git a/httpserver_20080306/lcoreselect.pas b/httpserver_20080306/lcoreselect.pas deleted file mode 100755 index 0369448..0000000 --- a/httpserver_20080306/lcoreselect.pas +++ /dev/null @@ -1,391 +0,0 @@ -{lsocket.pas} - -{io and timer code by plugwash} - -{ Copyright (C) 2005 Bas Steendijk and Peter Green - For conditions of distribution and use, see copyright notice in zlib_license.txt - which is included in the package - ----------------------------------------------------------------------------- } - - -unit lcoreselect; - - -interface -uses - fd_utils; -var - maxs : longint ; - exitloopflag : boolean ; {if set by app, exit mainloop} - -function getfdsrmaster : fdset; {$ifdef fpc}inline;{$endif} -function getfdswmaster : fdset; {$ifdef fpc}inline;{$endif} - -implementation -uses - lcore,sysutils, - {$ifdef VER1_0} - linux, - {$else} - baseunix,unix, - {$endif} - classes,pgtypes,bfifo, - {$ifndef nosignal} - lsignal; - {$endif} - -{$include unixstuff.inc} -{$include ltimevalstuff.inc} -var - fdreverse:array[0..absoloutemaxs] of tlasio; -type - tselecteventcore=class(teventcore) - public - procedure processmessages; override; - procedure messageloop; override; - procedure exitmessageloop;override; - procedure setfdreverse(fd : integer;reverseto : tlasio); override; - procedure rmasterset(fd : integer;islistensocket : boolean); override; - procedure rmasterclr(fd: integer); override; - procedure wmasterset(fd : integer); override; - procedure wmasterclr(fd: integer); override; - end; - -procedure processtimers;inline; -var - tv ,tvnow : ttimeval ; - currenttimer : tltimer ; - temptimer : tltimer ; - -begin - gettimeofday(tvnow); - currenttimer := firsttimer; - while assigned(currenttimer) do begin - //writeln(currenttimer.enabled); - if tv_compare(tvnow,ttimeval(currenttimer.nextts)) and currenttimer.enabled then begin - //if assigned(currenttimer.ontimer) then begin - // if currenttimer.enabled then if currenttimer.initialevent or currenttimer.initialdone then currenttimer.ontimer(currenttimer); - // currenttimer.initialdone := true; - //end; - if assigned(currenttimer.ontimer) then currenttimer.ontimer(currenttimer); - currenttimer.nextts := timeval(tvnow); - tv_add(ttimeval(currenttimer.nextts),currenttimer.interval); - end; - temptimer := currenttimer; - currenttimer := currenttimer.nexttimer; - if temptimer.released then temptimer.free; - end; -end; - -procedure processasios(var fdsr,fdsw:fdset);//inline; -var - currentsocket : tlasio ; - tempsocket : tlasio ; - socketcount : integer ; // for debugging perposes :) - dw,bt:integer; -begin -{ inc(lcoretestcount);} - - //the message loop will exit if all lasio's and ltimer's and lsignal's are destroyed - //if (not assigned(firstasin)) and (not assigned(firsttimer)) and (not assigned(firstsignal)) then exit; - - - {------- test optimised loop} - socketcount := 0; - for dw := (maxs shr 5) downto 0 do if (fdsr[dw] or fdsw[dw]) <> 0 then begin - for bt := 0 to 31 do if (fdsr[dw] or fdsw[dw]) and (1 shl bt) <> 0 then begin - inc(socketcount); - currentsocket := fdreverse[dw shl 5 or bt]; - {if not assigned(currentsocket) then raise exception.create('currentsocket not assigned'); - if currentsocket.fdhandlein < 0 then raise exception.create('currentsocket.fdhandlein out of range');} - {i've seen the out of range case actually happening, so it can happen. test: just close the fd - beware} - if not assigned(currentsocket) then begin - fdclose(dw shl 5 or bt); - continue - end; - if currentsocket.fdhandlein < 0 then begin - fdclose(dw shl 5 or bt); - continue - end; - try - currentsocket.handlefdtrigger(fd_isset(currentsocket.fdhandlein,fdsr),fd_isset(currentsocket.fdhandleout,fdsw)); - except - on E: exception do begin - currentsocket.HandleBackGroundException(e); - end; - end; - - if mustrefreshfds then begin - if select(maxs+1,@fdsr,@fdsw,nil,0) <= 0 then begin - fd_zero(fdsr); - fd_zero(fdsw); - end; - end; - end; - end; - - if asinreleaseflag then begin - asinreleaseflag := false; - currentsocket := firstasin; - while assigned(currentsocket) do begin - tempsocket := currentsocket; - currentsocket := currentsocket.nextasin; - if tempsocket.released then begin - tempsocket.free; - end; - end; - end; - { - !!! issues: - - sockets which are released may not be freed because theyre never processed by the loop - made new code for handling this, using asinreleaseflag - - - when/why does the mustrefreshfds select apply, sheck if i did it correctly? - - - what happens if calling handlefdtrigger for a socket which does not have an event - } - {------- original loop} - - (* - currentsocket := firstasin; - socketcount := 0; - while assigned(currentsocket) do begin - if mustrefreshfds then begin - if select(maxs,@fdsr,@fdsw,nil,0) <= 0 then begin - fd_zero(fdsr); - fd_zero(fdsw); - end; - end; - try - if fd_isset(currentsocket.fdhandlein,fdsr) or fd_isset(currentsocket.fdhandleout,fdsw) then begin - currentsocket.handlefdtrigger(fd_isset(currentsocket.fdhandlein,fdsr),fd_isset(currentsocket.fdhandleout,fdsw)); - end; - except - on E: exception do begin - currentsocket.HandleBackGroundException(e); - end; - end; - tempsocket := currentsocket; - currentsocket := currentsocket.nextasin; - inc(socketcount); - if tempsocket.released then begin - tempsocket.free; - end; - end; *) -{ debugout('socketcount='+inttostr(socketcount));} -end; - -procedure tselecteventcore.processmessages; -var - fdsr , fdsw : fdset ; - selectresult : longint ; -begin - mustrefreshfds := false; - {$ifndef nosignal} - prepsigpipe; - {$endif} - selectresult := select(maxs+1,@fdsr,@fdsw,nil,0); - while (selectresult>0) or assigned(firsttask) or assigned(currenttask) do begin; - - processtasks; - processtimers; - if selectresult > 0 then begin - processasios(fdsr,fdsw); - end; - selectresult := select(maxs+1,@fdsr,@fdsw,nil,0); - - end; - mustrefreshfds := true; -end; - - -var - FDSR , FDSW : fdset; - -Function doSelect(timeOut:PTimeVal):longint;//inline; -var - localtimeval : ttimeval; - maxslocal : integer; -begin - //unblock signals - //zeromemory(@sset,sizeof(sset)); - //sset[0] := ; - fdsr := getfdsrmaster; - fdsw := getfdswmaster; - - if assigned(firsttask) then begin - localtimeval.tv_sec := 0; - localtimeval.tv_usec := 0; - timeout := @localtimeval; - end; - - maxslocal := maxs; - mustrefreshfds := false; -{ debugout('about to call select');} - {$ifndef nosignal} - sigprocmask(SIG_UNBLOCK,@blockset,nil); - {$endif} - result := select(maxslocal+1,@FDSR,@FDSW,nil,timeout); - if result <= 0 then begin - fd_zero(FDSR); - fd_zero(FDSW); - if result=-1 then begin - if linuxerror = SYS_EINTR then begin - // we received a signal it's not a problem - end else begin - raise esocketexception.create('select returned error '+inttostr(linuxerror)); - end; - end; - end; - {$ifndef nosignal} - sigprocmask(SIG_BLOCK,@blockset,nil); - {$endif} -{ debugout('select complete');} -end; - -procedure tselecteventcore.exitmessageloop; -begin - exitloopflag := true -end; - - - -procedure tselecteventcore.messageloop; -var - tv ,tvnow : ttimeval ; - currenttimer : tltimer ; - selectresult:integer; -begin - {$ifndef nosignal} - prepsigpipe; - {$endif} - {currentsocket := firstasin; - if not assigned(currentsocket) then exit; //the message loop will exit if all lsockets are destroyed - repeat - - if currentsocket.state = wsconnected then currentsocket.sendflush; - currentsocket := currentsocket.nextasin; - until not assigned(currentsocket);} - - - repeat - - //the message loop will exit if all lasio's and ltimer's and lsignal's are destroyed - if (not assigned(firstasin)) and (not assigned(firsttimer)) {$ifndef nosignal} and (not assigned(firstsignal)){$endif} then exit; - {fd_zero(FDSR); - fd_zero(FDSW); - currentsocket := firstasin; - if not assigned(currentsocket) then exit; //the message loop will exit if all lsockets are destroyed - - repeat - if (not currentsocket.released) and (currentsocket.state<>wsclosed) then fd_set(currentsocket.fdhandlein,fdsr); - if (not currentsocket.released) and (currentsocket.state=wsconnecting) then fd_set(currentsocket.fdhandleout,fdsw); - if currentsocket is tlsocket then begin - if (not currentsocket.released) and (currentsocket.state=wsconnected) and(tlsocket(currentsocket).sendq <> '') then fd_set(currentsocket.fdhandleout,fdsw); - end; - tempsocket := currentsocket; - currentsocket := currentsocket.nextasin; - if tempsocket.released then begin - tempsocket.free; - end; - until not assigned(currentsocket); - } - processtasks; - //currenttask := nil; - {beware} - //if assigned(firsttimer) then begin - // tv.tv_sec := maxlongint; - tv := tv_invalidtimebig; - currenttimer := firsttimer; - while assigned(currenttimer) do begin - if tv_compare(tv,currenttimer.nextts) and currenttimer.enabled then tv := currenttimer.nextts; - currenttimer := currenttimer.nexttimer; - end; - - - if tv_compare(tv,tv_invalidtimebig) then begin - //writeln('no timers active'); - if exitloopflag then break; -{ sleep(10);} - selectresult := doselect(nil); - - end else begin - gettimeofday(tvnow); - tv_substract(tv,tvnow); - - //writeln('timers active'); - if tv.tv_sec < 0 then begin - tv.tv_sec := 0; - tv.tv_usec := 0; {0.1 sec} - end; - if exitloopflag then break; -{ sleep(10);} - selectresult := doselect(@tv); - processtimers; - - end; - if selectresult > 0 then processasios(fdsr,fdsw); - {!!!only call processasios if select has asio events -beware} - - {artificial delay to throttle the number of processasios per second possible and reduce cpu usage} - until false; -end; - -var - fdsrmaster , fdswmaster : fdset ; - -procedure tselecteventcore.rmasterset(fd : integer;islistensocket : boolean); -begin - if fd > absoloutemaxs then raise esocketexception.create('file discriptor out of range'); - if fd > maxs then maxs := fd; - if fd_isset(fd,fdsrmaster) then exit; - fd_set(fd,fdsrmaster); - -end; - -procedure tselecteventcore.rmasterclr(fd: integer); -begin - if not fd_isset(fd,fdsrmaster) then exit; - fd_clr(fd,fdsrmaster); - -end; - - -procedure tselecteventcore.wmasterset(fd : integer); -begin - if fd > absoloutemaxs then raise esocketexception.create('file discriptor out of range'); - if fd > maxs then maxs := fd; - - if fd_isset(fd,fdswmaster) then exit; - fd_set(fd,fdswmaster); - -end; - -procedure tselecteventcore.wmasterclr(fd: integer); -begin - if not fd_isset(fd,fdswmaster) then exit; - fd_clr(fd,fdswmaster); -end; - -procedure tselecteventcore.setfdreverse(fd : integer;reverseto : tlasio); -begin - fdreverse[fd] := reverseto; -end; - -function getfdsrmaster : fdset; {$ifdef fpc}inline;{$endif} -begin - result := fdsrmaster; -end; -function getfdswmaster : fdset; {$ifdef fpc}inline;{$endif} -begin - result := fdswmaster; -end; - - -begin - eventcore := tselecteventcore.create; - - maxs := 0; - fd_zero(fdsrmaster); - fd_zero(fdswmaster); -end.