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/6229 #6229] Rename the unique_future to future following the c++11. * [@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. " I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes? Best, Vicente

On Sun, Dec 30, 2012 at 12:58 PM, Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> wrote:
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
BOOST_THREAD_VERSION = 2? I'm not a fan of breaking backwards compatibility, especially if it happens silently without compile errors. -- Olaf

2012/12/30 Olaf van der Spek <ml@vdspek.org>
BOOST_THREAD_VERSION = 2?
I'm not a fan of breaking backwards compatibility, especially if it happens silently without compile errors.
i do agree. is there a big warning when BOOST_THREAD_VERSION is set to 3? we have a lot of code using boost;thread , and silently accept code that could break could be a big problem if the user is not aware of it.

On 2012-12-30 12:58, Vicente J. Botet Escriba wrote:
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
Given that the breaking changes are due to alignment with C++11, I think that this is a good reason to break compatibility per default. Users have upgraded to a new version of Boost, so some upgrade cost is expected. If users are unwilling (or unable) to upgrade their implementation, they can easily revert to BOOST_THREAD_VERSION 2.

On Sun, Dec 30, 2012 at 4:15 PM, Bjorn Reese <breese@mail1.stofanet.dk> wrote:
On 2012-12-30 12:58, Vicente J. Botet Escriba wrote:
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
Given that the breaking changes are due to alignment with C++11, I think that this is a good reason to break compatibility per default. Users have upgraded to a new version of Boost, so some upgrade cost is expected. If users are unwilling (or unable) to upgrade their implementation, they can easily revert to BOOST_THREAD_VERSION 2.
No, they can't. Some users use the Boost libs provided by their (Linux) distribution. They can't just #define BOOST_THREAD_VERSION 2 If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action from the developer himself, should not come with such costs. -- Olaf

on Sun Dec 30 2012, Olaf van der Spek <ml-AT-vdspek.org> wrote:
On Sun, Dec 30, 2012 at 4:15 PM, Bjorn Reese <breese@mail1.stofanet.dk> wrote:
On 2012-12-30 12:58, Vicente J. Botet Escriba wrote:
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
Given that the breaking changes are due to alignment with C++11, I think that this is a good reason to break compatibility per default. Users have upgraded to a new version of Boost, so some upgrade cost is expected. If users are unwilling (or unable) to upgrade their implementation, they can easily revert to BOOST_THREAD_VERSION 2.
No, they can't. Some users use the Boost libs provided by their (Linux) distribution. They can't just #define BOOST_THREAD_VERSION 2
If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action from the developer himself, should not come with such costs.
There are no absolutes in this area. Upgrades of Boost are allowed to break code. In general we try to avoid it, but sometimes progress is more important than backward compatibility. When to break code, how much warning users get, what their alternatives are, etc., are judgement calls we leave to library maintainers. -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

----- Original Message -----
From: Dave Abrahams <dave@boostpro.com>
If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action
from
the developer himself, should not come with such costs.
[snip] In general we try to avoid it, but sometimes progress is more important than backward compatibility. [snip]
Probably I would find myself in minority or hated by many Boost **developers** but I would say clearly that there are hundreds thounds of C++ developerds and thousands of project that break because Boost breaks API. HUGE amount of man hours are spent just because Boost breaks stuff. I would like to provide a recent quote of Linus Torvalds regarding the kernel: > WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? > [...] The fact that you then try to make *excuses* for breaking user space, Of course Boost is not Linux kernel, (if Linux kernel was managed as Boost I would switched to FreeBSD) and it not as important to maintain backward compatibility from user perspective, but this is something we MUST learn. There should be VERY STRONG reasons for breaking API, not just because new iterface is much better. This reminds me other discusstion I started: http://thread.gmane.org/gmane.comp.lib.boost.devel/237276 About security fixed and updates on which I got no reactions... Bottom line: - Boost does not provide fixes of critical bugs, for stable released - Boost does not provide security updates for stable released - Technically boost does not maintain stable releases at all - Boost breaks API. So how can it be used in some long running projects? The answer it can't, you either stuck with a release with huge holes and critical bugs or you break your software trying to upgrate and keep up with some new progressive and great idea some library brings. If boost does not maintain stable releases it must not break its API.
-- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost
This is just a sad reality Regards, Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

