Subject AV when switching to another app
I've been having some issues with profiling (using AQtime) an app that uses
the Unified Interbase components, and figured I'd give IBO a try. The test
system is XPSP2, D2005 Update 1, IBO Eval 4.5, and FB embedded 1.5.2.4731.

I can run the code below in the IDE or standalone, and as long as I leave it
focused until I close it, it performs as expected. However if I switch to
another app while the main processing is going on or after I've stopped it,
the app AVs at 00000000 trying to read 00000000. Under AQtime I get the AV
regardless.

Testing this, it looks like I can have as little as the TIB_Session created in
the thread, and the AV occurs.

(Yeah I know some of the stuff in here is bad coding practice, like the A.PM
and Sleep(1) combo. I wouldn't normally do such things - this is just a
throwaway test app.)

Any help would be greatly appreciated. Thanks!

unit Unit22;

interface

uses
Forms, Controls, StdCtrls, Classes, ExtCtrls;

type
TForm22 = class(TForm)
Panel1: TPanel;
Button1: TButton;
LB: TListBox;
procedure Button1Click(Sender: TObject);
end;

var
Form22: TForm22;

implementation

{$R *.dfm}

uses
Windows, SysUtils, IB_Components, SyncObjs;

const
MAX_THREADS = 10;

type
TIBTestThread = class(TThread)
private
FDBSession: TIB_Session;
FDBConnection: TIB_Connection;
FDBTransaction: TIB_Transaction;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
end;

var
KeepGoing: Boolean;
TotalThreads: Cardinal;
CS: TCriticalSection;

constructor TIBTestThread.Create;
begin
inherited Create(False);

FreeOnTerminate := True;

FDBSession := TIB_Session.Create(nil);
FDBConnection := TIB_Connection.Create(FDBSession);
FDBConnection.IB_Session := FDBSession;
FDBConnection.Path := ExtractFilePath(ParamStr(0)) + 'foo.fdb';
FDBConnection.Username := 'foo';
FDBConnection.Password := 'bar';
FDBConnection.Connect;
FDBTransaction := TIB_Transaction.Create(FDBSession);
FDBTransaction.IB_Connection := FDBConnection;
end;

destructor TIBTestThread.Destroy;
begin
CS.Enter;
try
Dec(TotalThreads);
finally
CS.Leave;
end;

FDBTransaction.Free;
FDBConnection.Disconnect;
FDBConnection.Free;
FDBSession.Free;

inherited;
end;

procedure TIBTestThread.Execute;
var
Cursor: TIB_Cursor;
begin
Cursor := TIB_Cursor.Create(FDBSession);
try
Cursor.IB_Transaction := FDBTransaction;

Cursor.SQL.Text :=
'select ' +
' RDB$RELATION_NAME ' +
'from ' +
' RDB$RELATIONS';
Cursor.Open;
try
while not Cursor.Eof do
begin
Cursor.Next;
end;
finally
Cursor.Close;
end;
finally
Cursor.Free;
end;

Terminate;
end;

procedure TForm22.Button1Click(Sender: TObject);
var
StillThreads: Boolean;
begin
try
if Button1.Caption <> 'Go' then
begin
KeepGoing := False;
Exit;
end;

Button1.Caption := 'Stop';
try
CS := TCriticalSection.Create;
try
Button1.Enabled := False;
try
TotalThreads := 0;
KeepGoing := True;
finally
Button1.Enabled := True;
end;

while KeepGoing do
begin
CS.Enter;
try
if TotalThreads < MAX_THREADS then
begin
TIBTestThread.Create;
Inc(TotalThreads);
end;
finally
CS.Leave;
end;

Application.ProcessMessages;
Sleep(1);
end;

Button1.Enabled := False;
try
repeat
CS.Enter;
try
StillThreads := TotalThreads > 0;
finally
CS.Leave;
end;

Application.ProcessMessages;
Sleep(1);
until not StillThreads;
finally
Button1.Enabled := True;
end;
finally
CS.Free;
end;
finally
Button1.Caption := 'Go';
end;
except
on E:Exception do
begin
OutputDebugString(PChar('EXCEPTION - ' + E.ClassType.ClassName + ' - ' +
E.Message));
end;
end;
end;

end.

--
Toby