An assertion in buf_Recycle() was being triggered when a cm_buf_t
object was supposed to be in the free buffer list but wasn't.
buf_Recycle() was racing with another thread. The test for
refCount == 0 was performed while holding the buf_globalLock
exclusively but the InterlockedDecrement(refCount) in buf_Release()
was performed without holding buf_globalLock at all. buf_globalLOck
must be held at least as a read lock. Otherwise, the refCount can
reach 0 prior to the thread blocking for exclusive access to the
buf_globalLock. This provides buf_Recycle() which is holding
buf_globalLock the opportunity to race.
The solution is to make sure that buf_Release() always holds
buf_globalLock as a read lock and then use buf_ReleaseLocked()
to perform the actual decrement and test.