Windows: ObjectInfo RefCount 0 <-> 1 transitions
authorJeffrey Altman <jaltman@your-file-system.com>
Fri, 19 Oct 2012 15:26:21 +0000 (11:26 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Sun, 28 Oct 2012 01:58:10 +0000 (18:58 -0700)
When the reference count transitions from 0 <-> 1 ensure that the
ObjectInfoLock is held exclusive to prevent the current thread from
altering the state while another thread is holding the ObjectInfoLock
shared in order to conditionally perform an action based upon
the the reference count being zero.

Change-Id: I5bcf384a0ea90e4896e55b537e92112ac3791a4c
Reviewed-on: http://gerrit.openafs.org/8257
Reviewed-by: Rod Widdowson <rdw@steadingsoftware.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

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

index fc85688..6a7a938 100644 (file)
@@ -6543,10 +6543,31 @@ AFSObjectInfoIncrement( IN AFSObjectInfoCB *ObjectInfo)
 
     LONG lCount;
 
-    AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
-                      TRUE);
+    if ( ObjectInfo->ObjectReferenceCount == 0)
+    {
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+    }
+    else
+    {
+
+        AFSAcquireShared( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                          TRUE);
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        if ( lCount == 1)
+        {
 
-    lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+            AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+            AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                            TRUE);
+        }
+    }
 
     AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
 
@@ -6564,6 +6585,19 @@ AFSObjectInfoDecrement( IN AFSObjectInfoCB *ObjectInfo)
 
     lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
 
+    if ( lCount == 0)
+    {
+
+        lCount = InterlockedIncrement( &ObjectInfo->ObjectReferenceCount);
+
+        AFSReleaseResource(&ObjectInfo->NonPagedInfo->ObjectInfoLock);
+
+        AFSAcquireExcl( &ObjectInfo->NonPagedInfo->ObjectInfoLock,
+                        TRUE);
+
+        lCount = InterlockedDecrement( &ObjectInfo->ObjectReferenceCount);
+    }
+
     AFSReleaseResource( &ObjectInfo->NonPagedInfo->ObjectInfoLock);
 
     return lCount;