This is a design question that has been bugging me for a while now. It is pretty simple really, when you provide datastructure libraries do you build in the thread-safety primitives or just provide the constructs and let the system using it decide on how to implement the actual operations.
A quick example, a Circular buffer which supports a Producer, Consumer model. 2 Methods, Get and Write, each updates a global variable fill count. Now, do you just provide the mutexes to lock and let the code using the buffer grab the mutexes OR do you the locking internally and provide mutual exclusion out of the box.
STL seems to take the approach of doing it externally, but there are performance reasons of why you would want to provide finer grained locking.