@@ -81,10 +81,11 @@ Channel::Channel(bdlbb::BlobBufferFactory* blobBufferFactory,
8181 d_allocators.get(" ItemPool" ))
8282, d_buffer(1024 , allocator)
8383, d_doStop(false )
84- , d_state(e_INITIAL )
84+ , d_state(e_RESET )
8585, d_description(name + " - " , d_allocator_p)
8686, d_name(name, d_allocator_p)
8787, d_stats()
88+ , d_isClosing(false )
8889{
8990 bslmt::ThreadAttributes attr = bmqsys::ThreadUtil::defaultAttributes ();
9091 bsl::string threadName (" bmqNet-" );
@@ -261,19 +262,14 @@ void Channel::resetChannel()
261262
262263void Channel::closeChannel ()
263264{
264- bsl::shared_ptr<bmqio::Channel> channel;
265- {
266- bslmt::LockGuard<bslmt::Mutex> guard (&d_mutex); // LOCK
267- channel = d_channel_wp.lock ();
268- } // UNLOCK
265+ d_isClosing.store (true );
269266
270- if (BSLS_PERFORMANCEHINT_PREDICT_LIKELY (channel)) {
271- channel->close ();
272- // Set the state to e_CLOSE to avoid repeated attempts to write until
273- // 'OnClose' calls 'resetChannel'.
267+ // No need to 'signal' to interrupt the waiting.
268+ // Waiting means there is no connection and therefore nothing to close.
274269
275- d_state.testAndSwap (e_READY, e_CLOSE);
276- }
270+ wakeUp ();
271+
272+ // do not wait for all items to drain.
277273}
278274
279275void Channel::setChannel (const bsl::weak_ptr<bmqio::Channel>& value)
@@ -747,7 +743,7 @@ void Channel::threadFn()
747743 bsl::string description;
748744 int mode = e_BLOCK;
749745
750- BSLS_ASSERT (d_state == e_INITIAL || d_state == e_RESET);
746+ BSLS_ASSERT (d_state == e_RESET);
751747
752748 while (!d_doStop) {
753749 bmqc::MonitoredQueueState::Enum queueState;
@@ -796,17 +792,14 @@ void Channel::threadFn()
796792 item.reset ();
797793 reset ();
798794
799- d_state = e_INITIAL;
800795 mode = e_BLOCK;
801- }
796+ d_isClosing. store ( false );
802797
803- if (d_state == e_INITIAL) {
804798 channel = d_channel_wp.lock ();
805799 description = d_description;
806800
807801 if (channel) {
808- // This is the only place for transitions:
809- // e_IDLE -> e_READY
802+ // This is the only place for the transition
810803 // e_RESET -> e_READY
811804 d_state = e_READY;
812805 }
@@ -856,6 +849,13 @@ void Channel::threadFn()
856849 // BLOCK mode and wait for the next batch of items.
857850 mode = e_BLOCK;
858851 }
852+ // if draining, this is where it stops.
853+ // Does not matter if 'flushAll' has failed; must close
854+ if (d_isClosing) {
855+ channel->close ();
856+ d_state.testAndSwap (e_READY, e_CLOSE);
857+ // bmqio::Channel observer will trigger 'resetChannel'
858+ }
859859 } break ;
860860 default : {
861861 BSLS_ASSERT (false && " Unreachable by design" );
0 commit comments