libcwdversion 2.0.0
The C++ Debugging Support Library
Loading...
Searching...
No Matches
ThreadSpecificData.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2001-2006, 2017-2018, 2020, 2023, 2026 Carlo Wood
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
9
10#ifndef LIBCWD_PRIVATE_STRUCT_TSD_H
11#define LIBCWD_PRIVATE_STRUCT_TSD_H
12
14#include "libcwd/config.h"
15
16namespace libcwd::_private_ {
17struct ThreadSpecificData;
18} // namespace libcwd::_private_
19
20// The active thread's TSD is passed as a local variable (see LIBCWD_TSD_DECLARATION)
21// or function parameter (LIBCWD_TSD_PARAM).
22// Several helper macros keep those signatures compact:
23
24#define LIBCWD_TSD __libcwd_tsd // Optional `__libcwd_tsd' parameter (foo() or foo(__libcwd_tsd)).
25#define LIBCWD_TSD_PARAM ::libcwd::_private_::ThreadSpecificData& __libcwd_tsd
26 // Optional function parameter (foo() or foo(ThreadSpecificData& __libcwd_tsd)).
27#define LIBCWD_TSD_PARAM_UNUSED ::libcwd::_private_::ThreadSpecificData&
28 // Same without parameter.
29#define LIBCWD_TSD_INSTANCE ::libcwd::_private_::ThreadSpecificData::instance()
30 // For directly passing the `__libcwd_tsd' instance to a function (foo(TSD::instance())).
31#define LIBCWD_TSD_DECLARATION \
32 ::libcwd::_private_::ThreadSpecificData& __libcwd_tsd(::libcwd::_private_::ThreadSpecificData::instance())
33 // Declaration of local `__libcwd_tsd' structure reference.
34#define LIBCWD_DO_TSD(debug_object) (*__libcwd_tsd.debug_object_array[(debug_object).index_])
35 // For use inside class DebugObject to access member `m'.
36#define LIBCWD_TSD_MEMBER_OFF (__libcwd_tsd.debug_object_off_array[index_])
37 // For use inside class DebugObject to access member `_off'.
38#define LIBCWD_DO_TSD_MEMBER_OFF(debug_object) (__libcwd_tsd.debug_object_off_array[(debug_object).index_])
39 // To access member _off of debug object.
40
41#define LIBCWD_DO_TSD_MEMBER(debug_object, m) (LIBCWD_DO_TSD(debug_object).m)
42#define LIBCWD_TSD_MEMBER(m) LIBCWD_DO_TSD_MEMBER(*this, m)
43
44// These includes use the above macros.
45#include "libcwd/DebugObject_ThreadSpecificData.h"
46
47namespace libcwd {
48
49#if CWDEBUG_LOCATION
52
58using location_format_t = unsigned short int;
59
63 // End of group 'source-file-line-number-information'
65#endif
66
67#ifndef HIDE_FROM_DOXYGEN
68namespace _private_ {
69
70extern int WST_initializing_TSD;
71
72struct ThreadSpecificData
73{
74 public:
75#if CWDEBUG_LOCATION
76 location_format_t format{}; // Determines how to print Location to an ostream.
77#endif
78 bool lock_interface_is_locked =
79 false; // Set while writing debugout to the final ostream if OstreamState::mutex_ was locked.
80 bool recursive_fatal = false; // Detect loop involving dc::fatal or dc::core.
81#if CWDEBUG_DEBUG
82 bool recursive_assert = false; // Detect loop involving LIBCWD_ASSERT.
83#endif
84 int debug_object_off_array[LIBCWD_DO_MAX]{}; // Thread Specific on/off counter for Debug Objects.
85 DebugObject_ThreadSpecificData*
86 debug_object_array[LIBCWD_DO_MAX]{}; // Thread Specific Data of Debug Objects or NULL when no debug object.
87
88 // Release per-thread debug-object data owned by this TSD.
89 //
90 // ThreadSpecificData::instance() continues to return this object while cleanup runs so diagnostics emitted during
91 // cleanup see the same per-thread state. A second cleanup attempt is ignored.
92 void cleanup_routine();
93 int off_cnt_array[LIBCWD_DC_MAX]{}; // Thread Specific Data of Debug Channels.
94
95 // Destroy this TSD object.
96 //
97 // Worker-thread TSD objects are deleted by a thread_local cleanup guard at thread exit. The main-thread
98 // object is retained until process termination so global destructors can still use libcwd.
99 ~ThreadSpecificData();
100
101 private:
102 bool initialized_ = false;
103 bool cleaning_up_ = false;
104
105 //-------------------------------------------------------
106 // Static data and methods.
107 private:
108 // Initialize tsd as the active TSD for the current thread.
109 //
110 // The initialized_ flag is set before subsystem initialization so recursive instance() calls reuse the
111 // partially initialized object instead of starting a second initialization path.
112 static ThreadSpecificData& S_create(ThreadSpecificData& tsd);
113
114 public:
115 // Return the TSD object for the calling thread, creating it on first use.
116 static ThreadSpecificData& instance();
117};
118
119// Thread Specific Data (TSD) is stored in a structure ThreadSpecificData
120// and is accessed through a reference to `__libcwd_tsd'.
121
122} // namespace _private_
123#endif // HIDE_FROM_DOXYGEN
124
125} // namespace libcwd
126
127#endif // LIBCWD_PRIVATE_STRUCT_TSD_H
location_format_t const show_path
Show the full source path when printing a location.
Definition ThreadSpecificData.h:60
unsigned short int location_format_t
The type of the argument of location_format.
Definition ThreadSpecificData.h:58
location_format_t const show_objectfile
Show the shared library or executable that owns the location.
Definition ThreadSpecificData.h:61
location_format_t const show_function
Show the mangled function name for the location.
Definition ThreadSpecificData.h:62
namespace for libcwd.