Flow 2.0.0
Flow project: Full implementation reference.
thread_lcl_ptr_impl.cpp
Go to the documentation of this file.
1/* Flow
2 * Copyright 2023 Akamai Technologies, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the
5 * "License"); you may not use this file except in
6 * compliance with the License. You may obtain a copy
7 * of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in
12 * writing, software distributed under the License is
13 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
14 * CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing
16 * permissions and limitations under the License. */
17
18/// @file
20#include <boost/thread.hpp>
21#include <cassert>
22#include <cstddef>
23
24namespace flow::util
25{
26
27// Implementations.
28
30 m_per_tlp_key(Unique_id_holder::create_unique_id())
31{
32 // That's all. Real action starts, potentially, in reset_release() and friends.
33}
34
36{
37 release(); // It checks s_this_thread_global_tl_state_operative.
38
39 /* Reminder: We only worry about *this* thread's release(); other threads' stuff is allowed to stay around,
40 * until each thread's deinit phase executes. */
41}
42
44{
45 // See s_this_thread_global_tl_state_operative doc header; it explains why we do this *here*.
46 boost::this_thread::at_thread_exit([]()
47 {
49 });
50}
51
53{
54 /* The following is clearly harmless and clearly not-wrong: If this dtor is running, then obviously m_tlp_states_map
55 * cannot be accessed, so obviously the definitional condition "do not access Global_tl_state" becomes
56 * true. And if it is already `false`, then it's a no-op.
57 *
58 * Is it necessary? It is moot, per preceding paragraph, but it can't hurt to think about it.
59 * - If the boost::thread-module at_thread_exit() + tsp-cleanup phase runs before thread_local deinit
60 * (boost::thread thread): Flag will already be false. No-op. Not necessary.
61 * - If the boost::thread-module at_thread_exit() + tsp-cleanup phase runs after thread_local deinit
62 * (std::thread thread): thread_local deinit might run some dtor which could, e.g., use
63 * Tlp::get() for some entry. If this flag remained true here, but m_tlp_states_map is destroyed
64 * (which it will be just after this dtor {block} exits), then that Tlp::get() would try to read
65 * from an invalid map. Undefined behavior. So yes: necessary in this (contrived but possible) case.
66 * More to the point (contrived or not): would vanilla thread_specific_ptr happen to work OK? Yes:
67 * it would. (Relying on that is probably not so smart though -- in a boost::thread the tsp cleanup would
68 * have run already, so only for std::thread could it ever work -- but that's not our code; that's
69 * on the user. We should just mirror tsp as promised.) */
71}
72
73
74} // namespace flow::util
static thread_local bool s_this_thread_global_tl_state_operative
A thread-local flag that starts at true and becomes false to indicate do not access Global_tl_state.
void release()
Our part of Thread_local_ptr::release().
Thread_local_ptr_cache()
Ctor. No apparent effect.
Each object of this class stores (at construction) and returns (on demand) a numeric ID unique from a...
Flow module containing miscellaneous general-use facilities that don't fit into any other Flow module...
Global_tl_state()
Ctor: registers (boost::this_thread::at_thread_exit()) a thing that sets s_this_thread_global_tl_stat...
~Global_tl_state()
Dtor that runs at thread_local deinit phase; unknown where among this thread's such deinits this runs...