On December 31, 2012 1:08:36 AM Artyom Beilis <artyomtnk@yahoo.com> wrote:
Probably I would find myself in minority or hated by many Boost **developers** but I would say clearly that there are hundreds thounds of C++ developerds and thousands of project that break because Boost breaks API.
HUGE amount of man hours are spent just because Boost breaks stuff.
Yes, you are probably right but that is a price that has to be paid to move the project forward. I'm not referring to the particular changes in Boost.Thread now, just a general thought. Realistically, API breaks are inevitable as long as Boost evolves. We can try to reduce the effect, we can provide compatibility layers but in the end there is some change that has to be done and which cannot be reasonably covered. And compatibility layers cannot be maintained forever as well. I've done a few Boost upgrades in different projects (large and not). Quite some work has to be done but it's quite doable if the project is not dead. If it is - who cares.
I would like to provide a recent quote of Linus Torvalds regarding the kernel:
> WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? > [...] The fact that you then try to make *excuses* for breaking user space,
Of course Boost is not Linux kernel, (if Linux kernel was managed as Boost I would switched to FreeBSD) and it not as important to maintain backward compatibility from user perspective, but this is something we MUST learn.
No disrespect to Linus but I can't say I agree with his strong position (and especially with his communication style, BTW). Bugs must be fixed where they are, be that kernel or userspace. Trying to cover them only makes things worse in the long run. Again, it's my opinion in general and not about the particular issue the quote is taken from.
There should be VERY STRONG reasons for breaking API, not just because new iterface is much better.
Agreed, if the new interface can be provided alongside with the old one. Deprecation periods are for this.
This reminds me other discusstion I started:
http://thread.gmane.org/gmane.comp.lib.boost.devel/237276
About security fixed and updates on which I got no reactions...
Personally, I would like to see that happen. Am I ready to make that happen? I don't think so. Releasing Boost is a hard work which includes testing, documenting and Release managers know what else. I'm not prepared to do that for point releases. As a user, I'd rather upgrade my projects to newer releases of Boost or particular Boost libraries, it's not a big problem to me. As a library developer I would probably backport critical bug fixes to previous releases but that still leaves a lot of work to actually release them and apparently noone has the resource for that.
So how can it be used in some long running projects?
The answer it can't, you either stuck with a release with huge holes and critical bugs or you break your software trying to upgrate and keep up with some new progressive and great idea some library brings.
I think you exaggerate. Boost is clearly used in many projects, including big ones and upgrade costs are coped with. To make things clear. I'm not saying that the API breaks are good; they are not. It's the necessary evil to move forward. And if the project is not moving, it is dead.

On Mon, 31 Dec 2012 02:19:15 +0400 Andrey Semashev <andrey.semashev@gmail.com> wrote:
To make things clear. I'm not saying that the API breaks are good; they are not. It's the necessary evil to move forward. And if the project is not moving, it is dead.
API breaks are good and expected when transitioning to next major release which was previously developed as unstable branch for some time. But Boost doesn't have such a branch or major/stable releases as far as Boost's users are concerned, while most other projects do. So basically Boost moves the burden to differentiate bugfixes and disruptive new features on end users. No wonder they don't like it.

On 30/12/12 22:08, Artyom Beilis wrote:
Probably I would find myself in minority or hated by many Boost **developers** but I would say clearly that there are hundreds thounds of C++ developerds and thousands of project that break because Boost breaks API.
HUGE amount of man hours are spent just because Boost breaks stuff.
I would like to provide a recent quote of Linus Torvalds regarding the kernel:
WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? [...] The fact that you then try to make *excuses* for breaking user space,
Boost is not even a runtime. Comparing Boost and the Linux kernel makes absolutely no sense.

on Sun Dec 30 2012, Artyom Beilis <artyomtnk-AT-yahoo.com> wrote:
HUGE amount of man hours are spent just because Boost breaks stuff.
People know what they're getting when they use Boost, and if they don't, we should be more explicit about telling them.
I would like to provide a recent quote of Linus Torvalds regarding the kernel:
> WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? > [...] The fact that you then try to make *excuses* for breaking user space,
Of course Boost is not Linux kernel, (if Linux kernel was managed as Boost I would switched to FreeBSD) and it not as important to maintain backward compatibility from user perspective, but this is something we MUST learn.
I don't agree. Boost wouldn't be what it is today if we had a rule like that. Every project is entitled to its own policies, and I don't disagree with Linus on this point because he is the steward of the Linux kernel. However, as you say, Boost is not the Linux kernel. -- Dave Abrahams BoostPro Computing Software Development Training http://www.boostpro.com Clang/LLVM/EDG Compilers C++ Boost

