Boost logo

Boost :

From: William Kempf (williamkempf_at_[hidden])
Date: 2001-08-31 10:15:21


From: "Peter Dimov" <pdimov_at_[hidden]>
>From: "William Kempf" <williamkempf_at_[hidden]>
>> >You need to remember whether 'join' was called anyway (for the
destructor.)
>> >So you can easily avoid the undefined behavior.
>>
>>Only if you retain the strict rules about adoption.
>
>I stated about three times that this will be, indeed, the case, and adopted
>threads will still invoke undefined behavior when joined.

The issue, again (we both keep saying the same thing here so we're both
getting frustrated), is that you can not tell when a thread is adopted.
Later on in this message you accuse me of always adopting threads in the
default constructor even when the thread was created by the Boost.Threads
library, and while I don't agree with that view it is still one way of
looking at things. For your thread_ref design are you going to make the
same assumption? If you don't the user is left in a quandry since he
doesn't know if the thread has been adopted or not, and in the end he must
assume that all such threads are adopted any way. So the end result in both
cases is that he can't call "join" on thread_ref objects returned from
current(). So, in practice, he's likely going to only call "join" once for
every thread any way.

And regardless of this, I've still not seen how the current thread design
prevents such a thread_ref design from being implemented (except for the
"initial thread" case, which you've not shown how this could be treated
differently by either Boost.Threads or POSIX/Win32).

>>I realize that you want
>>to make adoption fully undefined behavior,
>
>This is not being discussed in this subthread. ;-) In this subthread,
>adoption works as you've defined it to work. Fifth time: adopted threads
>invoke undefined behavior when joined.

Only by orthoganility to any thread object created through the default
constructor. This is the crux of the whole thing. The current design does
not treat adopted threads any differently from Boost.Threads created
threads. You view this as "all default constructed threads are adopted",
but I don't agree with this view point as I'll explain later.

>>It's not really a general question. Obviously all operations on the
thread
>>object must be thread safe (and they will be). The only one that can be
>>questionable is "join", but this operation is thread safe simply because
>>it's undefined behavior to call it more than once.
>
>Exactly. Obviously all operations on the thread are thread safe, but join
>is
>not. I don't see any specific reasons for this inconsistency.

But join *IS* thread safe because conforming programs can call it only once.
  There are *NO* race conditions here, so by definition it's thread safe.

Even if you change the rules to allow join to be called more than once (I'm
not going to) then join would still be thread safe... the implementation
would just have to synchronize the "joinable" state. So I *REALLY* don't
know what your argument is along these lines.

>>As for the assertion that "you can't detect from a conforming program how
>>many threads joined x simultaneously", this is simply not true, since a
>>conforming program CAN'T call "join" more than once, no matter what
>>thread(s) it's called from.
>
>We're in the context of case 3. A conforming program can call join mutliple
>times, from different threads, and every single call to join conforms to
>your definition.

You've lost me. Case 3 doesn't exist, and if it would it would still be
thread safe.

>> >I don't see why this complicates thread adoption; it's a separate issue.
>> >Joining an adopted thread will invoke undefined behavior, as usual.
>>
>>In a conforming program you can not tell if a thread is "adopted" or not
>>when you call "current" (or in our case the default constructor).
>
>Your current design always adopts on default construction, does it not?

Like I've said, you can view this as the case, but it's technically not. If
a thread must keep state information beyond that which the native thread
maintains then the act of adopting a thread would include the construction
of such state. For Boost.Threads native threads this construction wouldn't
take place here, since it would have occurred when the thread was created.
Your point of view is valid in the current implementation only because we
don't have any such state to maintain.

>You could even go further and separate the two thread classes, avoiding the
>undefined behavior altogether. boost::adopted_thread will simply not have a
>join member.

I'd name it boost::current_thread. This would be a valid seperation and
might eliminate a few programmer errors. However, it wouldn't change any of
this dicussion and would make the design less than optimal when the standard
can address these issues. I had actually thought about this during the
design.

>On a more serious note, you can't avoid the synchronization objects for the
>state when you expand the design, and the time overhead for the first join
>will be unmeasurable.

But an expanded design should be built on top, so that users only pay for
what they use ;).

>This is a general problem with these discussions. We have something (the
>current design) and we try to talk about it but we also try to foresee how
>it'd look in the future when the additional functionality is added, and
>everyone sees slightly different things.

I don't see any "additional functionality" being added, except for further
operations on thread objects such as cancellation, priority control, etc.
None of these apply to the current discussion and don't cause any "general
problem with these discussions". What I *DO* see is other concepts being
built on top, but this applies only if such concepts can't be built on
what's there (and more importantly that they *COULD* be built on the native
libraries in a portable manner, which would highlight a design flaw).
There's several issues with building a thread_ref design, but they aren't
caused by the current Boost.Threads design, but are instead caused by the
available native libraries. Any solution you can do with the native
libraries should be doable with Boost.Threads as well.

Bill Kempf

--
Peter Dimov
Multi Media Ltd.
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk