Coverage Report

Created: 2022-08-24 06:19

/src/Fast-DDS/include/fastrtps/utils/DBQueue.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
#ifndef DBQUEUE_H
16
#define DBQUEUE_H
17
18
#include <queue>
19
#include <mutex>
20
#include <memory>
21
#include <condition_variable>
22
23
namespace eprosima {
24
namespace fastrtps {
25
26
/**
27
 * Double buffered, threadsafe queue for MPSC (multi-producer, single-consumer) comms.
28
 */
29
template<class T>
30
class DBQueue
31
{
32
33
public:
34
35
    DBQueue()
36
        : mForegroundQueue(&mQueueAlpha)
37
        , mBackgroundQueue(&mQueueBeta)
38
4
    {
39
4
    }
eprosima::fastrtps::DBQueue<eprosima::fastdds::dds::Log::Entry>::DBQueue()
Line
Count
Source
38
4
    {
39
4
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::SHMPacketFileConsumer::Pkt>::DBQueue()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::DBQueue()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::DBQueue()
40
41
    //! Clears foreground queue and swaps queues.
42
    void Swap()
43
212k
    {
44
212k
        std::unique_lock<std::mutex> fgGuard(mForegroundMutex);
45
212k
        std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
46
47
        // Clear the foreground queue.
48
212k
        std::queue<T>().swap(*mForegroundQueue);
49
50
212k
        auto* swap       = mBackgroundQueue;
51
212k
        mBackgroundQueue = mForegroundQueue;
52
212k
        mForegroundQueue = swap;
53
212k
    }
eprosima::fastrtps::DBQueue<eprosima::fastdds::dds::Log::Entry>::Swap()
Line
Count
Source
43
212k
    {
44
212k
        std::unique_lock<std::mutex> fgGuard(mForegroundMutex);
45
212k
        std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
46
47
        // Clear the foreground queue.
48
212k
        std::queue<T>().swap(*mForegroundQueue);
49
50
212k
        auto* swap       = mBackgroundQueue;
51
212k
        mBackgroundQueue = mForegroundQueue;
52
212k
        mForegroundQueue = swap;
53
212k
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::SHMPacketFileConsumer::Pkt>::Swap()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::Swap()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::Swap()
54
55
    //! Pushes to the background queue. Copy constructor.
56
    void Push(
57
            const T& item)
58
0
    {
59
0
        std::unique_lock<std::mutex> guard(mBackgroundMutex);
60
0
        mBackgroundQueue->push(item);
61
0
    }
62
63
    //! Pushes to the background queue. Move constructor.
64
    void Push(
65
            T&& item)
66
1.23M
    {
67
1.23M
        std::unique_lock<std::mutex> guard(mBackgroundMutex);
68
1.23M
        mBackgroundQueue->push(std::move(item));
69
1.23M
    }
eprosima::fastrtps::DBQueue<eprosima::fastdds::dds::Log::Entry>::Push(eprosima::fastdds::dds::Log::Entry&&)
Line
Count
Source
66
1.23M
    {
67
1.23M
        std::unique_lock<std::mutex> guard(mBackgroundMutex);
68
1.23M
        mBackgroundQueue->push(std::move(item));
69
1.23M
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::Push(eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo&&)
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::Push(eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo&&)
70
71
    //! Returns a reference to the front element
72
    //! in the foregrund queue.
73
    T& Front()
74
1.22M
    {
75
1.22M
        std::unique_lock<std::mutex> guard(mForegroundMutex);
76
1.22M
        return mForegroundQueue->front();
77
1.22M
    }
78
79
    const T& Front() const
80
    {
81
        std::unique_lock<std::mutex> guard(mForegroundMutex);
82
        return mForegroundQueue->front();
83
    }
84
85
    //! Pops from the foreground queue.
86
    void Pop()
87
1.22M
    {
88
1.22M
        std::unique_lock<std::mutex> guard(mForegroundMutex);
89
1.22M
        mForegroundQueue->pop();
90
1.22M
    }
91
92
    //! Return the front element in the foreground queue by moving it and erase it from the queue.
93
    T FrontAndPop()
94
0
    {
95
0
        std::unique_lock<std::mutex> guard(mForegroundMutex);
96
97
        // Get value by moving the internal queue reference to a new value
98
0
        T value = std::move(mForegroundQueue->front());
99
        // At this point mForegroundQueue contains a non valid element, but mutex is taken and next instruction erase it
100
101
        // Pop value from queue
102
0
        mForegroundQueue->pop();
103
104
        // Return value (as it has been created in this scope, it will not be copied but moved or directly forwarded)
105
0
        return value;
106
0
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::SHMPacketFileConsumer::Pkt>::FrontAndPop()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::FrontAndPop()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::FrontAndPop()
107
108
    //! Reports whether the foreground queue is empty.
109
    bool Empty() const
110
1.43M
    {
111
1.43M
        std::unique_lock<std::mutex> guard(mForegroundMutex);
112
1.43M
        return mForegroundQueue->empty();
113
1.43M
    }
eprosima::fastrtps::DBQueue<eprosima::fastdds::dds::Log::Entry>::Empty() const
Line
Count
Source
110
1.43M
    {
111
1.43M
        std::unique_lock<std::mutex> guard(mForegroundMutex);
112
1.43M
        return mForegroundQueue->empty();
113
1.43M
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::SHMPacketFileConsumer::Pkt>::Empty() const
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::Empty() const
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::Empty() const
114
115
    //! Reports whether the both queues are empty.
116
    bool BothEmpty() const
117
0
    {
118
0
        std::unique_lock<std::mutex> guard(mForegroundMutex);
119
0
        std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
120
0
        return mForegroundQueue->empty() && mBackgroundQueue->empty();
121
0
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::dds::Log::Entry>::BothEmpty() const
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::SHMPacketFileConsumer::Pkt>::BothEmpty() const
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::BothEmpty() const
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::BothEmpty() const
122
123
    //! Reports the size of the foreground queue.
124
    size_t Size() const
125
    {
126
        std::unique_lock<std::mutex> guard(mForegroundMutex);
127
        return mForegroundQueue->size();
128
    }
129
130
    //! Clears foreground and background.
131
    void Clear()
132
0
    {
133
0
        std::unique_lock<std::mutex> fgGuard(mForegroundMutex);
134
0
        std::unique_lock<std::mutex> bgGuard(mBackgroundMutex);
135
0
        std::queue<T>().swap(*mForegroundQueue);
136
0
        std::queue<T>().swap(*mBackgroundQueue);
137
0
    }
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryPDPDataQueueInfo>::Clear()
Unexecuted instantiation: eprosima::fastrtps::DBQueue<eprosima::fastdds::rtps::ddb::DiscoveryEDPDataQueueInfo>::Clear()
138
139
private:
140
141
    // Underlying queues
142
    std::queue<T> mQueueAlpha;
143
    std::queue<T> mQueueBeta;
144
145
    // Front and background queue references (double buffering)
146
    std::queue<T>* mForegroundQueue;
147
    std::queue<T>* mBackgroundQueue;
148
149
    mutable std::mutex mForegroundMutex;
150
    mutable std::mutex mBackgroundMutex;
151
};
152
153
154
} // namespace fastrtps
155
} // namespace eprosima
156
157
#endif // ifndef DBQUEUE_H