21 #ifndef __TBB__flow_graph_async_msg_impl_H 22 #define __TBB__flow_graph_async_msg_impl_H 24 #ifndef __TBB_flow_graph_H 25 #error Do not #include this internal file directly; use public TBB headers instead. 34 template<
typename T,
typename =
void >
37 typedef T filtered_type;
39 static const bool is_async_type =
false;
41 static const void* to_void_ptr(
const T& t) {
42 return static_cast<const void*
>(&t);
45 static void* to_void_ptr(T& t) {
46 return static_cast<void*
>(&t);
49 static const T& from_void_ptr(
const void* p) {
50 return *
static_cast<const T*
>(p);
53 static T& from_void_ptr(
void* p) {
54 return *
static_cast<T*
>(p);
57 static task* try_put_task_wrapper_impl( receiver<T>*
const this_recv,
const void *p,
bool is_async ) {
62 task*
const new_task = msg.my_storage->subscribe(*this_recv);
69 return this_recv->try_put_task( from_void_ptr(p) );
74 template<
typename T >
75 struct async_helpers< T, typename
std::enable_if< std::is_base_of<async_msg<typename T::async_msg_data_type>, T>::value >::type > {
77 typedef typename T::async_msg_data_type filtered_type;
79 static const bool is_async_type =
true;
82 static const void* to_void_ptr(
const T& t) {
86 static void* to_void_ptr(T& t) {
91 static const T& from_void_ptr(
const void* p) {
95 static T& from_void_ptr(
void* p) {
100 static task* try_put_task_wrapper_impl(receiver<T>*
const this_recv,
const void *p,
bool is_async) {
103 return this_recv->try_put_task( from_void_ptr(p) );
109 return this_recv->try_put_task(msg);
114 template <
typename T>
117 typedef receiver<T> async_storage_client;
124 __TBB_STATIC_ASSERT( (
is_same_type<
typename strip<C>::type,
typename strip<T>::type>::value),
"incoming type must be T" );
132 __TBB_STATIC_ASSERT( (
is_same_type<
typename strip<C>::type,
typename strip<T>::type>::value),
"incoming type must be T" );
138 __TBB_ASSERT(
false,
"double set() call");
142 my_data = std::forward<C>(data);
147 for (
typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) {
148 (*it)->try_put(my_data);
154 task* subscribe(async_storage_client& client) {
161 for (
typename subscriber_list_type::iterator it = my_clients.begin(); it != my_clients.end(); ++it) {
162 __TBB_ASSERT(*it != &client,
"unexpected double subscription");
164 #endif // TBB_USE_ASSERT 167 my_clients.push_back(&client);
168 return SUCCESSFULLY_ENQUEUED;
172 __TBB_ASSERT(my_data_ready.load<
tbb::relaxed>(),
"data is NOT ready");
173 return client.try_put_task(my_data);
182 typedef std::vector<async_storage_client*> subscriber_list_type;
183 subscriber_list_type my_clients;
188 template <
typename T>
190 template<
typename >
friend class receiver;
193 typedef T async_msg_data_type;
203 void set(
const T& t) {
208 my_storage->set( std::move(t) );
214 virtual void finalize()
const {}
217 typedef std::shared_ptr< internal::async_storage<T> > async_storage_ptr;
218 async_storage_ptr my_storage;
221 #endif // __TBB__flow_graph_async_msg_impl_H Detects whether two given types are the same.
Definition: _template_helpers.h:56
Definition: _flow_graph_async_msg_impl.h:115
Definition: _tbb_windef.h:37
Acquire.
Definition: atomic.h:47
Definition: _flow_graph_async_msg_impl.h:35
No ordering.
Definition: atomic.h:51
Definition: _flow_graph_async_msg_impl.h:30
Represents acquisition of a mutex.
Definition: spin_mutex.h:54
Definition: _flow_graph_async_msg_impl.h:32
A lock that occupies a single byte.
Definition: spin_mutex.h:40
Release.
Definition: atomic.h:49