Den Sun, 30 Dec 2012 22:08:36 +0100 skrev Artyom Beilis <artyomtnk@yahoo.com>:
Probably I would find myself in minority or hated by many Boost **developers** but I would say clearly that there are hundreds thounds of C++ developerds and thousands of project that break because Boost breaks API.
HUGE amount of man hours are spent just because Boost breaks stuff.
I would like to provide a recent quote of Linus Torvalds regarding the kernel:
WE DO NOT BREAK USERSPACE! Seriously. How hard is this rule to understand? [...] The fact that you then try to make *excuses* for breaking user space,
Of course Boost is not Linux kernel, (if Linux kernel was managed as Boost I would switched to FreeBSD) and it not as important to maintain backward compatibility from user perspective, but this is something we MUST learn.
I disagree. As a boost user!
There should be VERY STRONG reasons for breaking API, not just because new iterface is much better.
Again, I disagree. One of the purposes of boost has always been to break new ground, to the point of submitting existing libraries for standardization. This is quite unlike *any other* c++ library out there. Sure, others occasionally do the same, but it is in boost's core values, so to speak. That said, I think a reasonable transition should be available. I'm not advocating breaking things, just because we can. If a library maintainer comes up with a better interface, it would be very nice to provide the old one as well for some releases, probably as default first, then as backup next, before it's finally removed. Obviously, if the compiler could be persuaded to give warnings as well that would be even better. But none of this should limit the flow of *progress*. We *want* to see how new interfaces can work!
This reminds me other discusstion I started:
http://thread.gmane.org/gmane.comp.lib.boost.devel/237276
About security fixed and updates on which I got no reactions...
Bottom line:
- Boost does not provide fixes of critical bugs, for stable released - Boost does not provide security updates for stable released
- Technically boost does not maintain stable releases at all - Boost breaks API.
So how can it be used in some long running projects?
The answer it can't, you either stuck with a release with huge holes and critical bugs or you break your software trying to upgrate and keep up with some new progressive and great idea some library brings.
I think (though I've not fully studied the fine print here) that this will become easier in the modularized boost. [snip]
This is just a sad reality
It's a consequence of the current model and the core purpose of boost. /Brian

On 2012-12-30 21:42, Dave Abrahams wrote:
on Sun Dec 30 2012, Olaf van der Spek <ml-AT-vdspek.org> wrote:
If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action from the developer himself, should not come with such costs. There are no absolutes in this area. Upgrades of Boost are allowed to break code. In general we try to avoid it, but sometimes progress is more important than backward compatibility. When to break code, how much warning users get, what their alternatives are, etc., are judgement calls we leave to library maintainers.
I think the main problem is expectation management: Since more than 50 releases there has been one minor release number change (1.x -> 1.(x+1)) after the other. No distinction. It would be much easier (for users) if there were rules about what kind of library changes are to be expected for what kind of release number changes. For example: Micro releases x.y.z -> x.y.(z+1): - Bug fixes Minor release x.y.z -> x.(y+1).0: - Bug fixes - Performance enhancements - backward compatible extensions Major release x.y.z -> (x+1).0.0: - all of the above - breaking changes Major releases should be rare, of course, but if they occur, library users would know that they have to expect breaking changes. Maybe this can be achieved with distributed boost? Regards, Roland

On 31 December 2012 07:44, Roland Bock <rbock@eudoxos.de> wrote:
Since more than 50 releases there has been one minor release number change (1.x -> 1.(x+1)) after the other. No distinction.
That's not actually true. See: http://www.boost.org/users/history/ e.g. 1.46.1, 1.34.1, 1.33.1. They've happened less often since we adopted a regular release schedule.
Maybe this can be achieved with distributed boost?
Distributed is largely irrelevant here, unless there are volunteers to maintain a stable fork? Improved branching could help, but the idea seems to be that modularization will change the way releases are handled.

On 2012-12-31 14:51, Daniel James wrote:
On 31 December 2012 07:44, Roland Bock <rbock@eudoxos.de> wrote:
Since more than 50 releases there has been one minor release number change (1.x -> 1.(x+1)) after the other. No distinction. That's not actually true. See:
http://www.boost.org/users/history/
e.g. 1.46.1, 1.34.1, 1.33.1. They've happened less often since we adopted a regular release schedule. Still, it is hard to know when to expect breaking changes.
Maybe this can be achieved with distributed boost? Distributed is largely irrelevant here, unless there are volunteers to maintain a stable fork? Improved branching could help, but the idea seems to be that modularization will change the way releases are handled.
Sorry, I meant modularized.

On Sun, Dec 30, 2012 at 4:15 PM, Bjorn Reese <breese@mail1.stofanet.dk> wrote:
On 2012-12-30 12:58, Vicente J. Botet Escriba wrote:
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
Given that the breaking changes are due to alignment with C++11, I think that this is a good reason to break compatibility per default. Users have upgraded to a new version of Boost, so some upgrade cost is expected. If users are unwilling (or unable) to upgrade their implementation, they can easily revert to BOOST_THREAD_VERSION 2. No, they can't. Some users use the Boost libs provided by their (Linux) distribution. They can't just #define BOOST_THREAD_VERSION 2 Well, I have made the effort to make it possible for a boost_thread
Le 30/12/12 20:48, Olaf van der Spek a écrit : library compiled with BOOST_THREAD_VERSION 3, to accept code compiled with version BOOST_THREAD_VERSION 2. Of course there could be an incompatibility if two part of the application defines BOOST_THREAD_VERSION with different values.
If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action from the developer himself, should not come with such costs. I agree with you, and I believed that letting the user 3 releases to move to the new behavior was enough. It seems that I was wrong.
Best, Vicente

On December 30, 2012 05:38:44 PM Vicente J. Botet Escriba wrote:
Le 30/12/12 20:48, Olaf van der Spek a écrit :
If I move from boost::thread to std::thread then yes, I'm expecting some costs moving. But merely 'upgrading' Boost, which might not require any action from the developer himself, should not come with such costs.
I agree with you, and I believed that letting the user 3 releases to move to the new behavior was enough. It seems that I was wrong.
I can't comment on the specifics of the breaking change, but on the topic of "3 releases is enough": with quarterly releases, this is only 9 months which is very short, IMHO. I would guess that many clients of boost upgrade maybe once a year or so --- in large part due to the fact that Boost does not maintain a stable API as described elsewhere in this thread by Artyom Beilis --- and thus would not see the deprecation period at all. Certainly users of a linux distribution like Debian/Ubuntu would never see this transition because we release every 1.5 - 2.5 years. My suggestion is that a deprecation period be measured in years, say 2-3 years. Regards, -Steve

________________________________ From: Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> To: boost@lists.boost.org 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.
See, breaking API has significant cost. It seems that the distance between 1.53 to 1.55 is small but in practice it is huge, for long running project such changes may be critical, especially stuff like a difference between detach or std::terminate that may me "transparent" in the API but breaking in all other aspects. Some points:
* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Rename the unique_future to future following the c++11.
Is it possible to keep both future and unique_future and make them interoperable? Such that existing code would not break. If you do not must remove interface why to remove it? To make it more clean? Just mark it as deprecated but don't break a program that a year ago could be build without any problem.
* [@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... Bottom line, what does the std library compience give us?
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
From my point of view if it isn't broken - don't fix it and current code is not. If you want std compient replcement, this is what stuff like boost::tr1 is for. But breaking existing code without significant reason or significant added value? I fail to see how it is right.
Best, Vicente
My $0.02 Best regards. Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

________________________________ From: Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> To: boost@lists.boost.org 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.
See, breaking API has significant cost. It seems that the distance between 1.53 to 1.55 is small but in practice it is huge, for long running project such changes may be critical, especially stuff like a difference between detach or std::terminate that may me "transparent" in the API but breaking in all other aspects.
Some points:
* [@http://svn.boost.org/trac/boost/ticket/6229 #6229] Rename the unique_future to future following the c++11. Is it possible to keep both future and unique_future and make them interoperable?
Such that existing code would not break.
If you do not must remove interface why to remove it? To make it more clean? Just mark it as deprecated but don't break a program that a year ago could be build without any problem. I just did that. I deprecated it in version 1.50. I agree also that I could have both future and unique_future.
* [@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,
Bottom line, what does the std library compience give us? There will be already less confusion. See all the questions about why
Le 30/12/12 21:50, Artyom Beilis a écrit : 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. the behaviors are different in the web.
I would like to request advise from the release managers and of course the Boost community. Should I rollback the default to BOOST_THREAD_VERSION==3 for 1.53 and let the time to discuss the best way to manage with these breaking changes?
From my point of view if it isn't broken - don't fix it and current code is not.
If you want std compient replcement, this is what stuff like boost::tr1 is for.
Thread is not part of tr1. Maybe we need boost::cxx11 ;-)
But breaking existing code without significant reason or significant added value? I fail to see how it is right.
All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed. Best, Vicente

All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed.
What is the point of changing boost::thread to behave like std::thread? The user can already choose to use std::thread behaviour - by using std::thread. Surely it makes more sense that where boost has implemented something that has made it to the standard, that the boost implementation be frozen and deprecated and that the compiler runtime version be preferred for new development? And that projects move to std::thread? That should apply to the smart pointers as much as thread, and possibly others too.

On Dec 31, 2012, at 4:31 AM, james <james@mansionfamily.plus.com> wrote:
All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed.
What is the point of changing boost::thread to behave like std::thread?
He gave one reason above: he thinks std::thread an improvement.
The user can already choose to use std::thread behaviour - by using std::thread.
That's only possible with a conforming C++11 implementation, which may not be available for years, especially to those writing cross-platform code.
Surely it makes more sense that where boost has implemented something that has made it to the standard, that the boost implementation be frozen and deprecated and that the compiler runtime version be preferred for new development? And that projects move to std::thread?
Where Boost's implementation differs significantly from C++11's, it certainly can make sense for Boost to provide both its original and the new behavior and interface. However, Boost is a volunteer organization and maintaining one version of a library is often sufficiently taxing. Another's suggestion to allow 2-3 years for deprecating features or to transition to new behavior is likewise asking much of a volunteer, though I'll grant that three quarterly releases is a rather short time by the calendar.
That should apply to the smart pointers as much as thread, and possibly others too
Obviously, if some volunteer to maintain the old, while others add and maintain the new, it is possible for Boost to have its original and a portable C++11 variant of such libraries. ___ Rob

All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed.
What is the point of changing boost::thread to behave like std::thread?
The user can already choose to use std::thread behaviour - by using std::thread.
if you cannot use c++11 for some reasons, it is good to have source-compatible version in namespace boost ... tim

2012/12/31 Tim Blechmann <tim@klingt.org>
All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed.
What is the point of changing boost::thread to behave like std::thread?
The user can already choose to use std::thread behaviour - by using std::thread.
if you cannot use c++11 for some reasons, it is good to have source-compatible version in namespace boost ...
So how about Boost.Threads2 (like Signals2), while leaving Boost.Thread unchanged? Regards, Kris

On 31/12/12 12:37, Krzysztof Czainski wrote:
2012/12/31 Tim Blechmann <tim@klingt.org>
All depend on what do you intend by significant added value. From my POV the std thread was designed more carefully than Boost.Thread which was the implementation of one of the first proposals. The implementation was just frozen until the standard was fixed.
What is the point of changing boost::thread to behave like std::thread?
The user can already choose to use std::thread behaviour - by using std::thread.
if you cannot use c++11 for some reasons, it is good to have source-compatible version in namespace boost ...
So how about Boost.Threads2 (like Signals2), while leaving Boost.Thread unchanged?
Isn't the BOOST_THREAD_VERSION_2 / VERSION_3 macro essentially equivalent? I guess it would be best if there was a boost::thread2 namespace, a boost::thread3 namespace, and that using those macros only did namespace thread = threadN;

2012/12/31 Mathias Gaunard <mathias.gaunard@ens-lyon.org>
On 31/12/12 12:37, Krzysztof Czainski wrote:
So how about Boost.Threads2 (like Signals2), while leaving Boost.Thread unchanged?
Isn't the BOOST_THREAD_VERSION_2 / VERSION_3 macro essentially equivalent?
I don't think it is. Many people seem to prefer the current behavior over std. So the idea I am suggesting is to leave the current Boost.Thread as is, so that people don't have to change their working code, and can still use the current version of Boost.Thread, preferably together with the new version. So I'm suggesting to prepare new Boost.Thread, that is intended forever to stay inside namespace threads2, and tell people if/when/why they should prefer threads2. I guess it would be best if there was a boost::thread2 namespace, a
boost::thread3 namespace, and that using those macros only did namespace thread = threadN;
Please note, that naming a namespace thread will collide with class thread. And the usual solution is adding 's' to the namespace, so the namespace is named in plural (please see [1] for an example). http://www.boost.org/doc/libs/1_52_0/libs/tuple/doc/design_decisions_rationa... Regards Kris

On 31 December 2012 07:40, Krzysztof Czainski <1czajnik@gmail.com> wrote:
I don't think it is. Many people seem to prefer the current behavior over std. So the idea I am suggesting is to leave the current Boost.Thread as is, so that people don't have to change their working code, and can still use the current version of Boost.Thread, preferably together with the new version. So I'm suggesting to prepare new Boost.Thread, that is intended forever to stay inside namespace threads2, and tell people if/when/why they should prefer threads2.
But so far *nobody* is volunteering to doing the maintenance work to keep the current Boost.Thread implementation going. The people who find this compatibility so important should be able to dedicate resources to making it happen. And if they aren't willing to do so, that is pretty telling too. -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404

if you cannot use c++11 for some reasons, it is good to have source-compatible version in namespace boost ...
I'm not sure that it is, though. You have a program that uses boost::thread. Its still not a program that uses std::thread. Changing boost::thread to work like std::thread causes problems for people using boost::thread now, and will only be a real help to portability if boost::thread is limited to what std::thread does. It seems to me likely that by the time the mess is sorted out, it is likely that compilers will offer enough compatibility with std::thread as defined that its a big waste of effort, and in the mean time everyone who has boost-based systems now has a world of pain as they work out when/how to 'big bang' entire systems (or at least the linked-together parts) over to the new behaviour. Why would anyone writing new software on a modern platform use boost::thread rather than std::thread unless then actually wanted the old semantics, anyway?

Why would anyone writing new software on a modern platform use boost::thread rather than std::thread unless then actually wanted the old semantics, anyway?
because one might want to run on systems with an older toolchain? for one of my projects, i have to stay compatible with gcc-4.2 for older osx compilers and with mingw/gcc-4.4 ... being able to conditionally pull std::thread or boost::thread into scope helps me a LOT in the transition without breaking old compilers. there are a couple of other boost libraries which have the same purpose (atomic, chrono, move) tim

On Mon, Dec 31, 2012 at 6:08 PM, Tim Blechmann <tim@klingt.org> wrote:
Why would anyone writing new software on a modern platform use boost::thread rather than std::thread unless then actually wanted the old semantics, anyway?
because one might want to run on systems with an older toolchain? for one of my projects, i have to stay compatible with gcc-4.2 for older osx compilers and with mingw/gcc-4.4 ...
being able to conditionally pull std::thread or boost::thread into scope helps me a LOT in the transition without breaking old compilers. there are a couple of other boost libraries which have the same purpose (atomic, chrono, move)
Wouldn't it be simpler to use boost::thread in all cases? Anyway, conditionally using boost or std::thread does not require these breaking changes, does it? -- Olaf

On Jan 1, 2013, at 10:12 AM, Olaf van der Spek <ml@vdspek.org> wrote:
On Mon, Dec 31, 2012 at 6:08 PM, Tim Blechmann <tim@klingt.org> wrote:
Why would anyone writing new software on a modern platform use boost::thread rather than std::thread unless then actually wanted the old semantics, anyway?
because one might want to run on systems with an older toolchain? for one of my projects, i have to stay compatible with gcc-4.2 for older osx compilers and with mingw/gcc-4.4 ...
being able to conditionally pull std::thread or boost::thread into scope helps me a LOT in the transition without breaking old compilers. there are a couple of other boost libraries which have the same purpose (atomic, chrono, move)
Wouldn't it be simpler to use boost::thread in all cases? Anyway, conditionally using boost or std::thread does not require these breaking changes, does it?
Of course it does. Using one on one platform and the other on another platform is only plausible if they have the same API and behavior unless the client code is changed for each platform, too. That leaves only four options for Boost: 1. Ignore C++11 compatibility. 2. Provide exactly C++11 API and behavior. 3. Provide 2 plus pure extensions. 4. Provide both 1 and 2 via two namespaces or classes. Options 1 and 2 are the simplest for the (mostly) one maintainer of Boost.Thread we have currently. I'll add my voice to those that don't want to lose everything that's unique in Boost.Thread. For example, I make good use of interruption points and I haven't taken the time to figure out how to do without them. I suspect I won't like the effect on my code or designs. ___ Rob

I just want to remind that boost.thread is much wider library than C++11 threading library. For example two feature that from my point of view C++11 threading library less attractive than even trivial wrap of pthrads library (or just using C API as is): - Read-Write locks - Thread local storage So going to "Standard library" directon is step backward. If you need C++11 compient interfaces this is what boost-tr1 for. Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/
________________________________ From: Rob Stewart <robertstewart@comcast.net> To: "boost@lists.boost.org" <boost@lists.boost.org> Sent: Tuesday, January 1, 2013 11:05 PM Subject: Re: [boost] Release managers: Boost.Thread breaking changes in 1.53
On Jan 1, 2013, at 10:12 AM, Olaf van der Spek <ml@vdspek.org> wrote:
On Mon, Dec 31, 2012 at 6:08 PM, Tim Blechmann <tim@klingt.org> wrote:
Why would anyone writing new software on a modern platform use boost::thread rather than std::thread unless then actually wanted the old semantics, anyway?
because one might want to run on systems with an older toolchain? for one of my projects, i have to stay compatible with gcc-4.2 for older osx compilers and with mingw/gcc-4.4 ...
being able to conditionally pull std::thread or boost::thread into scope helps me a LOT in the transition without breaking old compilers. there are a couple of other boost libraries which have the same purpose (atomic, chrono, move)
Wouldn't it be simpler to use boost::thread in all cases? Anyway, conditionally using boost or std::thread does not require these breaking changes, does it?
Of course it does. Using one on one platform and the other on another platform is only plausible if they have the same API and behavior unless the client code is changed for each platform, too.
That leaves only four options for Boost:
1. Ignore C++11 compatibility. 2. Provide exactly C++11 API and behavior. 3. Provide 2 plus pure extensions. 4. Provide both 1 and 2 via two namespaces or classes.
Options 1 and 2 are the simplest for the (mostly) one maintainer of Boost.Thread we have currently.
I'll add my voice to those that don't want to lose everything that's unique in Boost.Thread. For example, I make good use of interruption points and I haven't taken the time to figure out how to do without them. I suspect I won't like the effect on my code or designs.
___ Rob
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 01/01/2013 06:34 p.m., Artyom Beilis wrote:
For example two feature that from my point of view C++11 threading library less attractive than even trivial wrap of pthrads library (or just using C API as is):
- Read-Write locks - Thread local storage
So going to "Standard library" directon is step backward.
Artyom Beilis --------------
Thread local storage is supported by the language with the new `thread_local` storage class specifier. See [dcl.stc]/4 Agustín K-ballo Bergé. http://fusionfenix.com

From: Agustín K-ballo Bergé <kaballo86@hotmail.com>
Artyom Beilis wrote:
For example two feature that from my point of view C++11 threading library less attractive than even trivial wrap of pthrads library (or just using C API as is):
- Read-Write locks - Thread local storage
So going to "Standard library" directon is step backward.
Thread local storage is supported by the language with the new `thread_local` storage class specifier. See [dcl.stc]/4
Agustín K-ballo Bergé. http://fusionfenix.com
The problem of C++11 TLS is that it is allowed as specifier for static variables only which makes it much more limited, one of the common use cases of TLS is to allow thread local storage specific to object instance and not to class, for example I need some cache or for example I want to have thread-safe object that uses non-thread-safe db connections and caches them using object specific TLS pointer. Artyom Beilis -------------- CppCMS - C++ Web Framework: http://cppcms.com/ CppDB - C++ SQL Connectivity: http://cppcms.com/sql/cppdb/

On Tue, Jan 1, 2013 at 10:05 PM, Rob Stewart <robertstewart@comcast.net> wrote:
On Jan 1, 2013, at 10:12 AM, Olaf van der Spek <ml@vdspek.org> wrote:
Wouldn't it be simpler to use boost::thread in all cases? Anyway, conditionally using boost or std::thread does not require these breaking changes, does it?
Of course it does. Using one on one platform and the other on another platform is only plausible if they have the same API and behavior unless the client code is changed for each platform, too.
Don't think that's true. boost::thread could provide a superset of std::thread. Does your code depend on terminating in a thread destructor if the thread is joinable? If not, what's the problem with the existing behavior of not terminating, on which other code might be depending?
That leaves only four options for Boost:
1. Ignore C++11 compatibility.
What exactly is your definition of C++11 compatability? -- Olaf

On Jan 1, 2013, at 6:57 PM, Olaf van der Spek <ml@vdspek.org> wrote:
On Tue, Jan 1, 2013 at 10:05 PM, Rob Stewart <robertstewart@comcast.net> wrote:
On Jan 1, 2013, at 10:12 AM, Olaf van der Spek <ml@vdspek.org> wrote:
Wouldn't it be simpler to use boost::thread in all cases? Anyway, conditionally using boost or std::thread does not require these breaking changes, does it?
Of course it does. Using one on one platform and the other on another platform is only plausible if they have the same API and behavior unless the client code is changed for each platform, too.
Don't think that's true. boost::thread could provide a superset of std::thread.
If you focus on just one or two areas, that may be true, but it isn't possible in all cases.
Does your code depend on terminating in a thread destructor if the thread is joinable? If not, what's the problem with the existing behavior of not terminating, on which other code might be depending?
That's not the only breaking change made or planned.
That leaves only four options for Boost:
1. Ignore C++11 compatibility.
What exactly is your definition of C++11 compatability?
What I meant by that option is to stop, and even reverse, changes making Boost.Thread like C++11 in every possible way. That includes thread destructor behavior, s/unique_future/future/, removing interruption points, etc. ___ Rob

2013/1/1 Rob Stewart <robertstewart@comcast.net>
That leaves only four options for Boost:
1. Ignore C++11 compatibility. 2. Provide exactly C++11 API and behavior. 3. Provide 2 plus pure extensions. 4. Provide both 1 and 2 via two namespaces or classes.
If vincent wants some users opinion, I'm all for option 1 or 4. I know that option 4 is a maintenance nightmare, so sticking with option 1 is fine for me. I'm concerned about distribution maintenance. Boost.Thread is not a header library. so it is packaged once for all applications in a linux distribution (like debian). breaking compatibility on a header only library is not a problem, but for the other few dynamic libraries of boost, breaking compatibility is a big deal beacause you can't have control. One application might still use the old behaviour, as the other using the new one. this can't be solved using a macro definition. using a macro would be a distribution patching nightmare. more than the boost distribution cost of maintaining two distinct namespaces for old and new behaviour. For boost maintainers, i know that it's a really hard job to maintain a library. But when releasing a dynamic library for boost you should keep API and ABI backward compatibility if you announce that you support linux. I know a lot of the maintainers only care for windows or mac and have a point of view that the application developper is in charge of his software dependancy and build tool chain... but it's not true in linux domain. please keep it in mind.

On January 3, 2013 9:31:21 PM ecyrbe <ecyrbe@gmail.com> wrote:
For boost maintainers, i know that it's a really hard job to maintain a library. But when releasing a dynamic library for boost you should keep API and ABI backward compatibility if you announce that you support linux. I know a lot of the maintainers only care for windows or mac and have a point of view that the application developper is in charge of his software dependancy and build tool chain... but it's not true in linux domain. please keep it in mind.
I don't see why API and ABI backward compatibility is any more significant on Linux. Each distribution release typically sticks to particular versions of basic libraries, including Boost, and compiles the rest of packages against that set of libraries. But surely, if a compile time switch is introduced, it should only affect the header part of the library so that the compiled part is compatible with either configuration.

On 03/01/13 18:31, ecyrbe wrote:
2013/1/1 Rob Stewart <robertstewart@comcast.net>
That leaves only four options for Boost:
1. Ignore C++11 compatibility. 2. Provide exactly C++11 API and behavior. 3. Provide 2 plus pure extensions. 4. Provide both 1 and 2 via two namespaces or classes.
If vincent wants some users opinion, I'm all for option 1 or 4. I know that option 4 is a maintenance nightmare, so sticking with option 1 is fine for me.
I'm concerned about distribution maintenance. Boost.Thread is not a header library. so it is packaged once for all applications in a linux distribution (like debian). breaking compatibility on a header only library is not a problem, but for the other few dynamic libraries of boost, breaking compatibility is a big deal beacause you can't have control.
The changes in question do not break binary compatibility.

On Mon, Dec 31, 2012 at 12:39:22AM +0100, Vicente J. Botet Escriba wrote:
________________________________ From: Vicente J. Botet Escriba <vicente.botet@wanadoo.fr> To: boost@lists.boost.org 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,
Le 30/12/12 21:50, Artyom Beilis a écrit : 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@acc.umu.se

On Dec 31, 2012, at 6:17 AM, Lars Viklund <zao@acc.umu.se> wrote:
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?
It was in the release notes: http://www.boost.org/users/history/version_1_52_0.html Thread: • Deprecated Features: Deprecated features since boost 1.50 available only until boost 1.55. These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have yet 1 year to move to the new features. • Time related functions don't using the Boost.Chrono library, use the chrono overloads instead. • 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. • #6229 C++11 compliance & Breaking change: Rename the unique_future to future following the c++11. • #6266 C++11 compliance & Breaking change: thread destructor should call terminate if joinable. • #6269 C++11 compliance & Breaking change: thread move assignment should call terminate if joinable. -- Marshall Marshall Clow Idio Software <mailto:mclow.lists@gmail.com> A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait). -- Yu Suzuki

On Mon, Dec 31, 2012 at 07:38:55AM -0800, Marshall Clow wrote:
On Dec 31, 2012, at 6:17 AM, Lars Viklund <zao@acc.umu.se> wrote:
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?
It was in the release notes: http://www.boost.org/users/history/version_1_52_0.html
Thread: • Deprecated Features: Deprecated features since boost 1.50 available only until boost 1.55. These deprecated features will be provided by default up to boost 1.52. If you don't want to include the deprecated features you could define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. Since 1.53 these features will not be included any more by default. Since this version, if you want to include the deprecated features yet you could define BOOST_THREAD_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0. These deprecated features will be only available until boost 1.55, that is you have yet 1 year to move to the new features. • Time related functions don't using the Boost.Chrono library, use the chrono overloads instead. • 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. • #6229 C++11 compliance & Breaking change: Rename the unique_future to future following the c++11. • #6266 C++11 compliance & Breaking change: thread destructor should call terminate if joinable. • #6269 C++11 compliance & Breaking change: thread move assignment should call terminate if joinable.
Heh, look at that. Shows how at much attention at least one of us pays to release notes. :) -- Lars Viklund | zao@acc.umu.se
participants (21)
-
Agustín K-ballo Bergé
-
Andrey Semashev
-
Artyom Beilis
-
Bjorn Reese
-
Brian Ravnsgaard Riis
-
Daniel James
-
Dave Abrahams
-
ecyrbe
-
james
-
Krzysztof Czainski
-
Lars Viklund
-
Marshall Clow
-
Mathias Gaunard
-
Nevin Liber
-
Olaf van der Spek
-
Rob Stewart
-
Roland Bock
-
Sergey Popov
-
Steve M. Robbins
-
Tim Blechmann
-
Vicente J. Botet Escriba