Provide types and utilities to simplify thread creation.
More...
Detailed Description
- Outline
-
-
- Purpose:
- Provide types and utilities to simplify thread creation.
-
- Classes:
EntryPointFunctorAdapter | Encapsulate invokable object with allocator. |
EntryPointFunctorAdapterUtil | Dynamic allocation of adapter objects. |
-
- Description:
- This component defines a type,
EntryPointFunctorAdapter
, that contains a single instance of a parameterized invokable type along with an allocator to manage it. The parameterized type must provide a copy constructor and void operator()()
.
- This component also provides a C-linkage function
bslmt_EntryPointFunctorAdapter_invoker
that operates on a pointer to EntryPointFunctorAdapter
, invoking the invokable object contained within it and then deallocating the adapter object along with the contained invokable object. Together, EntryPointFunctorAdapter
and bslmt_EntryPointFunctorAdapter_invoker
simplify the process of invoking a generic functor as a C-style callback, such as a thread entry point.
- Finally, this component provides
EntryPointFunctorAdapterUtil
, a namespace for a utility function that dynamically allocates instances of EntryPointFunctorAdapter
.
-
- Usage:
- This section illustrates the intended use of this component.
-
- Example 1: Wrapping a C++ Invokable Type:
- Suppose we have an existing interface for invoking a C-linkage function and passing a void* argument to it. This situation may arise when starting threads or in general when registering a C-style callback. A simplistic example of such a function is:
extern "C" {
typedef void *(*CallbackFunction)(void*);
}
void *executeWithArgument(CallbackFunction funcPtr, void *argument)
{
return funcPtr(argument);
}
In this example, we want to use this interface to invoke a C++-style functor. Our approach will be to use bslmt_EntryPointFunctorAdapter_invoker
as the C-linkage callback function, and a dynamically allocated value of EntryPointFunctorAdapter
as the void*
argument.
- First, we define a C++ functor type. This type implements the job of counting the number of words in a string held by value.
class WordCountJob {
bsl::string d_message;
int *d_result_p;
public:
BSLMF_NESTED_TRAIT_DECLARATION(WordCountJob,
bslma::UsesBslmaAllocator);
WordCountJob(const bslstl::StringRef& message,
int *result,
bslma::Allocator *basicAllocator = 0);
WordCountJob(const WordCountJob& original,
bslma::Allocator *basicAllocator = 0);
void operator()();
};
inline
WordCountJob::WordCountJob(const bslstl::StringRef& message,
int *result,
bslma::Allocator *basicAllocator)
: d_message(message, basicAllocator)
, d_result_p(result)
{}
inline
WordCountJob::WordCountJob(const WordCountJob& original,
bslma::Allocator *basicAllocator)
: d_message(original.d_message, basicAllocator)
, d_result_p(original.d_result_p)
{}
void WordCountJob::operator()()
{
bool inWord = false;
*d_result_p = 0;
for (unsigned i = 0; i < d_message.length(); ++i) {
if (isspace(d_message[i])) {
inWord = false;
} else if (!inWord) {
inWord = true;
++(*d_result_p);
}
}
}
Next, we dynamically allocate an EntryPointFunctorAdapter
wrapping an instance of this functor: Finally, we use bslmt_EntryPointFunctorAdapter_invoker
to invoke the job in the context of a C-linkage function. Note that bslmt_EntryPointFunctorAdapter_invoker
will deallocate the adapter object and the contained invokable job after executing it, so we must release the adapter from memory management via ManagedPtr
. (In general, system APIs that register callbacks may fail; newly allocated adapters are loaded into ManagedPtr
to aid in proper error and exception handling, outside the scope of this example.)
Function Documentation
void* bslmt_EntryPointFunctorAdapter_invoker |
( |
void * |
argument |
) |
|
Interpreting argument
as an EntryPointFunctorAdapter_Base*
, invoke argument->function(argument)
. Do not use outside this component.