Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #include "wirestead/concurrency/io_thread_hook.hpp"
18 : :
19 : : #include <memory>
20 : : #include <mutex>
21 : :
22 : : namespace wirestead {
23 : : namespace concurrency {
24 : :
25 : : namespace {
26 : :
27 : 512 : std::mutex& hook_mutex() {
28 : : static std::mutex m;
29 : 512 : return m;
30 : : }
31 : :
32 : : // shared_ptr to const, so a thread that has taken a snapshot keeps a valid
33 : : // callable even while another thread installs a replacement - the same
34 : : // discipline interface::SharedCallback uses on the receive path.
35 : 512 : std::shared_ptr<const std::function<void()>>& hook_storage() {
36 [ + + + - ]: 512 : static std::shared_ptr<const std::function<void()>> hook;
37 : 512 : return hook;
38 : : }
39 : :
40 : : } // namespace
41 : :
42 : 6 : void set_io_thread_init(std::function<void()> fn) {
43 [ + + ]: 6 : auto installed = fn ? std::make_shared<const std::function<void()>>(std::move(fn))
44 [ + - ]: 6 : : std::shared_ptr<const std::function<void()>>{};
45 : 6 : std::lock_guard<std::mutex> lock(hook_mutex());
46 : 6 : hook_storage() = std::move(installed);
47 : 6 : }
48 : :
49 : 506 : void run_io_thread_init() noexcept {
50 : 506 : std::shared_ptr<const std::function<void()>> hook;
51 : : {
52 : 506 : std::lock_guard<std::mutex> lock(hook_mutex());
53 : 506 : hook = hook_storage();
54 : 506 : }
55 [ + + ]: 506 : if (!hook) return;
56 : : // An exception here would cross the thread entry point and terminate the
57 : : // process. Whatever the hook was setting is not worth that, and the thread
58 : : // still has io to service.
59 : : try {
60 : 4 : (*hook)();
61 : 2 : } catch (...) {
62 : 2 : }
63 : 506 : }
64 : :
65 : : } // namespace concurrency
66 : : } // namespace wirestead
|