I mean that the entire type interface is "as thread-safe as a
POSIX-thread-safe function".
In other words (quoting the Posix standard): "A function that
may be safely invoked concurrently by multiple threads." All of
the member functions of boost::shared_ptr meet that requirement.
In this case, of course, we're not talking about just functions,
but about an in memory object. And the Posix definitions for
memory access say that "Applications shall ensure that access to
any memory location by more than one thread of control (threads
or processes) is restricted such that no thread of control can
read or modify a memory location while another thread of control
may be modifying it." Which is exactly what boost::shared_ptr
requires.
I disagree that boost::smart_ptr meets the definition of POSIX
"thread-safe". Why? Because only a subset of, not all of, the
interface can be safely invoked concurrently by multiple
threads (example reset).
I don't think so. Could you post a scenario where reset (or any
other function) fails when invoked from different threads. Or
for that matter, when any combination of functions fails when
called from different threads, providing the basic requirement
is met: if you're modifying the object (and reset() modifies
it), then if any other thread accesses the same object (the same
instance of boost::shared_ptr---client code shouldn't have to be
concerned with what different instances of the object share),
access must be synchronized. This is exactly the same
requirement as for any Posix function. (There are a very few IO
functions which give an even stronger guarantee, i.e. read and
write.) In other words, given:
boost::shared_ptr< T > p1( new T ) ;
boost::shared_ptr< T > p2( p1 ) ;
you should be able to do p1.reset() in a thread, regardless of
what other threads might be doing with p2, but if you do
p1.reset() in one thread, all accesses to p1 must be
synchronized if p1 is accessed from any other thread. If I
understand correctly, boost::shared_ptr guarantees this, and
that's all that Posix guarantees for it's thread-safe functions.
First off (please correct me if I'm wrong) POSIX only defines
"thread-safe" for functions and that definition is:
3.396 Thread-Safe
A function that may be safely invoked concurrently by multiple
threads. Each function defined in the System Interfaces volume
of IEEE Std 1003.1-2001 is thread-safe unless explicitly stated
otherwise. Examples are any "pure" function, a function which
holds a mutex locked while it is accessing static storage, or
objects shared among threads.
It also defines guarantees concerning "memory" accesses, see
above. These are perhaps even more relevant than the function
guarantees when an object is involved---a boost::shared_ptr,
after all, is a replacement for a raw pointer, not for some
function.
So first the POSIX definition must be extended to the notion of
type (ie class in C++). One way to do that is to take the simple
and common view of all member functions being free functions that
take a hidden this pointer. Then we apply the POSIX definition to
that set of functions and if *every* function (minus destructor)
is POSIX thread-safe then we can say the class is "thread-safe".
boost::share_ptr fails this criteria for example "reset" fails
when supplied with identical "this" pointers.
And localtime_r fails when supplied with identical buffers.
That's a foregone. Posix doesn't require thread-safe functions
to be able to be called on the same objects from different
threads. Because that's not reasonable; if you want an extreme
example, think of setjmp (which Posix defines as thread safe).
In other words, it is what N2410
proposed to call "strong thread-safe" also as Chris MT has
called in some other posts. However, note that since "strong
thread-safe" is simply the most natural extension of POSIX
"thread-safe" to C++ types, then "thread-safe" without
qualification should mean "strong thread-safe" and that is
consistent with your claim that "the experts in the field,
more or less corresponds to the Posix definition". It's just I
don't know where you got your definition of POSIX
"thread-safe" because that's not what I recall from the POSIX
document?
If you'd read the document you'd site, it points out quite
clearly that the so-called "strong thread-safety" is a very
naïve meaning for thread safety. As pointed out above, Posix
doesn't require it, and in fact, no expert that I know defines
thread-saftey in that way.
Finally, I will note N2519
which claims that the level of thread-safe that
boost::shared_ptr provides is "not widely recognized or named
in the literature" and that is consistent with my experience
as well.
It's curious that in the sentence immediately following this
statement, he cites a document that does "recognize" this level
of thread safety. And if this level of thread safety has no
special name, it's probably because it is what is generally
assumed by "thread-safety" by the experts in the field; I've
never seen any article by an expert in threading that spoke of
"strong thread-safety" other than to explain that this is not
what is meant by "thread-safety".