NVIDIA DeepStream SDK API Reference

9.1 Release
sources/includes/ds3d/common/helper/safe_queue.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef DS3D_COMMON_HELPER_SAFE_QUEUE_H
19 #define DS3D_COMMON_HELPER_SAFE_QUEUE_H
20 
21 #include <ds3d/common/common.h>
22 #include <ds3d/common/func_utils.h>
23 
24 #include <chrono>
25 #include <deque>
26 
27 namespace ds3d {
28 
29 template <typename T, typename Container = std::deque<T>>
30 class SafeQueue {
31  // using namespace std::chrono_literals;
32 public:
33  void push(T data)
34  {
35  std::unique_lock<std::mutex> lock(_mutex);
36  _queue.emplace_back(std::move(data));
37  _cond.notify_one();
38  }
39  T pop(uint64_t timeoutMs = 0)
40  {
41  std::unique_lock<std::mutex> lock(_mutex);
42  auto stopWait = [this]() { return _wakeupOnce || !_queue.empty(); };
43  if (!timeoutMs) {
44  _cond.wait(lock, stopWait);
45  } else {
46  using namespace std::chrono_literals;
47  if (!_cond.wait_for(lock, timeoutMs * 1ms, stopWait)) {
48  throw Exception(ErrCode::kTimeOut, "queue pop timeout");
49  }
50  }
51  if (_wakeupOnce) {
52  _wakeupOnce = false;
53  LOG_DEBUG("SafeQueue pop end on wakeup signal");
54  throw Exception(ErrCode::kLockWakeup, "queue wakedup");
55  }
56  assert(!_queue.empty());
57  T ret = std::move(*_queue.begin());
58  _queue.erase(_queue.begin());
59  return ret;
60  }
61  void wakeupOnce()
62  {
63  LOG_DEBUG("SafeQueue trigger wakeup once");
64  std::unique_lock<std::mutex> lock(_mutex);
65  _wakeupOnce = true;
66  _cond.notify_all();
67  }
68  void clear()
69  {
70  LOG_DEBUG("SafeQueue clear");
71  std::unique_lock<std::mutex> lock(_mutex);
72  _queue.clear();
73  _wakeupOnce = false;
74  }
75  size_t size()
76  {
77  std::unique_lock<std::mutex> lock(_mutex);
78  return _queue.size();
79  }
80 
81 private:
82  std::mutex _mutex;
83  std::condition_variable _cond;
84  Container _queue;
85  bool _wakeupOnce = false;
86 };
87 
88 template <class UniPtr>
89 class BufferPool : public std::enable_shared_from_this<BufferPool<UniPtr>> {
90 public:
91  using ItemType = typename UniPtr::element_type;
92  using RecylePtr = std::unique_ptr<ItemType, std::function<void(ItemType*)>>;
93  BufferPool(const std::string& name) : m_Name(name) {}
94  virtual ~BufferPool()
95  {
96  LOG_DEBUG(
97  "BufferPool: %s deleted with free buffer size:%d", m_Name.c_str(),
98  (int)m_FreeBuffers.size());
99  }
100  bool setBuffer(UniPtr buf)
101  {
102  assert(buf);
103  m_FreeBuffers.push(std::move(buf));
104  LOG_DEBUG(
105  "BufferPool: %s set buf to free, available size:%d", m_Name.c_str(),
106  (int)m_FreeBuffers.size());
107  return true;
108  }
109  uint32_t size() { return m_FreeBuffers.size(); }
110 
112  {
113  try {
114  UniPtr p = m_FreeBuffers.pop();
115  auto deleter = p.get_deleter();
116  std::weak_ptr<BufferPool<UniPtr>> poolPtr = this->shared_from_this();
117  RecylePtr recBuf(p.release(), [poolPtr, d = deleter](ItemType* buf) {
118  assert(buf);
119  UniPtr data(buf, d);
120  auto pool = poolPtr.lock();
121  if (pool) {
122  LOG_DEBUG("BufferPool: %s release a buffer", pool->m_Name.c_str());
123  pool->setBuffer(std::move(data));
124  } else {
125  LOG_DEBUG("BufferPool was deleted before buffer release, maybe application is closing.");
126  //assert(false);
127  }
128  });
129  LOG_DEBUG(
130  "BufferPool: %s acquired buffer, available free buffer left:%d", m_Name.c_str(),
131  (int)m_FreeBuffers.size());
132  return recBuf;
133  }
134  catch (...) {
135  LOG_DEBUG(
136  "BufferPool: %s acquired buffer failed, queue may be waked up", m_Name.c_str());
137  assert(false);
138  return nullptr;
139  }
140  }
141 
142 private:
143  SafeQueue<UniPtr> m_FreeBuffers;
144  const std::string m_Name;
145 };
146 
147 } // namespace ds3d
148 
149 #endif //
ds3d::BufferPool
Definition: sources/includes/ds3d/common/helper/safe_queue.h:89
ds3d::BufferPool::acquireBuffer
RecylePtr acquireBuffer()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:111
ds3d::SafeQueue::clear
void clear()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:68
ds3d::SafeQueue
Definition: sources/includes/ds3d/common/helper/safe_queue.h:30
ds3d::Exception
Definition: sources/includes/ds3d/common/common.h:148
ds3d::BufferPool::size
uint32_t size()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:109
ds3d::BufferPool::setBuffer
bool setBuffer(UniPtr buf)
Definition: sources/includes/ds3d/common/helper/safe_queue.h:100
LOG_DEBUG
#define LOG_DEBUG(fmt,...)
Definition: sources/apps/sample_apps/deepstream-3d-action-recognition/deepstream_action.h:54
ds3d::ErrCode::kTimeOut
@ kTimeOut
ds3d::ErrCode::kLockWakeup
@ kLockWakeup
ds3d::SafeQueue::push
void push(T data)
Definition: sources/includes/ds3d/common/helper/safe_queue.h:33
ds3d::BufferPool::BufferPool
BufferPool(const std::string &name)
Definition: sources/includes/ds3d/common/helper/safe_queue.h:93
ds3d::SafeQueue::size
size_t size()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:75
ds3d::BufferPool::RecylePtr
std::unique_ptr< ItemType, std::function< void(ItemType *)> > RecylePtr
Definition: sources/includes/ds3d/common/helper/safe_queue.h:92
ds3d::SafeQueue::wakeupOnce
void wakeupOnce()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:61
ds3d::BufferPool::~BufferPool
virtual ~BufferPool()
Definition: sources/includes/ds3d/common/helper/safe_queue.h:94
ds3d::BufferPool::ItemType
typename UniPtr::element_type ItemType
Definition: sources/includes/ds3d/common/helper/safe_queue.h:91
ds3d
Definition: sources/includes/ds3d/common/abi_dataprocess.h:25
ds3d::SafeQueue::pop
T pop(uint64_t timeoutMs=0)
Definition: sources/includes/ds3d/common/helper/safe_queue.h:39