43 |
|
|
44 |
|
{$codepage UTF8} |
45 |
|
|
46 |
+ |
{ $DEFINE DEBUG} |
47 |
+ |
|
48 |
|
interface |
49 |
|
|
50 |
|
uses |
51 |
|
IB, IBUtils, IBSQL, IBCustomDataSet, IBDatabase, DB, IBInternals, |
52 |
< |
SysUtils, Classes, |
51 |
< |
{$IFDEF WINDOWS } |
52 |
< |
Windows |
53 |
< |
{$ENDIF} |
54 |
< |
{$IFDEF UNIX} |
55 |
< |
unix |
56 |
< |
{$ENDIF} |
57 |
< |
; |
52 |
> |
SysUtils, Classes; |
53 |
|
|
54 |
|
{Note that the original inter-thread communication between the Reader Thread and |
55 |
|
the ISQL Monitor used the Windows PostMessage interface. This is currently not |
64 |
|
{$DEFINE USE_SV5_IPC} |
65 |
|
{$ENDIF} |
66 |
|
|
72 |
– |
{$IFDEF LINUX} |
73 |
– |
{$DEFINE HAS_SEMTIMEDOP} |
74 |
– |
{$ENDIF} |
75 |
– |
|
67 |
|
type |
68 |
|
TIBCustomSQLMonitor = class; |
69 |
|
|
73 |
|
|
74 |
|
TIBCustomSQLMonitor = class(TComponent) |
75 |
|
private |
76 |
+ |
FOnMonitoringDisabled: TNotifyEvent; |
77 |
|
FOnSQLEvent: TSQLEvent; |
78 |
|
FTraceFlags: TTraceFlags; |
79 |
|
FEnabled: Boolean; |
80 |
+ |
function GetReadCount: integer; |
81 |
|
procedure SetEnabled(const Value: Boolean); |
82 |
|
protected |
83 |
|
procedure ReleaseObject; {Called from Writer Thread} |
84 |
|
procedure ReceiveMessage(Msg: TObject); {Called from Reader Thread} |
85 |
|
property OnSQL: TSQLEvent read FOnSQLEvent write FOnSQLEvent; |
86 |
+ |
property OnMonitoringDisabled: TNotifyEvent read FOnMonitoringDisabled write FOnMonitoringDisabled; |
87 |
|
property TraceFlags: TTraceFlags read FTraceFlags write FTraceFlags; |
88 |
|
property Enabled : Boolean read FEnabled write SetEnabled default true; |
89 |
|
public |
90 |
|
constructor Create(AOwner: TComponent); override; |
91 |
|
destructor Destroy; override; |
92 |
|
procedure Release; |
93 |
+ |
property ReadCount: integer read GetReadCount; |
94 |
|
end; |
95 |
|
|
96 |
|
{ TIBSQLMonitor } |
98 |
|
TIBSQLMonitor = class(TIBCustomSQLMonitor) |
99 |
|
published |
100 |
|
property OnSQL; |
101 |
+ |
property OnMonitoringDisabled; |
102 |
|
property TraceFlags; |
103 |
|
property Enabled; |
104 |
|
end; |
129 |
|
procedure SendMisc(Msg : String); |
130 |
|
function GetTraceFlags : TTraceFlags; |
131 |
|
function GetMonitorCount : Integer; |
132 |
+ |
function GetWriteCount: integer; |
133 |
|
procedure SetTraceFlags(const Value : TTraceFlags); |
134 |
|
function GetEnabled : boolean; |
135 |
|
procedure SetEnabled(const Value : Boolean); |
145 |
|
|
146 |
|
implementation |
147 |
|
|
148 |
< |
uses |
152 |
< |
contnrs, syncobjs, CustApp, IBMessages |
153 |
< |
{$IFDEF USE_SV5_IPC} |
154 |
< |
,ipc, Errors, baseunix |
155 |
< |
{$ENDIF}; |
156 |
< |
|
148 |
> |
uses IBIPC, contnrs, syncobjs, CustApp, IBMessages; |
149 |
|
|
150 |
|
const |
159 |
– |
cMonitorHookSize = 1024; |
160 |
– |
cMsgWaitTime = 1000; |
151 |
|
cWriteMessageAvailable = 'WriterMsgQueue'; |
152 |
|
|
153 |
|
type |
164 |
– |
{ There are two possible objects. One is a trace message object. |
165 |
– |
This object holds the flag of the trace type plus the message. |
166 |
– |
The second object is a Release object. It holds the handle that |
167 |
– |
the CM_RELEASE message is to be queued to. } |
168 |
– |
|
169 |
– |
{ TTraceObject } |
170 |
– |
|
171 |
– |
TTraceObject = Class(TObject) |
172 |
– |
FDataType : TTraceFlag; |
173 |
– |
FMsg : String; |
174 |
– |
FTimeStamp : TDateTime; |
175 |
– |
public |
176 |
– |
constructor Create(Msg : String; DataType : TTraceFlag); overload; |
177 |
– |
constructor Create(obj : TTraceObject); overload; |
178 |
– |
constructor Create(obj : TTraceObject; MsgOffset, MsgLen: integer); overload; |
179 |
– |
end; |
180 |
– |
|
181 |
– |
{ TReleaseObject } |
182 |
– |
|
183 |
– |
TReleaseObject = Class(TObject) |
184 |
– |
FMonitor : TIBCustomSQLMonitor; |
185 |
– |
public |
186 |
– |
constructor Create(Monitor : TIBCustomSQLMonitor); |
187 |
– |
end; |
188 |
– |
|
189 |
– |
{$IFDEF USE_SV5_IPC} |
190 |
– |
{$I sv5ipc.inc} |
191 |
– |
{$ENDIF} |
192 |
– |
{$IFDEF USE_WINDOWS_IPC} |
193 |
– |
{$I winipc.inc} |
194 |
– |
{$ENDIF} |
195 |
– |
|
196 |
– |
type |
197 |
– |
|
154 |
|
{ TIBSQLMonitorHook } |
155 |
|
|
156 |
|
TIBSQLMonitorHook = class(TInterfacedObject, IIBSQLMonitorHook) |
157 |
|
private |
158 |
< |
FGlobalInterface: TGlobalInterface; |
158 |
> |
FIPCInterface: IIPCInterface; |
159 |
|
FTraceFlags: TTraceFlags; |
160 |
|
FEnabled: Boolean; |
161 |
+ |
FWriteCount: integer; |
162 |
|
protected |
163 |
|
procedure WriteSQLData(Text: String; DataType: TTraceFlag); |
164 |
|
public |
165 |
|
constructor Create; |
209 |
– |
destructor Destroy; override; |
166 |
|
procedure RegisterMonitor(SQLMonitor : TIBCustomSQLMonitor); |
167 |
|
procedure UnregisterMonitor(SQLMonitor : TIBCustomSQLMonitor); |
168 |
|
procedure ReleaseMonitor(Arg : TIBCustomSQLMonitor); |
188 |
|
function GetEnabled: Boolean; |
189 |
|
function GetTraceFlags: TTraceFlags; |
190 |
|
function GetMonitorCount : Integer; |
191 |
+ |
function GetWriteCount: integer; |
192 |
|
procedure SetEnabled(const Value: Boolean); |
193 |
|
procedure SetTraceFlags(const Value: TTraceFlags); |
194 |
|
procedure ForceRelease; |
201 |
|
TWriterThread = class(TThread) |
202 |
|
private |
203 |
|
{ Private declarations } |
204 |
< |
FGlobalInterface: TGlobalInterface; |
204 |
> |
FIPCInterface: IIPCInterface; |
205 |
|
FMsgs : TObjectList; |
206 |
|
FCriticalSection: TCriticalSection; |
207 |
|
FMsgAvailable: TEventObject; |
208 |
+ |
FWriteCount: integer; |
209 |
|
procedure RemoveFromList; |
210 |
|
procedure PostRelease; |
211 |
|
public |
216 |
|
procedure Execute; override; |
217 |
|
procedure WriteToBuffer; |
218 |
|
public |
219 |
< |
constructor Create(GlobalInterface: TGlobalInterface); |
219 |
> |
constructor Create(IPCInterface: IIPCInterface); |
220 |
|
destructor Destroy; override; |
221 |
|
procedure WriteSQLData(Msg : String; DataType : TTraceFlag); |
222 |
|
end; |
228 |
|
{ Private declarations } |
229 |
|
st : TTraceObject; |
230 |
|
FMonitors : TObjectList; |
231 |
< |
FGlobalInterface: TGlobalInterface; |
231 |
> |
FIPCInterface: IIPCInterface; |
232 |
|
FCriticalSection: TCriticalSection; |
233 |
+ |
FReadCount: integer; |
234 |
|
procedure AlertMonitors; |
235 |
|
protected |
236 |
|
procedure BeginRead; |
238 |
|
procedure ReadSQLData; |
239 |
|
procedure Execute; override; |
240 |
|
public |
241 |
< |
constructor Create(GlobalInterface: TGlobalInterface); |
241 |
> |
constructor Create(IPCInterface: IIPCInterface); |
242 |
|
destructor Destroy; override; |
243 |
|
procedure AddMonitor(Arg : TIBCustomSQLMonitor); |
244 |
|
procedure RemoveMonitor(Arg : TIBCustomSQLMonitor); |
307 |
|
if (Assigned(FOnSQLEvent)) and |
308 |
|
(st.FDataType in FTraceFlags) then |
309 |
|
FOnSQLEvent(st.FMsg, st.FTimeStamp); |
310 |
+ |
if assigned(OnMonitoringDisabled) and (st.FDataType = tfDisabled) then |
311 |
+ |
OnMonitoringDisabled(self); |
312 |
|
st.Free; |
313 |
|
end; |
314 |
|
|
325 |
|
end; |
326 |
|
end; |
327 |
|
|
328 |
+ |
function TIBCustomSQLMonitor.GetReadCount: integer; |
329 |
+ |
begin |
330 |
+ |
Result := FReaderThread.FReadCount; |
331 |
+ |
end; |
332 |
+ |
|
333 |
|
{ TIBSQLMonitorHook } |
334 |
|
|
335 |
|
constructor TIBSQLMonitorHook.Create; |
336 |
|
begin |
337 |
|
inherited Create; |
338 |
|
FTraceFlags := [tfQPrepare..tfMisc]; |
339 |
+ |
FIPCInterface := CreateIPCInterface; |
340 |
|
FEnabled := false; |
341 |
|
end; |
342 |
|
|
376 |
– |
destructor TIBSQLMonitorHook.Destroy; |
377 |
– |
begin |
378 |
– |
if assigned(FGlobalInterface) then FGlobalInterface.Free; |
379 |
– |
inherited Destroy; |
380 |
– |
end; |
381 |
– |
|
343 |
|
procedure TIBSQLMonitorHook.DBConnect(db: TIBDatabase); |
344 |
|
var |
345 |
|
st : String; |
374 |
|
|
375 |
|
function TIBSQLMonitorHook.GetMonitorCount: Integer; |
376 |
|
begin |
377 |
< |
Result := FGlobalInterface.MonitorCount |
377 |
> |
Result := FIPCInterface.MonitorCount |
378 |
> |
end; |
379 |
> |
|
380 |
> |
function TIBSQLMonitorHook.GetWriteCount: integer; |
381 |
> |
begin |
382 |
> |
if assigned(FWriterThread) then |
383 |
> |
Result := FWriterThread.FWriteCount |
384 |
> |
else |
385 |
> |
Result := FWriteCount; |
386 |
|
end; |
387 |
|
|
388 |
|
function TIBSQLMonitorHook.GetTraceFlags: TTraceFlags; |
393 |
|
procedure TIBSQLMonitorHook.RegisterMonitor(SQLMonitor: TIBCustomSQLMonitor); |
394 |
|
begin |
395 |
|
{$IFDEF DEBUG}writeln('Register Monitor');{$ENDIF} |
427 |
– |
if not assigned(FGlobalInterface) then |
428 |
– |
FGlobalInterface := TGlobalInterface.Create; |
396 |
|
if not Assigned(FReaderThread) then |
397 |
< |
FReaderThread := TReaderThread.Create(FGlobalInterface); |
397 |
> |
FReaderThread := TReaderThread.Create(FIPCInterface); |
398 |
|
FReaderThread.AddMonitor(SQLMonitor); |
399 |
|
end; |
400 |
|
|
517 |
|
|
518 |
|
procedure TIBSQLMonitorHook.SetEnabled(const Value: Boolean); |
519 |
|
begin |
520 |
< |
{$ifdef UNIX} |
521 |
< |
if Value and not IsMultiThread then |
522 |
< |
IBError(ibxeMultiThreadRequired,['IBSQLMonitor']); |
523 |
< |
{$endif} |
524 |
< |
if FEnabled <> Value then |
525 |
< |
FEnabled := Value; |
520 |
> |
if FEnabled = Value then Exit; |
521 |
> |
|
522 |
> |
FEnabled := Value; |
523 |
> |
if FEnabled then |
524 |
> |
begin |
525 |
> |
if not Assigned(FWriterThread) then |
526 |
> |
FWriterThread := TWriterThread.Create(FIPCInterface); |
527 |
> |
(* {$ifdef UNIX} |
528 |
> |
if not IsMultiThread then |
529 |
> |
IBError(ibxeMultiThreadRequired,['IBSQLMonitor']); |
530 |
> |
{$endif}*) |
531 |
> |
end; |
532 |
|
if (not FEnabled) and (Assigned(FWriterThread)) then |
533 |
|
begin |
534 |
+ |
WriteSQLData('Monitoring Disabled',tfDisabled); |
535 |
|
FWriterThread.Terminate; |
536 |
|
FWriterThread.WaitFor; |
537 |
+ |
FWriteCount := FWriterThread.FWriteCount; |
538 |
|
FreeAndNil(FWriterThread); |
539 |
|
end; |
540 |
|
end; |
550 |
|
begin |
551 |
|
FReaderThread.Terminate; |
552 |
|
if not Assigned(FWriterThread) then |
553 |
< |
FWriterThread := TWriterThread.Create(FGlobalInterface); |
553 |
> |
FWriterThread := TWriterThread.Create(FIPCInterface); |
554 |
|
FWriterThread.WriteSQLData(' ', tfMisc); |
555 |
|
end; |
556 |
|
end; |
572 |
|
st := st + ': [Execute] ' + qry.SQL.Text; {do not localize} |
573 |
|
if qry.Params.GetCount > 0 then begin |
574 |
|
for i := 0 to qry.Params.GetCount - 1 do begin |
575 |
< |
st := st + CRLF + ' ' + qry.Params[i].Name + ' = '; |
575 |
> |
st := st + LineEnding + ' ' + qry.Params[i].Name + ' = '; |
576 |
|
try |
577 |
|
if qry.Params[i].IsNull then |
578 |
|
st := st + '<NULL>'; {do not localize} |
601 |
|
st := qry.Name; |
602 |
|
st := st + ': [Fetch] ' + qry.SQL.Text; {do not localize} |
603 |
|
if (qry.EOF) then |
604 |
< |
st := st + CRLF + ' ' + SEOFReached; |
604 |
> |
st := st + LineEnding + ' ' + SEOFReached; |
605 |
|
WriteSQLData(st, tfQFetch); |
606 |
|
end; |
607 |
|
end; |
619 |
|
st := TIBCustomDataSet(qry.Owner).Name |
620 |
|
else |
621 |
|
st := qry.Name; |
622 |
< |
st := st + ': [Prepare] ' + qry.SQL.Text + CRLF; {do not localize} |
622 |
> |
st := st + ': [Prepare] ' + qry.SQL.Text + LineEnding; {do not localize} |
623 |
|
st := st + ' Plan: ' + qry.Plan; {do not localize} |
624 |
|
WriteSQLData(st, tfQPrepare); |
625 |
|
end; |
716 |
|
Created := false; |
717 |
|
if not Assigned(FWriterThread) then |
718 |
|
begin |
719 |
< |
FWriterThread := TWriterThread.Create(FGlobalInterface); |
719 |
> |
FWriterThread := TWriterThread.Create(FIPCInterface); |
720 |
|
Created := true; |
721 |
|
end; |
722 |
|
FWriterThread.WriteSQLData(' ', tfMisc); |
744 |
|
procedure TIBSQLMonitorHook.WriteSQLData(Text: String; |
745 |
|
DataType: TTraceFlag); |
746 |
|
begin |
747 |
< |
{$IFDEF DEBUG}writeln('Write SQL Data: '+Text);{$ENDIF} |
748 |
< |
if not assigned(FGlobalInterface) then |
774 |
< |
FGlobalInterface := TGlobalInterface.Create; |
775 |
< |
Text := CRLF + '[Application: ' + ApplicationTitle + ']' + CRLF + Text; {do not localize} |
776 |
< |
if not Assigned(FWriterThread) then |
777 |
< |
FWriterThread := TWriterThread.Create(FGLobalInterface); |
747 |
> |
// {$IFDEF DEBUG}writeln('Write SQL Data: '+Text);{$ENDIF} |
748 |
> |
Text := LineEnding + '[Application: ' + ApplicationTitle + ']' + LineEnding + Text; {do not localize} |
749 |
|
FWriterThread.WriteSQLData(Text, DataType); |
750 |
|
end; |
751 |
|
|
752 |
|
{ TWriterThread } |
753 |
|
|
754 |
< |
constructor TWriterThread.Create(GlobalInterface: TGlobalInterface); |
754 |
> |
constructor TWriterThread.Create(IPCInterface: IIPCInterface); |
755 |
|
|
756 |
|
begin |
757 |
|
inherited Create(true); |
758 |
|
{$IFDEF DEBUG}writeln('Write Object Created');{$ENDIF} |
759 |
< |
FGlobalInterface := GlobalInterface; |
759 |
> |
FIPCInterface := IPCInterface; |
760 |
|
FMsgs := TObjectList.Create(true); |
761 |
|
FCriticalSection := TCriticalSection.Create; |
762 |
< |
FMsgAvailable := TEventObject.Create(FGlobalInterface.Sa,true,false,cWriteMessageAvailable); |
762 |
> |
FMsgAvailable := TEventObject.Create(FIPCInterface.Sa,true,false,cWriteMessageAvailable); |
763 |
|
Start; |
764 |
|
end; |
765 |
|
|
781 |
|
begin |
782 |
|
FMsgAvailable.WaitFor(cMsgWaitTime); |
783 |
|
{ Any one listening? } |
784 |
< |
if FGlobalInterface.MonitorCount = 0 then |
784 |
> |
if FIPCInterface.MonitorCount = 0 then |
785 |
|
begin |
786 |
|
if FMsgs.Count <> 0 then |
787 |
|
begin |
830 |
|
begin |
831 |
|
FCriticalSection.Enter; |
832 |
|
try |
833 |
< |
FMsgs.Add(TTraceObject.Create(Msg, DataType)); |
833 |
> |
FMsgs.Add(TTraceObject.Create(Msg, DataType,FWriteCount)); |
834 |
> |
Inc(FWriteCount); |
835 |
|
finally |
836 |
|
FCriticalSection.Leave; |
837 |
|
end; |
841 |
|
procedure TWriterThread.BeginWrite; |
842 |
|
begin |
843 |
|
{$IFDEF DEBUG}writeln('Begin Write');{$ENDIF} |
844 |
< |
with FGlobalInterface do |
844 |
> |
with FIPCInterface do |
845 |
|
begin |
846 |
|
ReadReadyEvent.PassThroughGate; {Wait for readers to become ready } |
847 |
|
WriterBusyEvent.Lock; {Set Busy State} |
852 |
|
procedure TWriterThread.EndWrite; |
853 |
|
begin |
854 |
|
{$IFDEF DEBUG}writeln('End Write');{$ENDIF} |
855 |
< |
with FGlobalInterface do |
855 |
> |
with FIPCInterface do |
856 |
|
begin |
857 |
|
DataAvailableEvent.Unlock; { Signal Data Available. } |
858 |
|
ReadFinishedEvent.PassThroughGate; {Wait for readers to finish } |
863 |
|
end; |
864 |
|
|
865 |
|
procedure TWriterThread.WriteToBuffer; |
894 |
– |
var I, len: integer; |
895 |
– |
Temp: TTraceObject; |
866 |
|
begin |
867 |
< |
{$IFDEF DEBUG}writeln('Write to Buffer');{$ENDIF} |
898 |
< |
FGlobalInterface.WriteLock.Lock; |
867 |
> |
FIPCInterface.WriteLock.Lock; |
868 |
|
try |
869 |
|
{ If there are no monitors throw out the message |
870 |
|
The alternative is to have messages queue up until a |
871 |
|
monitor is ready.} |
872 |
|
|
873 |
< |
if FGlobalInterface.MonitorCount = 0 then |
873 |
> |
if FIPCInterface.MonitorCount = 0 then |
874 |
|
RemoveFromList |
875 |
|
else |
876 |
|
begin |
877 |
< |
i := 1; |
909 |
< |
len := Length(TTraceObject(FMsgs[0]).FMsg); |
910 |
< |
if len <= FGlobalInterface.MaxBufferSize then |
911 |
< |
begin |
912 |
< |
BeginWrite; |
913 |
< |
try |
914 |
< |
FGlobalInterface.SendTrace(TTraceObject(FMsgs[0])) |
915 |
< |
finally |
916 |
< |
RemoveFromList; |
917 |
< |
EndWrite |
918 |
< |
end; |
919 |
< |
end |
920 |
< |
else |
877 |
> |
BeginWrite; |
878 |
|
try |
879 |
< |
while len > 0 do |
880 |
< |
begin |
924 |
< |
{$IFDEF DEBUG}writeln('Sending Partial Message, len = ',len);{$ENDIF} |
925 |
< |
Temp := TTraceObject.Create(TTraceObject(FMsgs[0]),i,Min(len,FGlobalInterface.MaxBufferSize)); |
926 |
< |
try |
927 |
< |
BeginWrite; |
928 |
< |
FGlobalInterface.SendTrace(Temp); |
929 |
< |
Inc(i,FGlobalInterface.MaxBufferSize); |
930 |
< |
Dec(len,FGlobalInterface.MaxBufferSize); |
931 |
< |
finally |
932 |
< |
Temp.Free; |
933 |
< |
EndWrite |
934 |
< |
end |
935 |
< |
end; |
879 |
> |
{$IFDEF DEBUG}writeln('Write to Buffer. Msg No. ',TTraceObject(FMsgs[0]).FMsgNumber);{$ENDIF} |
880 |
> |
FIPCInterface.SendTrace(TTraceObject(FMsgs[0])) |
881 |
|
finally |
882 |
|
RemoveFromList; |
883 |
+ |
EndWrite |
884 |
|
end |
885 |
|
end; |
886 |
|
finally |
887 |
< |
FGlobalInterface.WriteLock.Unlock; |
887 |
> |
FIPCInterface.WriteLock.Unlock; |
888 |
|
end; |
889 |
|
{$IFDEF DEBUG}writeln('Done Write');{$ENDIF} |
890 |
|
end; |
903 |
|
procedure TWriterThread.PostRelease; |
904 |
|
var Monitor: TIBCustomSQLMonitor; |
905 |
|
begin |
906 |
< |
Monitor := TReleaseObject(FMsgs.Items[0]).FMonitor; |
906 |
> |
Monitor := TReleaseObject(FMsgs.Items[0]).FMonitor as TIBCustomSQLMonitor; |
907 |
|
Monitor.ReleaseObject |
908 |
|
end; |
909 |
|
|
912 |
|
FMsgs.Add(TReleaseObject.Create(Arg)); |
913 |
|
end; |
914 |
|
|
969 |
– |
{ TTraceObject } |
970 |
– |
|
971 |
– |
constructor TTraceObject.Create(Msg : String; DataType: TTraceFlag); |
972 |
– |
begin |
973 |
– |
FMsg := Msg; |
974 |
– |
FDataType := DataType; |
975 |
– |
FTimeStamp := Now; |
976 |
– |
end; |
977 |
– |
|
978 |
– |
constructor TTraceObject.Create(obj: TTraceObject); |
979 |
– |
begin |
980 |
– |
FMsg := obj.FMsg; |
981 |
– |
FDataType := obj.FDataType; |
982 |
– |
FTimeStamp := obj.FTimeStamp; |
983 |
– |
end; |
984 |
– |
|
985 |
– |
constructor TTraceObject.Create(obj: TTraceObject; MsgOffset, MsgLen: integer); |
986 |
– |
begin |
987 |
– |
FDataType := obj.FDataType; |
988 |
– |
FTimeStamp := obj.FTimeStamp; |
989 |
– |
FMsg := copy(obj.FMsg,MsgOffset,MsgLen) |
990 |
– |
end; |
991 |
– |
|
992 |
– |
{ TReleaseObject } |
993 |
– |
|
994 |
– |
constructor TReleaseObject.Create(Monitor : TIBCustomSQLMonitor); |
995 |
– |
begin |
996 |
– |
FMonitor := Monitor; |
997 |
– |
end; |
998 |
– |
|
915 |
|
{ ReaderThread } |
916 |
|
|
917 |
|
procedure TReaderThread.AddMonitor(Arg: TIBCustomSQLMonitor); |
942 |
|
procedure TReaderThread.BeginRead; |
943 |
|
begin |
944 |
|
{$IFDEF DEBUG}writeln('Begin Read');{$ENDIF} |
945 |
< |
with FGlobalInterface do |
945 |
> |
with FIPCInterface do |
946 |
|
begin |
947 |
|
WriterBusyEvent.PassthroughGate; { Wait for Writer not busy} |
948 |
|
ReadFinishedEvent.Lock; { Prepare Read Finished Gate} |
953 |
|
{$IFDEF DEBUG}writeln('Begin Read Complete');{$ENDIF} |
954 |
|
end; |
955 |
|
|
956 |
< |
constructor TReaderThread.Create(GlobalInterface: TGlobalInterface); |
956 |
> |
constructor TReaderThread.Create(IPCInterface: IIPCInterface); |
957 |
|
begin |
958 |
|
inherited Create(true); |
959 |
< |
FGlobalInterface := GlobalInterface; |
959 |
> |
FIPCInterface := IPCInterface; |
960 |
|
st := TTraceObject.Create('', tfMisc); |
961 |
< |
FGlobalInterface.IncMonitorCount; |
961 |
> |
FIPCInterface.IncMonitorCount; |
962 |
|
FMonitors := TObjectList.Create(false); |
963 |
|
FCriticalSection := TCriticalSection.Create; |
964 |
|
{$IFDEF DEBUG}writeln('Reader Thread Created');{$ENDIF} |
965 |
< |
FGlobalInterface.ReadReadyEvent.Lock; { Initialise Read Ready} |
965 |
> |
FIPCInterface.ReadReadyEvent.Lock; { Initialise Read Ready} |
966 |
|
Start; |
967 |
|
end; |
968 |
|
|
969 |
|
destructor TReaderThread.Destroy; |
970 |
|
begin |
971 |
|
{$IFDEF DEBUG}writeln('Reader Thread Destory');{$ENDIF} |
972 |
< |
FGlobalInterface.ReadReadyEvent.UnLock; |
973 |
< |
if assigned(FGlobalInterface) and (FGlobalInterface.MonitorCount > 0) then |
974 |
< |
FGlobalInterface.DecMonitorCount; |
972 |
> |
FIPCInterface.ReadReadyEvent.UnLock; |
973 |
> |
if assigned(FIPCInterface) and (FIPCInterface.MonitorCount > 0) then |
974 |
> |
FIPCInterface.DecMonitorCount; |
975 |
|
FMonitors.Free; |
976 |
|
if assigned(FCriticalSection) then FCriticalSection.Free; |
977 |
|
st.Free; |
981 |
|
procedure TReaderThread.EndRead; |
982 |
|
begin |
983 |
|
{$IFDEF DEBUG}writeln('End Read');{$ENDIF} |
984 |
< |
FGlobalInterface.ReadReadyEvent.Lock; { reset Read Ready} |
985 |
< |
FGlobalInterface.ReadFinishedEvent.Unlock; {Signal Read completed } |
984 |
> |
FIPCInterface.ReadReadyEvent.Lock; { reset Read Ready} |
985 |
> |
FIPCInterface.ReadFinishedEvent.Unlock; {Signal Read completed } |
986 |
|
{$IFDEF DEBUG}writeln('End Read Complete');{$ENDIF} |
987 |
|
end; |
988 |
|
|
1010 |
|
BeginRead; |
1011 |
|
if not bDone then |
1012 |
|
try |
1013 |
< |
FGlobalInterface.ReceiveTrace(st) |
1013 |
> |
FIPCInterface.ReceiveTrace(st); |
1014 |
> |
{$IFDEF DEBUG}writeln('Msg No. ',st.FMsgNumber,' received');{$ENDIF} |
1015 |
> |
{ if st.FMsgNumber < FReadCount then |
1016 |
> |
FReadCount := 0 |
1017 |
> |
else |
1018 |
> |
if st.FMsgNumber <> FReadCount then |
1019 |
> |
IBError(ibxeMissedRead,[st.FMsgNumber,FReadCount]);} |
1020 |
> |
Inc(FReadCount); |
1021 |
|
finally |
1022 |
|
EndRead; |
1023 |
|
end; |
1052 |
|
|
1053 |
|
procedure EnableMonitoring; |
1054 |
|
begin |
1055 |
+ |
if assigned(FWriterThread) then |
1056 |
+ |
FWriterThread.FWriteCount := 0; |
1057 |
|
MonitorHook.Enabled := True; |
1058 |
|
end; |
1059 |
|
|
1090 |
|
FWriterThread := nil; |
1091 |
|
FReaderThread := nil; |
1092 |
|
bDone := False; |
1168 |
– |
{$IFDEF USE_SV5_IPC} |
1169 |
– |
if GetEnvironmentVariable('FBSQL_IPCFILENAME') <> '' then |
1170 |
– |
IPCFileName := GetEnvironmentVariable('FBSQL_IPCFILENAME') |
1171 |
– |
else |
1172 |
– |
IPCFileName := GetTempDir(true) + IPCFileName + '.' + GetEnvironmentVariable('USER'); |
1173 |
– |
{$ENDIF} |
1093 |
|
|
1094 |
|
finalization |
1095 |
|
{$IFDEF DEBUG}writeln('Entered Finalisation');{$ENDIF} |