MySQL 9.3.0
Source Code Documentation
jit_executor_context_pool.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024, 2025, Oracle and/or its affiliates.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2.0,
6 * as published by the Free Software Foundation.
7 *
8 * This program is designed to work with certain software (including
9 * but not limited to OpenSSL) that is licensed under separate terms,
10 * as designated in a particular file or component or in included license
11 * documentation. The authors of MySQL hereby grant you an additional
12 * permission to link the program and your derivative works with the
13 * separately licensed software that they have either included with
14 * the program or referenced in the documentation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License, version 2.0, for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#ifndef ROUTER_SRC_JIT_EXECUTOR_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_CONTEXT_POOL_H_
27#define ROUTER_SRC_JIT_EXECUTOR_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_CONTEXT_POOL_H_
28
29#include <condition_variable>
30#include <deque>
31#include <functional>
32#include <memory>
33#include <mutex>
34#include <stdexcept>
35#include <string>
36#include <thread>
37#include <vector>
38
45
46namespace jit_executor {
47
49
50/**
51 * Generic implementation of a pool
52 */
53template <class T>
54class Pool {
55 public:
56 explicit Pool(size_t size, const std::function<T(size_t)> &factory,
57 const std::function<void(T)> &destructor = {})
58 : m_pool_size{size},
59 m_item_factory{factory},
60 m_item_destructor{destructor} {}
61
62 T get() {
63 {
64 std::unique_lock lock(m_mutex);
65
66 if (m_teardown) return {};
67
68 T item = {};
69
70 // Contention mode is turned ON when a memory error happened, for that
71 // reason creating new contexts is a no-go so we should wait for a context
72 // from the pool to get released
73 if (m_contention_mode && m_items.empty()) {
74 m_item_availability.wait(
75 lock, [this]() { return m_active_items == 0 || !m_items.empty(); });
76
77 if (m_active_items == 0) {
78 throw std::runtime_error(
79 "All the contexts on the pool have been released.");
80 }
81 }
82
83 if (!m_items.empty()) {
84 // Pop a resource from the pool
85 item = m_items.front();
86 m_items.pop_front();
87 return item;
88 }
89 }
90
91 try {
92 T item = m_item_factory(m_created_items);
93 increase_active_items();
94 return item;
95 } catch (const std::runtime_error &) {
96 // An initialization failure would raise this exception, no action is
97 // needed
98 return {};
99 }
100 }
101
102 void release(T ctx) {
103 {
104 std::scoped_lock lock(m_mutex);
105
106 if (!m_teardown && m_items.size() < m_pool_size) {
107 m_items.push_back(ctx);
108 m_item_availability.notify_one();
109 return;
110 }
111 }
112
113 discard(ctx, false);
114 }
115
116 void teardown() {
117 {
118 std::scoped_lock lock(m_mutex);
119 m_teardown = true;
120 }
121
122 while (!m_items.empty()) {
123 auto item = m_items.front();
124 m_items.pop_front();
125
126 discard(item, false);
127 }
128
129 // Waits until all the contexts created by the pool get released
130 std::unique_lock<std::mutex> lock(m_mutex);
131 m_item_availability.wait(lock, [this]() { return m_active_items == 0; });
132 }
133
134 size_t active_items() const {
135 std::scoped_lock lock(m_mutex);
136 return m_active_items;
137 }
138
139 /**
140 * Discards the affected context and turns ON contention mode for the pool
141 */
142 void discard(T ctx, bool set_contention_mode) {
143 decrease_active_items(set_contention_mode);
144
145 if (m_item_destructor) {
146 try {
147 m_item_destructor(ctx);
148 } catch (const std::exception &e) {
149 log_error("%s", e.what());
150 }
151 }
152 }
153
154 private:
156 {
157 std::scoped_lock lock(m_mutex);
158 m_active_items++;
159 m_created_items++;
160 }
161 }
162
163 void decrease_active_items(bool set_contention_mode = false) {
164 {
165 std::scoped_lock lock(m_mutex);
166 m_active_items--;
167
168 if (set_contention_mode) {
169 m_contention_mode = true;
170 }
171 }
172 m_item_availability.notify_all();
173 }
174
175 std::mutex m_mutex;
176 std::condition_variable m_item_availability;
177 bool m_teardown = false;
179 std::deque<T> m_items;
180 std::function<T(size_t id)> m_item_factory;
181 std::function<void(T)> m_item_destructor;
182 size_t m_active_items = 0;
183 size_t m_created_items = 0;
184 bool m_contention_mode = false;
185};
186
188class CommonContext;
189class ContextPool final {
190 public:
191 ContextPool(size_t size, CommonContext *common_context);
192
193 ~ContextPool();
194
195 std::shared_ptr<PooledContextHandle> get_context();
196 void release(IContext *ctx);
197 void teardown();
198
199 private:
200 void release_thread();
201
203 std::unique_ptr<Pool<IContext *>> m_pool;
205 std::unique_ptr<std::thread> m_release_thread;
206};
207
208/**
209 * A wrapper that will return a context to the pool as soon as it is released
210 */
212 public:
214 : m_pool{pool}, m_context{ctx} {}
216
217 IContext *get() override { return m_context; }
218
219 private:
222};
223
224} // namespace jit_executor
225
226#endif // ROUTER_SRC_JIT_EXECUTOR_INCLUDE_MYSQLROUTER_JIT_EXECUTOR_CONTEXT_POOL_H_
Specialization of the Polyglot_common_context to provide MRS specific logging functions as well as th...
Definition: jit_executor_common_context.h:46
Definition: jit_executor_context_pool.h:189
std::unique_ptr< std::thread > m_release_thread
Definition: jit_executor_context_pool.h:205
void release(IContext *ctx)
Definition: jit_executor_context_pool.cc:86
void release_thread()
Definition: jit_executor_context_pool.cc:88
~ContextPool()
Definition: jit_executor_context_pool.cc:57
CommonContext * m_common_context
Definition: jit_executor_context_pool.h:202
mysql_harness::WaitingMPSCQueue< IContext * > m_release_queue
Definition: jit_executor_context_pool.h:204
std::shared_ptr< PooledContextHandle > get_context()
Definition: jit_executor_context_pool.cc:71
std::unique_ptr< Pool< IContext * > > m_pool
Definition: jit_executor_context_pool.h:203
ContextPool(size_t size, CommonContext *common_context)
Definition: jit_executor_context_pool.cc:40
void teardown()
Definition: jit_executor_context_pool.cc:59
Base handler for Jit Executor Context instances.
Definition: jit_executor_context_handle.h:36
Definition: jit_executor_context.h:40
Generic implementation of a pool.
Definition: jit_executor_context_pool.h:54
Pool(size_t size, const std::function< T(size_t)> &factory, const std::function< void(T)> &destructor={})
Definition: jit_executor_context_pool.h:56
void discard(T ctx, bool set_contention_mode)
Discards the affected context and turns ON contention mode for the pool.
Definition: jit_executor_context_pool.h:142
std::condition_variable m_item_availability
Definition: jit_executor_context_pool.h:176
void teardown()
Definition: jit_executor_context_pool.h:116
std::deque< T > m_items
Definition: jit_executor_context_pool.h:179
void release(T ctx)
Definition: jit_executor_context_pool.h:102
std::function< void(T)> m_item_destructor
Definition: jit_executor_context_pool.h:181
std::function< T(size_t id)> m_item_factory
Definition: jit_executor_context_pool.h:180
size_t m_pool_size
Definition: jit_executor_context_pool.h:178
size_t active_items() const
Definition: jit_executor_context_pool.h:134
void decrease_active_items(bool set_contention_mode=false)
Definition: jit_executor_context_pool.h:163
T get()
Definition: jit_executor_context_pool.h:62
void increase_active_items()
Definition: jit_executor_context_pool.h:155
std::mutex m_mutex
Definition: jit_executor_context_pool.h:175
A wrapper that will return a context to the pool as soon as it is released.
Definition: jit_executor_context_pool.h:211
IContext * m_context
Definition: jit_executor_context_pool.h:221
IContext * get() override
Definition: jit_executor_context_pool.h:217
~PooledContextHandle() override
Definition: jit_executor_context_pool.h:215
PooledContextHandle(ContextPool *pool, IContext *ctx)
Definition: jit_executor_context_pool.h:213
ContextPool * m_pool
Definition: jit_executor_context_pool.h:220
provide waiting pop and push operator to thread-safe queues.
Definition: waiting_queue_adaptor.h:40
#define log_error(...)
Definition: log_client.h:155
#define T
Definition: jit_executor_value.cc:373
Logging interface for using and extending the logging subsystem.
#define IMPORT_LOG_FUNCTIONS()
convenience macro to avoid common boilerplate
Definition: logging.h:323
Definition: jit_executor_callbacks.h:36
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
size_t size(const char *const c)
Definition: base64.h:46
static std::mutex lock
Definition: net_ns.cc:56