Browse Source

* Destroying a line reader or write buffer now works within an event
handler of these classes

sg 21 years ago
parent
commit
0675164195
1 changed files with 55 additions and 17 deletions
  1. 55 17
      fcl/inc/fpasync.pp

+ 55 - 17
fcl/inc/fpasync.pp

@@ -100,7 +100,7 @@ type
     RealBuffer, FBuffer: PChar;
     RealBuffer, FBuffer: PChar;
     FBytesInBuffer: Integer;
     FBytesInBuffer: Integer;
     FOnLine: TLineNotify;
     FOnLine: TLineNotify;
-    DoStopAndFree: Boolean;
+    InCallback, DoStopAndFree: Boolean;
 
 
     function  Read(var ABuffer; count: Integer): Integer; virtual; abstract;
     function  Read(var ABuffer; count: Integer): Integer; virtual; abstract;
     procedure NoData; virtual; abstract;
     procedure NoData; virtual; abstract;
@@ -150,6 +150,7 @@ type
     FBufferSent: Boolean;
     FBufferSent: Boolean;
     FOnBufferEmpty: TNotifyEvent;
     FOnBufferEmpty: TNotifyEvent;
     FOnBufferSent: TNotifyEvent;
     FOnBufferSent: TNotifyEvent;
+    InCallback: Boolean;
 
 
     function  Seek(Offset: LongInt; Origin: Word): LongInt; override;
     function  Seek(Offset: LongInt; Origin: Word): LongInt; override;
     function  Write(const ABuffer; Count: LongInt): LongInt; override;
     function  Write(const ABuffer; Count: LongInt): LongInt; override;
@@ -508,7 +509,8 @@ begin
   begin
   begin
     BytesRead := Read(NewData, SizeOf(NewData));
     BytesRead := Read(NewData, SizeOf(NewData));
     //WriteLn('Linereader: ', BytesRead, ' bytes read');
     //WriteLn('Linereader: ', BytesRead, ' bytes read');
-    if BytesRead <= 0 then begin
+    if BytesRead <= 0 then
+    begin
       if FirstRun then
       if FirstRun then
         NoData;
         NoData;
       break;
       break;
@@ -546,10 +548,16 @@ begin
           Inc(i);
           Inc(i);
         LastEndOfLine := i + 1;
         LastEndOfLine := i + 1;
 
 
-        if Assigned(FOnLine) then begin
+        if Assigned(FOnLine) then
+	begin
           FBuffer := RealBuffer + LastEndOfLine;
           FBuffer := RealBuffer + LastEndOfLine;
           FBytesInBuffer := CurBytesInBuffer - LastEndOfLine;
           FBytesInBuffer := CurBytesInBuffer - LastEndOfLine;
-          FOnLine(line);
+	  InCallback := True;
+	  try
+            FOnLine(line);
+	  finally
+	    InCallback := False;
+	  end;
           // Check if <this> has been destroyed by FOnLine:
           // Check if <this> has been destroyed by FOnLine:
           if DoStopAndFree then
           if DoStopAndFree then
 	    exit;
 	    exit;
@@ -605,12 +613,16 @@ end;
 
 
 procedure TAsyncStreamLineReader.StopAndFree;
 procedure TAsyncStreamLineReader.StopAndFree;
 begin
 begin
-  if Assigned(NotifyHandle) then
+  if InCallback then
   begin
   begin
-    EventLoop.ClearDataAvailableNotify(NotifyHandle);
-    NotifyHandle := nil;
-  end;
-  DoStopAndFree := True;
+    if Assigned(NotifyHandle) then
+    begin
+      EventLoop.ClearDataAvailableNotify(NotifyHandle);
+      NotifyHandle := nil;
+    end;
+    DoStopAndFree := True;
+  end else
+    Self.Free;
 end;
 end;
 
 
 function TAsyncStreamLineReader.Read(var ABuffer; count: Integer): Integer;
 function TAsyncStreamLineReader.Read(var ABuffer; count: Integer): Integer;
@@ -637,7 +649,14 @@ begin
     EventLoop.ClearDataAvailableNotify(NotifyHandle);
     EventLoop.ClearDataAvailableNotify(NotifyHandle);
     NotifyHandle := nil;
     NotifyHandle := nil;
     if Assigned(FOnEOF) then
     if Assigned(FOnEOF) then
-      FOnEOF(Self);
+    begin
+      InCallback := True;
+      try
+        FOnEOF(Self);
+      finally
+        InCallback := False;
+      end;
+    end;
   end;
   end;
 end;
 end;
 
 
@@ -656,7 +675,11 @@ end;
 procedure TWriteBuffer.BufferEmpty;
 procedure TWriteBuffer.BufferEmpty;
 begin
 begin
   if Assigned(FOnBufferEmpty) then
   if Assigned(FOnBufferEmpty) then
+  begin
+    InCallback := True;
     FOnBufferEmpty(Self);
     FOnBufferEmpty(Self);
+    InCallback := False;
+  end;
 end;
 end;
 
 
 constructor TWriteBuffer.Create;
 constructor TWriteBuffer.Create;
@@ -778,7 +801,14 @@ begin
     end;
     end;
     FBufferSent := True;
     FBufferSent := True;
     if Assigned(FOnBufferSent) then
     if Assigned(FOnBufferSent) then
-      FOnBufferSent(Self);
+    begin
+      InCallback := True;
+      try
+        FOnBufferSent(Self);
+      finally
+        InCallback := False;
+      end;
+    end;
   end else
   end else
     Run;
     Run;
   if DoStopAndFree then
   if DoStopAndFree then
@@ -811,12 +841,16 @@ end;
 
 
 procedure TAsyncWriteStream.StopAndFree;
 procedure TAsyncWriteStream.StopAndFree;
 begin
 begin
-  if Assigned(NotifyHandle) then
+  if InCallback then
   begin
   begin
-    EventLoop.ClearCanWriteNotify(NotifyHandle);
-    NotifyHandle := nil;
-  end;
-  DoStopAndFree := True;
+    if Assigned(NotifyHandle) then
+    begin
+      EventLoop.ClearCanWriteNotify(NotifyHandle);
+      NotifyHandle := nil;
+    end;
+    DoStopAndFree := True;
+  end else
+    Self.Free;
 end;
 end;
 
 
 
 
@@ -825,7 +859,11 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.5  2003-11-22 11:46:40  sg
+  Revision 1.6  2004-02-02 16:50:44  sg
+  * Destroying a line reader or write buffer now works within an event
+    handler of these classes
+
+  Revision 1.5  2003/11/22 11:46:40  sg
   * Removed TAsyncWriteStream.BufferEmpty (not needed anymore)
   * Removed TAsyncWriteStream.BufferEmpty (not needed anymore)
 
 
   Revision 1.4  2003/08/03 21:18:40  sg
   Revision 1.4  2003/08/03 21:18:40  sg