BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslmt_threadlocalvariable.h
Go to the documentation of this file.
1/// @file bslmt_threadlocalvariable.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_threadlocalvariable.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_THREADLOCALVARIABLE
9#define INCLUDED_BSLMT_THREADLOCALVARIABLE
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_threadlocalvariable bslmt_threadlocalvariable
15/// @brief Provide a macro to declare a thread-local variable.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_threadlocalvariable
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_threadlocalvariable-purpose"> Purpose</a>
25/// * <a href="#bslmt_threadlocalvariable-macros"> Macros </a>
26/// * <a href="#bslmt_threadlocalvariable-description"> Description </a>
27/// * <a href="#bslmt_threadlocalvariable-usage"> Usage </a>
28/// * <a href="#bslmt_threadlocalvariable-example-1-a-service-request-processor-with-thread-local-context"> Example 1: A Service Request Processor with Thread Local Context </a>
29///
30/// # Purpose {#bslmt_threadlocalvariable-purpose}
31/// Provide a macro to declare a thread-local variable.
32///
33/// # Macros {#bslmt_threadlocalvariable-macros}
34///
35/// - BSLMT_THREAD_LOCAL_VARIABLE: macro to declare a thread-local variable
36///
37/// @see
38///
39/// # Description {#bslmt_threadlocalvariable-description}
40/// This component should *not* be used outside of the `bslmt`
41/// package at this time.
42///
43/// This component defines a macro for declaring a `static` thread-local
44/// variable. Where a normal static variable is located at the same memory
45/// location for all threads within a process, a thread-local static variable
46/// has a different memory location for each thread in the process:
47/// @code
48/// BSLMT_THREAD_LOCAL_VARIABLE(BASIC_TYPE, VARIABLE_NAME, INITIAL_VALUE)
49/// Declare, at function or namespace scope, a thread-local `static`
50/// variable having the specified `VARIABLE_NAME` of the specified
51/// `BASIC_TYPE` in the current context and initialize it with the
52/// specified `INITIAL_VALUE`. The `BASIC_TYPE` must be a valid
53/// typename, and that typename must represent either a fundamental or a
54/// pointer type. The specified `VARIABLE_NAME` must be a valid variable
55/// name in the scope in which the macro is employed. The specified
56/// `INITIAL_VALUE` must evaluate to a *compile-time* *constant* *value*
57/// of type `BASIC_TYPE`. If `VARIABLE_NAME` is not a valid variable
58/// name, or the type of `INITIAL_VALUE` is not convertible to type
59/// `BASIC_TYPE`, the instantiation will result in a *compile* *time*
60/// error. The behavior is undefined unless this macro is instantiated
61/// within a function or at file (or namespace) scope (i.e., *not* at
62/// class scope), and `INITIAL_VALUE` is a *compile-time* constant. Note
63/// that the instantiation of this macro is similar to the declaration:
64/// `static BASIC_TYPE VARIABLE_NAME = INITIAL_VALUE;`
65/// except that the declared variable, `VARIABLE_NAME`, refers to a
66/// different memory location for each thread in the process.
67/// @endcode
68/// Note that, `BSLMT_THREAD_LOCAL_VARIABLE` should *not* be instantiated at
69/// class scope.
70///
71/// ## Usage {#bslmt_threadlocalvariable-usage}
72///
73///
74/// This section illustrates intended use of this component.
75///
76/// ### Example 1: A Service Request Processor with Thread Local Context {#bslmt_threadlocalvariable-example-1-a-service-request-processor-with-thread-local-context}
77///
78///
79/// In the following example we create a `RequestProcessor` that places context
80/// information for the current request in a thread-local variable.
81///
82/// First, we define a trivial structure for a request context.
83/// @code
84/// // requestprocessor.h
85///
86/// struct RequestContext {
87///
88/// // DATA
89/// int d_userId; // BB user id
90/// int d_workstation; // BB LUW
91/// };
92/// @endcode
93/// Next, we create a trivial `RequestProcessor` that provides a `static` class
94/// method that returns the `RequestContext` for the current thread, or 0 if the
95/// current thread is not processing a request.
96/// @code
97/// /// This class implements an "example" request processor.
98/// class RequestProcessor {
99///
100/// private:
101/// // NOT IMPLEMENTED
102/// RequestProcessor(const RequestProcessor&);
103/// RequestProcessor& operator=(const RequestProcessor&);
104///
105/// // PRIVATE CLASS METHODS
106///
107/// /// Return a reference to a *modifiable* thread-local pointer to the
108/// /// non-modifiable request context for this thread. Note that this
109/// /// method explicitly allows the pointer (but not the
110/// /// `RequestContext` object) to be modified by the caller to allow
111/// /// other methods to assign the thread-local context pointer to a
112/// /// new address.
113/// static const RequestContext *&contextReference();
114///
115/// public:
116///
117/// // CLASS METHODS
118///
119/// /// Return the address of the non-modifiable, request context for
120/// /// this thread, or 0 if none has been set.
121/// static const RequestContext *requestContext();
122///
123/// // CREATORS
124///
125/// /// Create a `RequestProcessor`.
126/// RequestProcessor() {}
127///
128/// /// Destroy this request processor.
129/// ~RequestProcessor() {}
130///
131/// // MANIPULATORS
132///
133/// /// Process (in the caller`s thread) the specified `request` for
134/// /// the specified `userId` and `workstation`.
135/// void processRequest(int userId, int workstation, const char *request);
136/// };
137///
138/// // requestprocessor.cpp
139///
140/// // PRIVATE CLASS METHODS
141/// @endcode
142/// Now, we define the `contextReference` method, which defines a thread-local
143/// `RequestContext` pointer, `context`, initialized to 0, and returns a
144/// reference providing modifiable access to that pointer.
145/// @code
146/// const RequestContext *&RequestProcessor::contextReference()
147/// {
148/// BSLMT_THREAD_LOCAL_VARIABLE(const RequestContext *, context, 0);
149/// return context;
150/// }
151///
152/// // CLASS METHODS
153/// const RequestContext *RequestProcessor::requestContext()
154/// {
155/// return contextReference();
156/// }
157///
158/// // MANIPULATORS
159/// @endcode
160/// Then, we define the `processRequest` method, which first sets the
161/// thread-local pointer containing the request context, and then processes the
162/// `request`.
163/// @code
164/// void RequestProcessor::processRequest(int userId,
165/// int workstation,
166/// const char *request)
167/// {
168/// RequestContext currentContext = {userId, workstation};
169///
170/// contextReference() = &currentContext;
171///
172/// // Process the request.
173///
174/// contextReference() = 0;
175/// }
176/// @endcode
177/// Finally, we define a separate function `myFunction` that uses the
178/// `RequestProcessor` class to access the `RequestContext` for the current
179/// thread.
180/// @code
181/// void myFunction()
182/// {
183/// const RequestContext *context = RequestProcessor::requestContext();
184///
185/// // Perform some task that makes use of this threads 'requestContext'.
186/// // ...
187/// }
188/// @endcode
189/// @}
190/** @} */
191/** @} */
192
193/** @addtogroup bsl
194 * @{
195 */
196/** @addtogroup bslmt
197 * @{
198 */
199/** @addtogroup bslmt_threadlocalvariable
200 * @{
201 */
202
203#include <bslscm_version.h>
204
205#include <bsls_keyword.h>
206
207 // =================
208 // Macro Definitions
209 // =================
210
211/// Define, at function or namespace scope, a thread-local `static` variable
212/// having the specified `VARIABLE_NAME` of the specified `BASIC_TYPE`,
213/// initialized with the specified `INITIAL_VALUE`. If `VARIABLE_NAME` is
214/// not a valid variable name, or `INITIAL_VALUE` is not convertible to the
215/// type `BASIC_TYPE`, the instantiation of this macro will result in a compile time error.
216///
217/// \pre The behavior is undefined unless `INITIAL_VALUE` is
218/// a *compile* *time* constant value.
219#define BSLMT_THREAD_LOCAL_VARIABLE(BASIC_TYPE, VARIABLE_NAME, INITIAL_VALUE) \
220static BSLS_KEYWORD_THREAD_LOCAL BASIC_TYPE VARIABLE_NAME = INITIAL_VALUE;
221
222/// @deprecated Use @ref BSLS_KEYWORD_THREAD_LOCAL instead.
223#define BSLMT_THREAD_LOCAL_KEYWORD BSLS_KEYWORD_THREAD_LOCAL
224
225
226#endif
227
228// ----------------------------------------------------------------------------
229// Copyright 2015 Bloomberg Finance L.P.
230//
231// Licensed under the Apache License, Version 2.0 (the "License");
232// you may not use this file except in compliance with the License.
233// You may obtain a copy of the License at
234//
235// http://www.apache.org/licenses/LICENSE-2.0
236//
237// Unless required by applicable law or agreed to in writing, software
238// distributed under the License is distributed on an "AS IS" BASIS,
239// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
240// See the License for the specific language governing permissions and
241// limitations under the License.
242// ----------------------------- END-OF-FILE ----------------------------------
243
244/** @} */
245/** @} */
246/** @} */
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238