David Hopwood wrote:
Martin Sebor wrote:
David Hopwood wrote:
[...]
That defies common sense. Exiting a function that has declared a pthreads
synchronization object with auto scope, without having destroyed that
object, will scribble over the memory holding the object representation.
This is no different to doing:
pthread_mutex_t x;
assert(pthread_mutex_init(&x) == 0);
(char *) &x = 42; // undefined behaviour
Consider:
pthread_xxx_t x, y;
pthread_xxx_init (&x);
memcpy (&y, &x, sizeof y);
memset (&x, 42, sizeof x);
memcpy (&x, &y, sizeof y);
Is x valid after the last call to memcpy?
No. The call to memset immediately causes undefined behaviour.
If the call to memset were omitted, the second memcpy would still cause
undefined behaviour, because the representation of the pthread_xxx_t may
have changed since those bytes were read. In general, it must be assumed
that the representation of an initialized synchronization object can be
accessed asynchronously at any time. To require otherwise would disallow
some perfectly reasonable implementations.
Thanks. I had not considered such implementations. I found text
on the pthread_mutex_init() page that supports this (see below).
Similar text appears on pages describing requirements on all
the other pthread_xxx_init() pages but not on the
pthread_xxxattr_init() pages.
So the intent is for synchronization objects not to be copyable
and implementations can keep track of their addresses and thus
detect double initialization.
However, the same restriction doesn't appear to apply to the
attributes objects.
pthread_mutex_init():
Only mutex itself may be used for performing synchronization.
The result of referring to copies of mutex in calls to
pthread_mutex_lock(), pthread_mutex_trylock(),
pthread_mutex_unlock(), and pthread_mutex_destroy() is
undefined.
Martin
|