No. The most common cause of this behavior is that a thread is trying to acquire a lock it already owns or else trying to release a lock it doesn't own. Use ASSERT statements to tell when this is happening. Be sure to #include utility.h to use ASSERT.
In C++, everything is pass by value. So in
void BBuffer::Read(char *c)
you must do:
*c=buf[nextout];
and not
c=&buf[nextout];
The former just uses the unchangable pointer c to change what c points to. That's what you want. When the function ends, c will be unchanged, but what c points to will have changed. The latter tries to change the pointer. This will only work locally. Once the function is done, the pointer that was passed in as the argument won't have changed.