Boost logo

Boost :

Subject: Re: [boost] Release managers: Boost.Thread breaking changes in 1.53
From: Lars Viklund (zao_at_[hidden])
Date: 2012-12-31 09:17:46


On Mon, Dec 31, 2012 at 12:39:22AM +0100, Vicente J. Botet Escriba wrote:
> Le 30/12/12 21:50, Artyom Beilis a écrit :
>>> ________________________________
>>> From: Vicente J. Botet Escriba <vicente.botet_at_[hidden]>
>>> To: boost_at_[hidden]
>>> Sent: Sunday, December 30, 2012 1:58 PM
>>> Subject: [boost] Release managers: Boost.Thread breaking changes in 1.53
>>>
>>> Hi,
>>>
>>> there has been some threads about the following Boost.Thread breaking change in release 1.53.
>>>
>>> "Breaking changes when BOOST_THREAD_VERSION==3 (Default value since Boost 1.53):
>>>
>>> There are some new features which share the same interface
>>> but with different behavior. These breaking features are provided
>>> by default when BOOST_THREAD_VERSION is 3, but the user can however
>>> choose the version 2 behavior by defining the corresponding macro.
>>> As for the deprecated features, these broken features will be only
>>> available until boost 1.55.
>>>
>>> * [@http://svn.boost.org/trac/boost/ticket/6266 #6266] Breaking change: thread destructor should call terminate if joinable.
>>> * [@http://svn.boost.org/trac/boost/ticket/6269 #6269] Breaking change: thread move assignment should call terminate if joinable.
>>> "
>>>
>> Now I would like to know what is the rationale behind calling std::terminate instead
>> of deaching the thread?
>>
>> Usually std::terminate is called in case no actions can be done,
>> like uncatched exception is thrown.
>>
>> This is sort of smarter "assert()" or even I would say, we can't define the
>>
>> behavior, but instead of making it "undefined" lets call std::terminate.
>>
>> The biggest question what advatnage does it give to the user? Properly
>> constructed program should not get to std::terminate, unless there is a bug,
>> on the other hand some users (and I used to be one of them till I switched
>> to different threading library for unrelated reasoms) expect defined behavior
>> of detaching the thread...
> This is exactly the reason the standard committee made these changes,
> that is, provide an interface that force the user to make correct
> programs. See
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2880.html for
> part of the rationale.

For as long as I've used the library, I've known that it's "safe" to
abandon the controlling boost::thread object because it automatically
detaches for me. Why? Because I either:

* know that my thread-of-execution is fine with being unconditionally
  clobbered at program shutdown; or
* have other synchronization to ensure that the thread-of-execution is
  sufficiently over when the program is over.

This is also what I've mentioned to countless people as a feature of the
library, the ability to simply discard the boost::thread object when you
don't need it, and allowing its use in temporary contexts.

I count several places in my codebase where I pass a shared_ptr<thread>
around, knowing that if someone cares about the lifetime, they'll hold
on to it for future joining. If not, they can just drop it and RAII
takes care of detaching. Yes, that code can be "fixed" by having a
custom deleter that also detaches, but it's not a trivial task to
identify all the places where it occurs, particularly not for a third
party.

There's likely TONS of code out there that leverages this that will be
bit by the change.

You want to know the real-life implication of this? Distributions
already have a more or less glacial and variable adoption rate of new
Boost, due to perceived and actual breakages. This will add yet another
thing that will make life more miserable for packagers and will cause
even more local distribution patching.

Not all software is built in isolation. In a typical OS distro, you have
one single Boost version, and a whole universe of software that needs to
build with it. Actively making it worse isn't exactly good PR.

I'm strongly opposed to making such a breaking change for some odd
corner case like "somone has a boost::thread in some singleton", when
most use cases aren't like that. I may be missing something significant
in the linked paper, but I can't see how such a draconian measure is a
good thing for something that has existing code written around it.

For std::thread, sure, no code is written around it and C++ is rife with
fun quirks you have to take into consideration.

>> Bottom line, what does the std library compience give us?
> There will be already less confusion. See all the questions about why
> the behaviors are different in the web.

Maybe that's a fault of the C++11 thread, not Boost.Thread? If you go
and base something off something and change things, maybe the onus is on
_them_ to ensure that any changes in behaviour are violently advertised?

This list thread (heh) is pretty much the _first_ I ever hear about this
debacle. None of the "it's deprecated releases ago" have I ever seen,
and I, unlike most people, read the lists and (used to) hang in #boost.

What chance does your average packager or developer have to notice this?

-- 
Lars Viklund | zao_at_[hidden]

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