Windows: AFSDeleteObjectInfo InterlockedExchange
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 22 Mar 2013 04:54:36 +0000 (00:54 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Fri, 22 Mar 2013 14:32:23 +0000 (07:32 -0700)
Use InterlockedExchangePointer to disconnect the ObjectInformationCB
pointer from the caller.  This ensures that only one thread can
successfully call AFSDeleteObjectInfo on the same object at a time.

Change-Id: Ie70f52fc443f88c3cb4be41f12caa91466d92905
Reviewed-on: http://gerrit.openafs.org/9644
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp

index d607b4f..1854c0c 100644 (file)
@@ -6822,13 +6822,13 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
 {
 
     BOOLEAN bAcquiredTreeLock = FALSE;
-    AFSObjectInfoCB *pObjectInfo = (*ppObjectInfo);
-    BOOLEAN bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
+    AFSObjectInfoCB *pObjectInfo = NULL;
+    BOOLEAN bHeldInService;
     AFSObjectInfoCB * pParentObjectInfo = NULL;
     AFSFileID FileId;
     LONG lCount;
 
-    if ( BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_ROOT_VOLUME))
+    if ( BooleanFlagOn( (*ppObjectInfo)->Flags, AFS_OBJECT_ROOT_VOLUME))
     {
 
         //
@@ -6841,9 +6841,19 @@ AFSDeleteObjectInfo( IN AFSObjectInfoCB **ppObjectInfo)
         return;
     }
 
+    pObjectInfo = (AFSObjectInfoCB *) InterlockedCompareExchangePointer( (PVOID *)ppObjectInfo,
+                                                                         NULL,
+                                                                         (PVOID *)ppObjectInfo);
+
+    if ( pObjectInfo == NULL)
+    {
+
+        return;
+    }
+
     ASSERT( pObjectInfo->ObjectReferenceCount == 0);
 
-    (*ppObjectInfo) = NULL;
+    bHeldInService = BooleanFlagOn( pObjectInfo->Flags, AFS_OBJECT_HELD_IN_SERVICE);
 
     if( !ExIsResourceAcquiredExclusiveLite( pObjectInfo->VolumeCB->ObjectInfoTree.TreeLock))
     {