Could you work it with two semaphores.
Semaphore (a) is always gotten with AttemptSemaphoreShared() except by the destructor method, witch does an ObtainSemaphore().
Semaphore (b) is the used for locking purposes.
All the methods lock (a) the lock (b) then free the lock on (a)
For most methods an AttemptSemaphoreShared() on (a) will succeed, if it doesn't then someone is running the destructor().