Browse Source

GUI: stability fix, thread-safe grid updates

Herman Schoenfeld 7 years ago
parent
commit
22cb39524b
2 changed files with 45 additions and 8 deletions
  1. 27 7
      src/core.utils/UDataSources.pas
  2. 18 1
      src/libraries/sphere10/UCommon.Data.pas

+ 27 - 7
src/core.utils/UDataSources.pas

@@ -194,16 +194,26 @@ end;
 
 
 function TAccountsDataSource.GetFilterKeys: TArray<TAccountKey>;
 function TAccountsDataSource.GetFilterKeys: TArray<TAccountKey>;
 begin
 begin
-  Result := FKeys.ToArray;
+  EnterLock;
+  try
+    Result := FKeys.ToArray;
+  finally
+    ReleaseLock;
+  end;
 end;
 end;
 
 
 procedure TAccountsDataSource.SetFilterKeys(const AKeys: TArray<TAccountKey>);
 procedure TAccountsDataSource.SetFilterKeys(const AKeys: TArray<TAccountKey>);
 var
 var
   i: integer;
   i: integer;
 begin
 begin
-  FKeys.Clear;
-  for i := Low(AKeys) to High(AKeys) do
-    FKeys.Add(AKeys[i]);
+  EnterLock;
+  try
+    FKeys.Clear;
+    for i := Low(AKeys) to High(AKeys) do
+      FKeys.Add(AKeys[i]);
+  finally
+    ReleaseLock;
+  end;
 end;
 end;
 
 
 procedure TAccountsDataSource.FetchAll(const AContainer: TList<TAccount>);
 procedure TAccountsDataSource.FetchAll(const AContainer: TList<TAccount>);
@@ -368,13 +378,23 @@ end;
 
 
 function TAccountsOperationsDataSource.GetAccounts: TArray<cardinal>;
 function TAccountsOperationsDataSource.GetAccounts: TArray<cardinal>;
 begin
 begin
-  Result := FAccounts.ToArray;
+  EnterLock;
+  try
+    Result := FAccounts.ToArray;
+  finally
+    ReleaseLock;
+  end;
 end;
 end;
 
 
 procedure TAccountsOperationsDataSource.SetAccounts(const AAccounts: TArray<cardinal>);
 procedure TAccountsOperationsDataSource.SetAccounts(const AAccounts: TArray<cardinal>);
 begin
 begin
-  FAccounts.Clear;
-  FAccounts.AddRange(AAccounts);
+  EnterLock;
+  try
+    FAccounts.Clear;
+    FAccounts.AddRange(AAccounts);
+  finally
+    ReleaseLock;
+  end;
 end;
 end;
 
 
 procedure TAccountsOperationsDataSource.FetchAll(const AContainer: TList<TOperationResume>);
 procedure TAccountsOperationsDataSource.FetchAll(const AContainer: TList<TOperationResume>);

+ 18 - 1
src/libraries/sphere10/UCommon.Data.pas

@@ -195,6 +195,8 @@ const
       procedure OnBeforeFetchAll(constref AParams: TPageFetchParams); virtual;
       procedure OnBeforeFetchAll(constref AParams: TPageFetchParams); virtual;
       procedure FetchAll(const AContainer : TList<T>); virtual; abstract;
       procedure FetchAll(const AContainer : TList<T>); virtual; abstract;
       procedure OnAfterFetchAll(constref AParams: TPageFetchParams); virtual;
       procedure OnAfterFetchAll(constref AParams: TPageFetchParams); virtual;
+      procedure EnterLock; inline;
+      procedure ReleaseLock; inline;
     public
     public
       constructor Create(AOwner: TComponent); override; overload;
       constructor Create(AOwner: TComponent); override; overload;
       destructor Destroy; override;
       destructor Destroy; override;
@@ -515,7 +517,12 @@ begin
   try
   try
      // Fetch underlying data if stale
      // Fetch underlying data if stale
      data := GC.AddObject( TList<T>.Create ) as TList<T>;
      data := GC.AddObject( TList<T>.Create ) as TList<T>;
-     FetchAll(data);
+     EnterLock;
+     try
+       FetchAll(data);
+     finally
+       ReleaseLock;
+     end;
 
 
      // Filter the data
      // Filter the data
      filters := AParams.GetSearchFilters;
      filters := AParams.GetSearchFilters;
@@ -591,6 +598,16 @@ procedure TCustomDataSource<T>.OnAfterFetchAll(constref AParams: TPageFetchParam
 begin
 begin
 end;
 end;
 
 
+procedure TCustomDataSource<T>.EnterLock;
+begin
+  FLock.Acquire;
+end;
+
+procedure TCustomDataSource<T>.ReleaseLock; inline;
+begin
+  FLock.Release;
+end;
+
 { TColumnFilterPredicate }
 { TColumnFilterPredicate }
 
 
 constructor TColumnFilterPredicate<T>.Create(const AFilter : TColumnFilter; const ADelegate : TApplyFilterDelegate<T>);
 constructor TColumnFilterPredicate<T>.Create(const AFilter : TColumnFilter; const ADelegate : TApplyFilterDelegate<T>);