浏览代码

* Patch from Pascal Riekenberg to make component loading thread safe (bug ID 35638)

git-svn-id: trunk@42248 -
michael 6 年之前
父节点
当前提交
ade808cb43
共有 2 个文件被更改,包括 25 次插入5 次删除
  1. 3 0
      rtl/objpas/classes/classesh.inc
  2. 22 5
      rtl/objpas/classes/reader.inc

+ 3 - 0
rtl/objpas/classes/classesh.inc

@@ -1442,6 +1442,7 @@ type
     FParent: TComponent;
     FFixups: TObject;
     FLoaded: TFpList;
+    FLock: TRTLCriticalSection;
     FOnFindMethod: TFindMethodEvent;
     FOnSetMethodProperty: TSetMethodPropertyEvent;
     FOnSetName: TSetNameEvent;
@@ -1456,6 +1457,8 @@ type
     FOnReadStringProperty:TReadWriteStringPropertyEvent;
     procedure DoFixupReferences;
     function FindComponentClass(const AClassName: string): TComponentClass;
+    procedure Lock;
+    procedure Unlock;
   protected
     function Error(const Message: string): Boolean; virtual;
     function FindMethod(ARoot: TComponent; const AMethodName: string): CodePointer; virtual;

+ 22 - 5
rtl/objpas/classes/reader.inc

@@ -609,14 +609,26 @@ begin
   If (Stream=Nil) then
     Raise EReadError.Create(SEmptyStreamIllegalReader);
   FDriver := CreateDriver(Stream, BufSize);
+  InitCriticalSection(FLock);
 end;
 
 destructor TReader.Destroy;
 begin
+  DoneCriticalSection(FLock);
   FDriver.Free;
   inherited Destroy;
 end;
 
+procedure TReader.Lock;
+begin
+  EnterCriticalSection(FLock);
+end;
+
+procedure TReader.Unlock;
+begin
+  LeaveCriticalSection(FLock);
+end;
+
 procedure TReader.FlushBuffer;
 begin
   Driver.FlushBuffer;
@@ -1476,12 +1488,17 @@ begin
           { Don't use Result.Name directly, as this would influence
             FindGlobalComponent in successive loop runs }
           ResultName := CompName;
-          while Assigned(FindGlobalComponent(ResultName)) do
-          begin
-            Inc(i);
-            ResultName := CompName + '_' + IntToStr(i);
+          Lock;
+          try
+            while Assigned(FindGlobalComponent(ResultName)) do
+            begin
+              Inc(i);
+              ResultName := CompName + '_' + IntToStr(i);
+            end;
+            Result.Name := ResultName;
+          finally
+            Unlock;
           end;
-          Result.Name := ResultName;
         end;
       end;