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 explicit 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
64template <typename Func> struct exception_guard {
65 Func func;
66
67 explicit exception_guard(Func f) : func(std::move(f)) {}
68
69 template <typename... Args>
70 auto operator()(Args &&...args) -> decltype(func(std::forward<Args>(args)...)) {
71 try {
72 return func(std::forward<Args>(args)...);
73 } catch (const pg_exception &e) {
74 error(e);
75 } catch (const std::exception &e) {
76 report(ERROR, "exception: %s", e.what());
77 } catch (...) {
78 report(ERROR, "some exception occurred");
79 }
80 __builtin_unreachable();
81 }
82};
83
84} // namespace cppgres
Definition: exception.hpp:7
Wraps a C++ function to catch exceptions and report them as Postgres errors.
Definition: guard.hpp:64
Definition: guard.hpp:19