\r
\r
const\r
- receivebufsize=1460;\r
+ {how this number is made up:\r
+ - ethernet: MTU 1500\r
+ - be safe for either "ethernet v1" or "PPPoE", both take 8 bytes\r
+ - IPv6 header: 40 bytes (IPv4 is 20)\r
+ - TCP/UDP header: 20 bytes\r
+ }\r
+ packetbasesize = 1432;\r
+ receivebufsize=packetbasesize*8;\r
+\r
+ var\r
+ absoloutemaxs:integer=0;\r
\r
type\r
{$ifdef ver1_0}\r
onfdwrite : procedure (Sender: TObject; Error: word) of object; //added for bewarehttpd\r
lasterror:integer;\r
destroying:boolean;\r
+ recvbufsize:integer;\r
function receivestr:string; virtual;\r
procedure close;\r
procedure abort;\r
\r
//procedure messageloop;\r
function Receive(Buf:Pointer;BufSize:integer):integer; virtual;\r
- procedure flush;virtual;{$ifdef win32} abstract;{$endif}\r
+ procedure flush;virtual;\r
procedure dodatasent(wparam,lparam:longint);\r
procedure doreceiveloop(wparam,lparam:longint);\r
procedure sinkdata(sender:tobject;error:word);\r
constructor tlasio.create;\r
begin\r
inherited create(AOwner);\r
+ if not assigned(eventcore) then raise exception.create('no event core');\r
sendq := tfifo.create;\r
recvq := tfifo.create;\r
state := wsclosed;\r
if nextasin <> nil then begin\r
nextasin.prevasin := prevasin;\r
end;\r
- recvq.destroy;\r
- sendq.destroy;\r
+ recvq.free;\r
+ sendq.free;\r
inherited destroy;\r
end;\r
\r
\r
procedure tlasio.internalclose(error:word);\r
begin\r
- if state<>wsclosed then begin\r
+ if (state<>wsclosed) and (state<>wsinvalidstate) then begin\r
if (fdhandlein < 0) or (fdhandleout < 0) then raise exception.create('internalclose called with invalid fd handles');\r
eventcore.rmasterclr(fdhandlein);//fd_clr(fdhandlein,fdsrmaster);\r
eventcore.wmasterclr(fdhandleout);//fd_clr(fdhandleout,fdswmaster);\r
\r
if assigned(onsessionclosed) then if not destroying then onsessionclosed(self,error);\r
end;\r
- sendq.del(maxlongint);\r
+ if assigned(sendq) then sendq.del(maxlongint);\r
end;\r
\r
\r
begin\r
if state <> wsconnected then exit;\r
\r
- lensent := sendq.get(data,2920);\r
+ lensent := sendq.get(data,packetbasesize*2);\r
if assigned(data) then result := myfdwrite(fdhandleout,data^,lensent) else result := 0;\r
\r
if result = -1 then lensent := 0 else lensent := result;\r
var\r
sendflushresult : integer;\r
tempbuf:array[0..receivebufsize-1] of byte;\r
+ a:integer;\r
begin\r
if (state=wsconnected) and writetrigger then begin\r
//writeln('write trigger');\r
internalclose(0);\r
\r
end else begin\r
- internalclose({$ifdef win32}getlasterror{$else}linuxerror{$endif});\r
+ {$ifdef win32}
+ if getlasterror=WSAEWOULDBLOCK then begin
+ //the asynchronous nature of windows messages means we sometimes
+ //get here with the buffer full
+ //so do nothing in that case
+ end else
+ {$endif}
+ begin
+ internalclose({$ifdef win32}getlasterror{$else}linuxerror{$endif});\r
+ end
end;\r
end;\r
\r
writtenthiscycle := false;\r
if (state =wsconnected) and readtrigger then begin\r
if recvq.size=0 then begin\r
- numread := myfdread(fdhandlein,tempbuf,sizeof(tempbuf));\r
+ a := recvbufsize;\r
+ if (a <= 0) or (a > sizeof(tempbuf)) then a := sizeof(tempbuf);\r
+ numread := myfdread(fdhandlein,tempbuf,a);\r
if (numread=0) and (not mustrefreshfds) then begin\r
{if i remember correctly numread=0 is caused by eof\r
if this isn't dealt with then you get a cpu eating infinite loop\r
end;\r
end;\r
\r
-{$ifndef win32}\r
- procedure tlasio.flush;\r
- var\r
- fds : fdset;\r
- begin\r
- fd_zero(fds);\r
- fd_set(fdhandleout,fds);\r
- while sendq.size>0 do begin\r
- select(fdhandleout+1,nil,@fds,nil,nil);\r
- if sendflush <= 0 then exit;\r
- end;\r
- end;\r
+procedure tlasio.flush;\r
+{$ifdef win32}\r
+type fdset = tfdset;\r
{$endif}\r
+var\r
+ fds : fdset;\r
+begin\r
+ fd_zero(fds);\r
+ fd_set(fdhandleout,fds);\r
+ while sendq.size>0 do begin\r
+ select(fdhandleout+1,nil,@fds,nil,nil);\r
+ if sendflush <= 0 then exit;\r
+ end;\r
+end;\r
\r
procedure tlasio.dodatasent(wparam,lparam:longint);\r
begin\r