Spicy
context.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <cassert>
6 #include <memory>
7 #include <utility>
8 #include <vector>
9 
10 #include <hilti/rt/fiber.h>
11 #include <hilti/rt/threading.h>
12 
13 namespace hilti::rt {
14 
22 struct Context {
26  explicit Context(vthread::ID vid);
27  ~Context();
28 
29  Context() = delete;
30  Context(const Context&) = delete;
31  Context(Context&&) = delete;
32  Context& operator=(const Context&) = delete;
33  Context& operator=(Context&&) = delete;
34 
39  vthread::ID vid;
40 
46 
49 
55  std::vector<std::shared_ptr<void>> hilti_globals;
56 
58  void* cookie = nullptr;
59 
61  uint64_t debug_indent{};
62 
68  const char* location = nullptr;
69 };
70 
71 namespace context {
72 namespace detail {
73 
81 extern Context*& current();
82 
84 extern Context* master();
85 
87 inline auto get(bool allow_missing_context = false) {
88  auto* ctx = current();
89 
90  if ( ! allow_missing_context )
91  assert(ctx);
92 
93  return ctx;
94 }
95 
100 hilti::rt::Context* set(Context* ctx);
101 
106 public:
107  explicit ResumableSetter(resumable::Handle* r) {
108  old = get()->resumable;
109  get()->resumable = r;
110  }
111 
112  ~ResumableSetter() { get()->resumable = old; }
113 
114  ResumableSetter(const ResumableSetter&) = delete;
115  ResumableSetter(ResumableSetter&&) = delete;
116  ResumableSetter& operator=(const ResumableSetter&) = delete;
117  ResumableSetter& operator=(ResumableSetter&&) = delete;
118 
119  resumable::Handle* old;
120 };
121 
122 } // namespace detail
123 
125 inline void saveCookie(void* cookie) { detail::get()->cookie = cookie; }
126 
128 inline void* cookie() { return detail::get()->cookie; }
129 
131 inline void clearCookie() { detail::get()->cookie = nullptr; }
132 
137 public:
138  explicit CookieSetter(void* cookie) {
139  _old = detail::get()->cookie;
140  detail::get()->cookie = cookie;
141  }
142 
143  ~CookieSetter() { detail::get()->cookie = _old; }
144 
145  CookieSetter() = delete;
146  CookieSetter(const CookieSetter&) = delete;
147  CookieSetter(CookieSetter&&) = delete;
148  CookieSetter& operator=(const CookieSetter&) = delete;
149  CookieSetter& operator=(CookieSetter&&) = delete;
150 
151 private:
152  void* _old;
153 };
154 
162 template<typename Function, typename... Params>
163 Resumable execute(Function f, Params&&... params) {
164  auto cb = [&](resumable::Handle* r) {
165  auto _ = detail::ResumableSetter(r);
166  return f(std::forward<Params>(params)...);
167  };
168 
169  Resumable r(std::move(cb));
170  r.run();
171  return r;
172 }
173 
174 } // namespace context
175 } // namespace hilti::rt
Definition: function.h:18
Definition: fiber.h:305
Definition: fiber.h:154
Definition: any.h:7
Definition: context.h:22
const char * location
Definition: context.h:68
void * cookie
Definition: context.h:58
resumable::Handle * resumable
Definition: context.h:45
detail::FiberContext fiber
Definition: context.h:48
std::vector< std::shared_ptr< void > > hilti_globals
Definition: context.h:55
uint64_t debug_indent
Definition: context.h:61
vthread::ID vid
Definition: context.h:39
Definition: fiber.h:45