Cppgres
Build Postgres extensions in C++
Loading...
Searching...
No Matches
threading.hpp
1#pragma once
2
3#include <future>
4#include <queue>
5#include <type_traits>
6
7#include "imports.h"
8
9#ifdef __linux__
10#include <sys/syscall.h>
11#include <unistd.h>
12#elif __APPLE__
13#include <pthread.h>
14#endif
15
16namespace cppgres {
17
18#if defined(__linux__)
19static inline bool is_main_thread() { return gettid() == getpid(); }
20#elif defined(__APPLE__)
21static inline bool is_main_thread() { return pthread_main_np() != 0; }
22#else
23#warning "is_main_thread() not implemented"
24static inline bool is_main_thread() { return false; }
25#endif
26
34struct worker {
35 worker() : done(false), terminated(false) {}
36
37 ~worker() { terminate(); }
38
39 void terminate() {
40 {
41 std::scoped_lock lock(mutex);
42 if (terminated)
43 return;
44 done = true;
45 cv.notify_one();
46 }
47 }
48
49 template <typename F, typename... Args>
50 auto post(F &&f, Args &&...args) -> std::future<std::invoke_result_t<F, Args...>> {
51 using ReturnType = std::invoke_result_t<F, Args...>;
52
53 auto task = std::make_shared<std::packaged_task<ReturnType()>>(
54 [f = std::move(f), ... args = std::move(args)]() { return f(args...); });
55 std::future<ReturnType> result = task->get_future();
56
57 {
58 std::scoped_lock lock(mutex);
59 tasks.emplace([task]() { (*task)(); });
60 }
61 cv.notify_one();
62 return result;
63 }
64
70 void run() {
71 if (!is_main_thread()) {
72 throw std::runtime_error("Worker can only run on main thread");
73 }
74 while (true) {
75 std::function<void()> task;
76 {
77 std::unique_lock<std::mutex> lock(mutex);
78 cv.wait(lock, [&]() { return done.load() || !tasks.empty(); });
79 if (done.load() && tasks.empty())
80 break;
81 task = std::move(tasks.front());
82 tasks.pop();
83 }
84 task();
85 }
86 terminated = true;
87 }
88
89private:
90 std::mutex mutex;
91 std::condition_variable cv;
92 std::queue<std::function<void()>> tasks;
93 std::atomic<bool> done;
94 std::atomic<bool> terminated;
95};
96
97} // namespace cppgres
Single-threaded Postgres workload worker.
Definition: threading.hpp:34
void run()
Run the worker.
Definition: threading.hpp:70