BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_threadlocalvariable

Macros

#define BSLMT_THREAD_LOCAL_VARIABLE(BASIC_TYPE, VARIABLE_NAME, INITIAL_VALUE)   static BSLMT_THREAD_LOCAL_KEYWORD BASIC_TYPE VARIABLE_NAME = INITIAL_VALUE;
 
#define BSLMT_THREAD_LOCAL_KEYWORD   __thread
 

Detailed Description

Outline

Purpose

Provide a macro to declare a thread-local variable.

Macros

See also

Description

This component should not be used outside of the bslmt package at this time.

This component defines a macro for declaring a static thread-local variable. Where a normal static variable is located at the same memory location for all threads within a process, a thread-local static variable has a different memory location for each thread in the process:

BSLMT_THREAD_LOCAL_VARIABLE(BASIC_TYPE, VARIABLE_NAME, INITIAL_VALUE)
Declare, at function or namespace scope, a thread-local `static`
variable having the specified `VARIABLE_NAME` of the specified
`BASIC_TYPE` in the current context and initialize it with the
specified `INITIAL_VALUE`. The `BASIC_TYPE` must be a valid
typename, and that typename must represent either a fundamental or a
pointer type. The specified `VARIABLE_NAME` must be a valid variable
name in the scope in which the macro is employed. The specified
`INITIAL_VALUE` must evaluate to a *compile-time* *constant* *value*
of type `BASIC_TYPE`. If `VARIABLE_NAME` is not a valid variable
name, or the type of `INITIAL_VALUE` is not convertible to type
`BASIC_TYPE`, the instantiation will result in a *compile* *time*
error. The behavior is undefined unless this macro is instantiated
within a function or at file (or namespace) scope (i.e., *not* at
class scope), and `INITIAL_VALUE` is a *compile-time* constant. Note
that the instantiation of this macro is similar to the declaration:
`static BASIC_TYPE VARIABLE_NAME = INITIAL_VALUE;`
except that the declared variable, `VARIABLE_NAME`, refers to a
different memory location for each thread in the process.
#define BSLMT_THREAD_LOCAL_VARIABLE(BASIC_TYPE, VARIABLE_NAME, INITIAL_VALUE)
Definition bslmt_threadlocalvariable.h:224

Note that, BSLMT_THREAD_LOCAL_VARIABLE should not be instantiated at class scope.

Usage

This section illustrates intended use of this component.

Example 1: A Service Request Processor with Thread Local Context

In the following example we create a RequestProcessor that places context information for the current request in a thread-local variable.

First, we define a trivial structure for a request context.

// requestprocessor.h
struct RequestContext {
// DATA
int d_userId; // BB user id
int d_workstation; // BB LUW
};

Next, we create a trivial RequestProcessor that provides a static class method that returns the RequestContext for the current thread, or 0 if the current thread is not processing a request.

/// This class implements an "example" request processor.
class RequestProcessor {
// NOT IMPLEMENTED
RequestProcessor(const RequestProcessor&);
RequestProcessor& operator=(const RequestProcessor&);
// PRIVATE CLASS METHODS
/// Return a reference to a *modifiable* thread-local pointer to the
/// non-modifiable request context for this thread. Note that this
/// method explicitly allows the pointer (but not the
/// `RequestContext` object) to be modified by the caller to allow
/// other methods to assign the thread-local context pointer to a
/// new address.
static const RequestContext *&contextReference();
public:
// CLASS METHODS
/// Return the address of the non-modifiable, request context for
/// this thread, or 0 if none has been set.
static const RequestContext *requestContext();
// CREATORS
/// Create a `RequestProcessor`.
RequestProcessor() {}
/// Destroy this request processor.
~RequestProcessor() {}
// MANIPULATORS
/// Process (in the caller`s thread) the specified `request` for
/// the specified `userId` and `workstation`.
void processRequest(int userId, int workstation, const char *request);
};
// requestprocessor.cpp
// PRIVATE CLASS METHODS

Now, we define the contextReference method, which defines a thread-local RequestContext pointer, context, initialized to 0, and returns a reference providing modifiable access to that pointer.

const RequestContext *&RequestProcessor::contextReference()
{
BSLMT_THREAD_LOCAL_VARIABLE(const RequestContext *, context, 0);
return context;
}
// CLASS METHODS
const RequestContext *RequestProcessor::requestContext()
{
return contextReference();
}
// MANIPULATORS

Then, we define the processRequest method, which first sets the thread-local pointer containing the request context, and then processes the request.

void RequestProcessor::processRequest(int userId,
int workstation,
const char *request)
{
RequestContext currentContext = {userId, workstation};
contextReference() = &currentContext;
// Process the request.
contextReference() = 0;
}

Finally, we define a separate function myFunction that uses the RequestProcessor class to access the RequestContext for the current thread.

void myFunction()
{
const RequestContext *context = RequestProcessor::requestContext();
// Perform some task that makes use of this threads 'requestContext'.
// ...
}

Macro Definition Documentation

◆ BSLMT_THREAD_LOCAL_KEYWORD

#define BSLMT_THREAD_LOCAL_KEYWORD   __thread

◆ BSLMT_THREAD_LOCAL_VARIABLE

#define BSLMT_THREAD_LOCAL_VARIABLE (   BASIC_TYPE,
  VARIABLE_NAME,
  INITIAL_VALUE 
)    static BSLMT_THREAD_LOCAL_KEYWORD BASIC_TYPE VARIABLE_NAME = INITIAL_VALUE;

Define, at function or namespace scope, a thread-local static variable having the specified VARIABLE_NAME of the specified BASIC_TYPE, initialized with the specified INITIAL_VALUE. If VARIABLE_NAME is not a valid variable name, or INITIAL_VALUE is not convertible to the type BASIC_TYPE, the instantiation of this macro will result in a compile time error. The behavior is undefined unless INITIAL_VALUE is a compile time constant value.