Cppgres
Build Postgres extensions in C++
Loading...
Searching...
No Matches
guard.hpp
Go to the documentation of this file.
1
4#pragma once
5
6extern "C" {
7#include <setjmp.h>
8}
9
10#include <iostream>
11#include <utility>
12
13#include "error.hpp"
14#include "exception.hpp"
16
17namespace cppgres {
18
19template <typename Func> struct ffi_guard {
20 Func func;
21
22 ffi_guard(Func f) : func(std::move(f)) {}
23
24 template <typename... Args>
25 auto operator()(Args &&...args) -> decltype(func(std::forward<Args>(args)...)) {
26 int state;
27 sigjmp_buf *pbuf;
28 ::ErrorContextCallback *cb;
29 sigjmp_buf buf;
30 ::MemoryContext mcxt = ::CurrentMemoryContext;
31
32 pbuf = ::PG_exception_stack;
33 cb = ::error_context_stack;
34 ::PG_exception_stack = &buf;
35
36 // restore state upon exit
37 std::shared_ptr<void> defer(nullptr, [&](...) {
38 ::error_context_stack = cb;
39 ::PG_exception_stack = pbuf;
40 });
41
42 state = sigsetjmp(buf, 1);
43
44 if (state == 0) {
45 return func(std::forward<Args>(args)...);
46 } else if (state == 1) {
47 throw pg_exception(mcxt);
48 }
49 __builtin_unreachable();
50 }
51};
52
53template <typename Func> auto ffi_guarded(Func f) { return ffi_guard<Func>{f}; }
54
55} // namespace cppgres
Definition: exception.hpp:7
Definition: guard.hpp:19