Prepare Bareos for an upgrade to the C++20 standard#1271
Conversation
f234b52 to
4cbd561
Compare
core/src/tests/thread_list.cc
Outdated
| status_ = Status::kWaiting; | ||
| bool success = cond_variable_.wait_for(ul, ms, [=]() { return notified; }); | ||
| bool success | ||
| = cond_variable_.wait_for(ul, ms, [=, this]() { return notified; }); |
There was a problem hiding this comment.
i guess you could just capture notified
There was a problem hiding this comment.
creates this error:
bareos/core/src/tests/thread_list.cc:61: error: capture of non-variable ‘WaitCondition::notified’
bareos/core/src/tests/thread_list.cc: In member function ‘void WaitCondition::WaitFor(std::chrono::milliseconds)’:
bareos/core/src/tests/thread_list.cc:61:19: error: capture of non-variable ‘WaitCondition::notified’
this must be captured.
capturing this->notified doesn't work either.
There was a problem hiding this comment.
you're right, but you don't need to capture = then.
240ca7f to
642ecc3
Compare
642ecc3 to
3c20a73
Compare
3c20a73 to
42b43e1
Compare
| # switch on CXX 17 Support | ||
| # |
There was a problem hiding this comment.
| # switch on CXX 17 Support | |
| # |
core/src/lib/bsock_tcp.cc
Outdated
| timer_start = 0; /* clear timer */ | ||
| if (rc != pktsiz) { | ||
| errors++; | ||
| errors = errors + 1; |
There was a problem hiding this comment.
The atomic has working operator++()
| errors = errors + 1; | |
| ++errors; |
core/src/lib/bsock_tcp.cc
Outdated
| b_errno = errno; | ||
| } | ||
| errors++; | ||
| errors = errors + 1; |
There was a problem hiding this comment.
The atomic has working operator++()
| errors = errors + 1; | |
| ++errors; |
core/src/lib/bsock_tcp.cc
Outdated
| timer_start = 0; /* clear timer */ | ||
| if (nbytes != header_length) { | ||
| errors++; | ||
| errors = errors + 1; |
There was a problem hiding this comment.
The atomic has working operator++()
| errors = errors + 1; | |
| ++errors; |
core/src/lib/bsock_tcp.cc
Outdated
| b_errno = errno; | ||
| } | ||
| errors++; | ||
| errors = errors + 1; |
There was a problem hiding this comment.
The atomic has working operator++()
| errors = errors + 1; | |
| ++errors; |
| VolumeReservationItem* vol; | ||
| VolumeReservationItem emptyVol; | ||
|
|
||
| vol = (VolumeReservationItem*)malloc(sizeof(VolumeReservationItem)); | ||
| *vol = emptyVol; | ||
| vol = new (vol) VolumeReservationItem(); /* placement new instead of memset */ | ||
|
|
There was a problem hiding this comment.
This is one of the places that we can actually improve a lot with C++20.
An obvious one is:
auto* vol = static_cast<VolumeReservationItem*>(malloc(sizeof(VolumeReservationItem)));
std::construct_at(vol);
The two functions below FreeVolItem(), FreeReadVolItem() are identical, so we should probably remove the latter one.
Having said that, I think optimal code for this function would look like:
auto* vol = new VolumeReservationItem(VolumeName, dcr);
With all the setup and teardown moved into proper a ctor and dtor.
What is currently stopping us from doing that is that the volume list is a dlist<VolumeReservationItem> and that dlist<>::destroy() always uses free(n) to simply free the memory.
So if we extended dlist<T> to dlist<T, use_delete = false> and changed dlist<>::destroy() to honor that flag and use delete instead of free() we could then add a ctor/dtor to VolumeReservationItem, simplifying new_vol_item(), FreeVolItem(), FreeReadVolItem(), dup_vol_list() and FreeVolumeList() a lot.
However, after reading what I just wrote, this may be better suited for another cleanup PR.
There was a problem hiding this comment.
I had somewhat of the same idea here at least in the sense of just using new and trying to replace the free with a delete somewhere or a destructor, but I ended up with the same conclusion that those changes would probably require more work than simply complying with c++20 standards
There was a problem hiding this comment.
Certain compilers we use in our containers seem to not support std::construct_at
There was a problem hiding this comment.
That's bad. std::construct_at() is part of C++20. If a compiler or library doesn't support it, we don't have real C++20 support there.
Maybe we can move to even newer compilers/libraries on the affected platforms?
I cannot find construct_at() as a feature on cppreference's compiler support page. However, there are a lot of features that require at least GCC 10 or even GCC 11.
At least for RHEL 7 and RHEL 8 we're on GCC 8 right now, which seems to be way too old for C++20.
core/src/stored/vol_mgr.h
Outdated
| void IncUseCount(void) { use_count_++; } | ||
| void DecUseCount(void) { use_count_--; } |
There was a problem hiding this comment.
| void IncUseCount(void) { use_count_++; } | |
| void DecUseCount(void) { use_count_--; } | |
| void IncUseCount(void) { ++use_count_; } | |
| void DecUseCount(void) { --use_count_; } |
core/src/tests/thread_list.cc
Outdated
| status_ = Status::kWaiting; | ||
| bool success = cond_variable_.wait_for(ul, ms, [=]() { return notified; }); | ||
| bool success | ||
| = cond_variable_.wait_for(ul, ms, [=, this]() { return notified; }); |
There was a problem hiding this comment.
you're right, but you don't need to capture = then.
| Device() = default; | ||
| virtual ~Device(); | ||
| Device* volatile swap_dev{}; /**< Swap vol from this device */ | ||
| Device* swap_dev{}; /**< Swap vol from this device */ |
There was a problem hiding this comment.
Hmm... that's a tough one. Basically, if the code ran on C++11 and later with volatile it should also run fine without volatile.
We could probably make this a std::atomic<Device*>, but I don't think that is required.
| JobControlRecord* jcr{}; /**< Pointer to JobControlRecord */ | ||
| pthread_mutex_t mutex_ = PTHREAD_MUTEX_INITIALIZER; /**< Access control */ | ||
| pthread_mutex_t r_mutex = PTHREAD_MUTEX_INITIALIZER; /**< rLock pre-mutex */ | ||
| Device* volatile dev{}; /**< Pointer to device */ |
There was a problem hiding this comment.
This does indeed produce different assembler code in some translation units. However, I don't see how not using volatile here should lead to an issue.
0861754 to
b4cbcbf
Compare
dbef0a9 to
bebe040
Compare
442b2a4 to
7c74b46
Compare
volmgr vol_mgr: use std::construct_at instead of placement new
replace problematic accesses to JobStatus with getter
Certain compilers we use in our containers seem to not support std::construct_at
C++20 supports designated initializers. However, it doesn't allow mixing of named and unnamed initialization. As we need to use the PyVarObject_HEAD_INIT() macro, which doesn't name the attributes it sets, we have to downgrade the compiler to C++17, so designated initializers are handled as compiler extension, which will allow the mixing that occurs here. See also: python/cpython#99202
7c74b46 to
3922775
Compare
Thank you for contributing to the Bareos Project!
Description
This PR will upgrade Bareos to use the C++20 standard.
Please check
If you have any questions or problems, please give a comment in the PR.
Helpful documentation and best practices
Checklist for the reviewer of the PR (will be processed by the Bareos team)
General
Source code quality
bareos-check-sources --since-mergedoes not report any problems