void close() noexcept {
context * active_ctx = context::active();
detail::spinlock_lock lk{ splk_ };
- closed_ = true;
- // notify all waiting producers
- while ( ! waiting_producers_.empty() ) {
- context * producer_ctx = & waiting_producers_.front();
- waiting_producers_.pop_front();
- std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
- if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
- // notify context
- active_ctx->schedule( producer_ctx);
- } else if ( static_cast< std::intptr_t >( 0) == expected) {
- // no timed-wait op.
- // notify context
- active_ctx->schedule( producer_ctx);
+ if ( ! closed_) {
+ closed_ = true;
+ // notify all waiting producers
+ while ( ! waiting_producers_.empty() ) {
+ context * producer_ctx = & waiting_producers_.front();
+ waiting_producers_.pop_front();
+ std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
+ if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ // notify context
+ active_ctx->schedule( producer_ctx);
+ } else if ( static_cast< std::intptr_t >( 0) == expected) {
+ // no timed-wait op.
+ // notify context
+ active_ctx->schedule( producer_ctx);
+ }
}
- }
- // notify all waiting consumers
- while ( ! waiting_consumers_.empty() ) {
- context * consumer_ctx = & waiting_consumers_.front();
- waiting_consumers_.pop_front();
- std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
- if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
- // notify context
- active_ctx->schedule( consumer_ctx);
- } else if ( static_cast< std::intptr_t >( 0) == expected) {
- // no timed-wait op.
- // notify context
- active_ctx->schedule( consumer_ctx);
+ // notify all waiting consumers
+ while ( ! waiting_consumers_.empty() ) {
+ context * consumer_ctx = & waiting_consumers_.front();
+ waiting_consumers_.pop_front();
+ std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
+ if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ // notify context
+ active_ctx->schedule( consumer_ctx);
+ } else if ( static_cast< std::intptr_t >( 0) == expected) {
+ // no timed-wait op.
+ // notify context
+ active_ctx->schedule( consumer_ctx);
+ }
}
}
}
waiting_consumers_.pop_front();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_consumers_.empty() ) {
context * consumer_ctx = & waiting_consumers_.front();
waiting_consumers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_consumers_.empty() ) {
context * consumer_ctx = & waiting_consumers_.front();
waiting_consumers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_consumers_.empty() ) {
context * consumer_ctx = & waiting_consumers_.front();
waiting_consumers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_consumers_.empty() ) {
context * consumer_ctx = & waiting_consumers_.front();
waiting_consumers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_consumers_.empty() ) {
context * consumer_ctx = & waiting_consumers_.front();
waiting_consumers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( consumer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( consumer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( consumer_ctx);
while ( ! waiting_producers_.empty() ) {
context * producer_ctx = & waiting_producers_.front();
waiting_producers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( producer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( producer_ctx);
while ( ! waiting_producers_.empty() ) {
context * producer_ctx = & waiting_producers_.front();
waiting_producers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( producer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( producer_ctx);
while ( ! waiting_producers_.empty() ) {
context * producer_ctx = & waiting_producers_.front();
waiting_producers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( producer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( producer_ctx);
while ( ! waiting_producers_.empty() ) {
context * producer_ctx = & waiting_producers_.front();
waiting_producers_.pop_front();
- lk.unlock();
std::intptr_t expected = reinterpret_cast< std::intptr_t >( this);
if ( producer_ctx->twstatus.compare_exchange_strong( expected, static_cast< std::intptr_t >( -1), std::memory_order_acq_rel) ) {
+ lk.unlock();
// notify context
active_ctx->schedule( producer_ctx);
break;
} else if ( static_cast< std::intptr_t >( 0) == expected) {
+ lk.unlock();
// no timed-wait op.
// notify context
active_ctx->schedule( producer_ctx);
}
iterator & operator++() {
+ reinterpret_cast< value_type * >( std::addressof( storage_) )->~value_type();
increment_();
return * this;
}