BlockingList: fix unsafe getLockGuard() API

getLockGuard relies on copy elision to work correctly, which the compiler
is not required to do (only with C++17).
If no copy elision happens, the mutex ends up being unlocked twice, and the
CS is executed with the mutex unlocked.

The patch also ensures that the same pattern cannot be used again.
This commit is contained in:
Beat Küng 2019-11-05 11:09:05 +01:00
parent 5c6d16ca27
commit 23334df1e5
3 changed files with 7 additions and 4 deletions

View File

@ -70,7 +70,7 @@ FindWorkQueueByName(const char *name)
return nullptr;
}
auto lg = _wq_manager_wqs_list->getLockGuard();
LockGuard lg{_wq_manager_wqs_list->mutex()};
// search list
for (WorkQueue *wq : *_wq_manager_wqs_list) {
@ -298,7 +298,7 @@ WorkQueueManagerStop()
// first ask all WQs to stop
if (_wq_manager_wqs_list != nullptr) {
{
auto lg = _wq_manager_wqs_list->getLockGuard();
LockGuard lg{_wq_manager_wqs_list->mutex()};
// ask all work queues (threads) to stop
// NOTE: not currently safe without all WorkItems stopping first
@ -342,7 +342,7 @@ WorkQueueManagerStatus()
const size_t num_wqs = _wq_manager_wqs_list->size();
PX4_INFO_RAW("\nWork Queue: %-1zu threads RATE INTERVAL\n", num_wqs);
auto lg = _wq_manager_wqs_list->getLockGuard();
LockGuard lg{_wq_manager_wqs_list->mutex()};
size_t i = 0;
for (WorkQueue *wq : *_wq_manager_wqs_list) {

View File

@ -80,7 +80,7 @@ public:
List<T>::clear();
}
LockGuard getLockGuard() { return LockGuard{_mutex}; }
pthread_mutex_t &mutex() { return _mutex; }
private:

View File

@ -44,6 +44,9 @@ public:
pthread_mutex_lock(&_mutex);
}
LockGuard(const LockGuard &other) = delete;
LockGuard &operator=(const LockGuard &other) = delete;
~LockGuard()
{
pthread_mutex_unlock(&_mutex);