Issue #397: simplify synchronized code calls in query threads, especially wrt LogFromOutside()

This commit is contained in:
Ansgar Becker
2021-01-27 22:41:56 +01:00
parent ac9f16e4d1
commit be66d708dc
2 changed files with 21 additions and 48 deletions

View File

@@ -119,12 +119,6 @@ type
FRowsAffected: Int64;
FRowsFound: Int64;
FWarningCount: Int64;
FLogMsg: String;
FLogCategory: TDBLogCategory;
procedure BeforeQuery;
procedure AfterQuery;
procedure BatchFinished;
procedure Log;
public
property Connection: TDBConnection read FConnection;
property Batch: TSQLBatch read FBatch;
@@ -141,7 +135,7 @@ type
property ErrorMessage: String read FErrorMessage;
constructor Create(Connection: TDBConnection; Batch: TSQLBatch; TabNumber: Integer);
procedure Execute; override;
procedure LogFromOutside(Msg: String; Category: TDBLogCategory);
procedure LogFromThread(Msg: String; Category: TDBLogCategory);
end;
TAppSettingDataType = (adInt, adBool, adString);
@@ -2987,15 +2981,15 @@ begin
end;
FQueriesInPacket := i - FBatchPosition;
end;
Synchronize(BeforeQuery);
Synchronize(procedure begin MainForm.BeforeQueryExecution(Self); end);
try
FConnection.LockedByThread := Self;
DoStoreResult := ResultCount < AppSettings.ReadInt(asMaxQueryResults);
if (not DoStoreResult) and (not LogMaxResultsDone) then begin
// Inform user about preference setting for limiting result tabs
LogFromOutside(
f_('Reached maximum number of result tabs (%d). To display more results, increase setting in Preferences > SQL', [AppSettings.ReadInt(asMaxQueryResults)]),
lcInfo);
FConnection.Log(lcInfo,
f_('Reached maximum number of result tabs (%d). To display more results, increase setting in Preferences > SQL', [AppSettings.ReadInt(asMaxQueryResults)])
);
LogMaxResultsDone := True;
end;
FConnection.Query(SQL, DoStoreResult, lcUserFiredSQL);
@@ -3015,46 +3009,20 @@ begin
end;
end;
FConnection.LockedByThread := nil;
Synchronize(AfterQuery);
Synchronize(procedure begin MainForm.AfterQueryExecution(Self); end);
// Check if FAborted is set by the main thread, to avoid proceeding the loop in case
// FStopOnErrors is set to false
if FAborted or ErrorAborted then
break;
end;
Synchronize(BatchFinished);
Synchronize(procedure begin MainForm.FinishedQueryExecution(Self); end);
end;
procedure TQueryThread.BeforeQuery;
procedure TQueryThread.LogFromThread(Msg: String; Category: TDBLogCategory);
begin
MainForm.BeforeQueryExecution(Self);
end;
procedure TQueryThread.LogFromOutside(Msg: String; Category: TDBLogCategory);
begin
FLogMsg := Msg;
FLogCategory := Category;
Synchronize(Log);
end;
procedure TQueryThread.Log;
begin
FConnection.OnLog(FLogMsg, FLogCategory, FConnection);
end;
procedure TQueryThread.AfterQuery;
begin
MainForm.AfterQueryExecution(Self);
end;
procedure TQueryThread.BatchFinished;
begin
MainForm.FinishedQueryExecution(Self);
Queue(procedure begin FConnection.Log(Category, Msg); end);
end;

View File

@@ -4247,16 +4247,21 @@ end;
If running a thread, log to queue and let the main thread later do logging
}
procedure TDBConnection.Log(Category: TDBLogCategory; Msg: String);
var
LogMessage,
begin
// If in a thread, synchronize logging with the main thread. Logging within a thread
// causes SynEdit to throw exceptions left and right.
if (FLockedByThread <> nil) and (FLockedByThread.ThreadID = GetCurrentThreadID) then begin
(FLockedByThread as TQueryThread).LogFromThread(Msg, Category);
Exit;
end;
if Assigned(FOnLog) then begin
LogMessage := Msg;
if FLogPrefix <> '' then
Msg := '['+FLogPrefix+'] ' + Msg;
// If in a thread, synchronize logging with the main thread. Logging within a thread
// causes SynEdit to throw exceptions left and right.
if (FLockedByThread <> nil) and (FLockedByThread.ThreadID = GetCurrentThreadID) then
(FLockedByThread as TQueryThread).LogFromOutside(Msg, Category)
else
FOnLog(Msg, Category, Self);
LogMessage := '['+FLogPrefix+'] ' + LogMessage;
FOnLog(LogMessage, Category, Self);
end;
end;