瀏覽代碼

Remove FDestroyCount.

Rika Ichinose 6 月之前
父節點
當前提交
c3f80014b4
共有 2 個文件被更改,包括 25 次插入8 次删除
  1. 24 6
      rtl/inc/objpas.inc
  2. 1 2
      rtl/inc/objpash.inc

+ 24 - 6
rtl/inc/objpas.inc

@@ -1171,16 +1171,32 @@ end;
     function TInterfacedObject._AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
 
       begin
-         _addref:=interlockedincrement(frefcount);
+         _addref:=frefcount;
+         if _addref>0 then
+           _addref:=interlockedincrement(frefcount)
+         else if _addref=0 then
+           begin
+             frefcount:=1; { Work non-atomically in the common case of refcount = 0 (typical state after the complete object construction). }
+             _addref:=1;
+           end;
       end;
 
     function TInterfacedObject._Release : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
 
       begin
-         _Release:=interlockeddecrement(frefcount);
+         _Release:=frefcount;
+         if _Release<=0 then { -1 means recursive call from destructor... 0 is impossible. }
+           exit;
+         if _Release=1 then
+           begin
+             _Release:=0; { Work non-atomically in the common case of refcount = 1 (typical state for the last owner... which is often the only owner). }
+             frefcount:=0;
+           end
+         else
+           _Release:=interlockeddecrement(frefcount);
          if _Release=0 then
            begin
-           if interlockedincrement(fdestroycount)=1 then
+             frefcount:=-1; { Prevent recursive _Release from destroying twice (bug 32168). }
              self.destroy;
            end;
       end;
@@ -1190,7 +1206,6 @@ end;
    begin
      // We must explicitly reset. Bug ID 32353
      FRefCount:=0;
-     FDestroyCount:=0;
      inherited Destroy;
    end;
 
@@ -1199,13 +1214,16 @@ end;
       begin
          { we need to fix the refcount we forced in newinstance }
          { further, it must be done in a thread safe way        }
-         declocked(frefcount);
+         if frefcount=1 then
+           frefcount:=0 { Work non-atomically in the common case of refcount = 1 (usual state before AfterConstruction). }
+         else
+           declocked(frefcount);
       end;
 
     procedure TInterfacedObject.BeforeDestruction;
 
       begin
-         if frefcount<>0 then
+         if frefcount>0 then { Legitimate values: -1 if destroying by _Release, 0 if destroying manually. }
            HandleError(204);
       end;
 

+ 1 - 2
rtl/inc/objpash.inc

@@ -353,8 +353,7 @@
 
        TInterfacedObject = class(TObject,IUnknown)
        protected
-          FRefCount : longint;
-          FDestroyCount : longint;
+          FRefCount : longint; { -1 = destroying. }
           { implement methods of IUnknown }
           function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid : tguid;out obj) : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};
           function _AddRef : longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF};