Loading...
Searching...
No Matches
lock_free_queue.h
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#pragma once
21
22#include <glog/logging.h>
23
24#include <boost/lockfree/queue.hpp>
25#include <condition_variable>
26
27#include "absl/status/statusor.h"
28
29namespace resdb {
30
31template <typename T>
33 public:
34 LockFreeQueue(const std::string& name = "") : name_(name), queue_(4096) {}
35 void Push(std::unique_ptr<T> data) {
36 T* ptr = data.release();
37 while (!queue_.push(ptr)) {
38 LOG(ERROR) << "push data:" << name_ << " fail";
39 }
40 if (need_notify_.load()) {
41 bool old_v = true;
42 if (need_notify_.compare_exchange_strong(old_v, false,
43 std::memory_order_acq_rel,
44 std::memory_order_acq_rel)) {
45 std::lock_guard<std::mutex> lk(mutex_);
46 cv_.notify_all();
47 return;
48 }
49 }
50 }
51
52 std::unique_ptr<T> Pop(int timeout_ms = 100) {
53 T* ret = nullptr;
54 if (!queue_.pop(ret)) {
55 if (timeout_ms > 0) {
56 std::unique_lock<std::mutex> lk(mutex_);
57 need_notify_ = true;
58 cv_.wait_for(lk, std::chrono::milliseconds(timeout_ms),
59 [&] { return !need_notify_.load(); });
60 if (queue_.pop(ret)) {
61 return std::unique_ptr<T>(ret);
62 }
63 }
64 return nullptr;
65 }
66 return std::unique_ptr<T>(ret);
67 }
68 bool Empty() { return queue_.empty(); }
69
70 private:
71 std::string name_;
72 boost::lockfree::queue<T*> queue_;
73 std::condition_variable cv_;
74 std::mutex mutex_;
75 std::atomic<bool> need_notify_;
76};
77
78} // namespace resdb
std::string data
LockFreeQueue(const std::string &name="")
void Push(std::unique_ptr< T > data)
std::unique_ptr< T > Pop(int timeout_ms=100)