@@ -92,6 +92,11 @@ void NtcChannelFactory::processListenerResult(
92
92
bslstl::SharedPtrUtil::dynamicCast (&alias, channel);
93
93
if (alias) {
94
94
int catalogHandle = d_channels.add (alias);
95
+
96
+ // Increment resource usage count for new channel
97
+ BALL_LOG_ERROR << " d_resourceMonitor.acquire()" ;
98
+ d_resourceMonitor.acquire ();
99
+
95
100
alias->setChannelId (catalogHandle);
96
101
alias->onClose (bdlf::BindUtil::bind (
97
102
&NtcChannelFactory::processChannelClosed,
@@ -122,16 +127,8 @@ void NtcChannelFactory::processListenerClosed(int handle)
122
127
<< BALL_LOG_END;
123
128
}
124
129
125
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
126
- if (d_state == e_STATE_STOPPING) {
127
- if (d_channels.length () == 0 && d_listeners.length () == 0 ) {
128
- BALL_LOG_TRACE << " NTC factory channels and listeners have closed"
129
- << BALL_LOG_END;
130
-
131
- d_state = e_STATE_STOPPED;
132
- d_stateCondition.signal ();
133
- }
134
- }
130
+ BALL_LOG_ERROR << " d_resourceMonitor.release()" ;
131
+ d_resourceMonitor.release (); // Decrement resource usage count
135
132
}
136
133
137
134
void NtcChannelFactory::processChannelResult (
@@ -166,16 +163,8 @@ void NtcChannelFactory::processChannelClosed(int handle)
166
163
<< BALL_LOG_END;
167
164
}
168
165
169
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
170
- if (d_state == e_STATE_STOPPING) {
171
- if (d_channels.length () == 0 && d_listeners.length () == 0 ) {
172
- BALL_LOG_TRACE << " NTC factory channels and listeners have closed"
173
- << BALL_LOG_END;
174
-
175
- d_state = e_STATE_STOPPED;
176
- d_stateCondition.signal ();
177
- }
178
- }
166
+ BALL_LOG_ERROR << " d_resourceMonitor.release()" ;
167
+ d_resourceMonitor.release (); // Decrement resource usage count
179
168
}
180
169
181
170
// CREATORS
@@ -189,9 +178,9 @@ NtcChannelFactory::NtcChannelFactory(
189
178
, d_createSignaler(basicAllocator)
190
179
, d_limitSignaler(basicAllocator)
191
180
, d_owned(false )
192
- , d_stateMutex( )
193
- , d_stateCondition( )
194
- , d_state(e_STATE_DEFAULT )
181
+ , d_validator( false )
182
+ , d_resourceMonitor( false )
183
+ , d_isInterfaceStarted( false )
195
184
, d_allocator_p(bslma::Default::allocator(basicAllocator))
196
185
{
197
186
}
@@ -206,9 +195,9 @@ NtcChannelFactory::NtcChannelFactory(
206
195
, d_createSignaler(basicAllocator)
207
196
, d_limitSignaler(basicAllocator)
208
197
, d_owned(true )
209
- , d_stateMutex( )
210
- , d_stateCondition( )
211
- , d_state(e_STATE_DEFAULT )
198
+ , d_validator( false )
199
+ , d_resourceMonitor( false )
200
+ , d_isInterfaceStarted( false )
212
201
, d_allocator_p(bslma::Default::allocator(basicAllocator))
213
202
{
214
203
bsl::shared_ptr<bdlbb::BlobBufferFactory> blobBufferFactory_sp (
@@ -232,7 +221,6 @@ NtcChannelFactory::~NtcChannelFactory()
232
221
d_interface_sp.reset ();
233
222
}
234
223
235
- BSLS_ASSERT_OPT (d_state == e_STATE_DEFAULT || d_state == e_STATE_STOPPED);
236
224
BSLS_ASSERT_OPT (d_listeners.length () == 0 );
237
225
BSLS_ASSERT_OPT (d_channels.length () == 0 );
238
226
BSLS_ASSERT_OPT (d_createSignaler.slotCount () == 0 );
@@ -243,65 +231,60 @@ NtcChannelFactory::~NtcChannelFactory()
243
231
// MANIPULATORS
244
232
int NtcChannelFactory::start ()
245
233
{
246
- ntsa::Error error ;
234
+ bmqu::AtomicValidatorGuard valGuard (&d_validator) ;
247
235
248
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
236
+ if (valGuard.isValid ()) {
237
+ // Already started.
238
+ return 1 ; // RETURN
239
+ }
249
240
250
- switch (d_state) {
251
- case e_STATE_DEFAULT:
252
- error = d_interface_sp->start ();
241
+ if (!d_isInterfaceStarted) {
242
+ // Make sure we don't restart the same interface if we have
243
+ // `start()`, `stop()`, `start()` sequence.
244
+ d_isInterfaceStarted = true ;
245
+ const ntsa::Error error = d_interface_sp->start ();
253
246
if (error) {
254
247
return error.number (); // RETURN
255
248
}
256
- d_state = e_STATE_STARTED;
257
- return 0 ; // RETURN
258
- case e_STATE_STOPPED: d_state = e_STATE_STARTED; return 0 ; // RETURN
259
- case e_STATE_STARTED: return 0 ; // RETURN
260
- case e_STATE_STOPPING: return 1 ; // RETURN
261
- default : return 1 ; // RETURN
262
249
}
250
+
251
+ d_resourceMonitor.reset ();
252
+ d_validator.reset ();
253
+
254
+ return 0 ;
263
255
}
264
256
265
257
void NtcChannelFactory::stop ()
266
258
{
267
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
259
+ bmqu::AtomicValidatorGuard valGuard (&d_validator);
268
260
269
- if (d_state != e_STATE_STARTED ) {
261
+ if (!valGuard. isValid () ) {
270
262
return ; // RETURN
271
263
}
272
264
273
- d_state = e_STATE_STOPPING;
265
+ valGuard.release ()->release ();
266
+ d_validator.invalidate (); // Disallow new listen/connect
274
267
275
268
BALL_LOG_TRACE << " NTC factory is stopping" << BALL_LOG_END;
276
269
277
- if (d_channels.length () == 0 && d_listeners.length () == 0 ) {
278
- d_state = e_STATE_STOPPED;
279
- }
280
- else {
281
- {
282
- ChannelIterator iterator (d_channels);
283
- while (iterator) {
284
- iterator.value ()->close (bmqio::Status ());
285
- ++iterator;
286
- }
287
- }
288
-
289
- {
290
- ListenerIterator iterator (d_listeners);
291
- while (iterator) {
292
- iterator.value ()->cancel ();
293
- ++iterator;
294
- }
270
+ {
271
+ ChannelIterator iterator (d_channels);
272
+ while (iterator) {
273
+ iterator.value ()->close (bmqio::Status ());
274
+ ++iterator;
295
275
}
276
+ }
296
277
297
- while (d_state != e_STATE_STOPPED) {
298
- d_stateCondition.wait (&d_stateMutex);
278
+ {
279
+ ListenerIterator iterator (d_listeners);
280
+ while (iterator) {
281
+ iterator.value ()->cancel ();
282
+ ++iterator;
299
283
}
300
284
}
301
285
302
- BSLS_ASSERT_OPT (d_state == e_STATE_STOPPED);
303
-
304
- lock.release ()->unlock ();
286
+ // Wait until all channels and listeners are finished
287
+ d_resourceMonitor.invalidate ();
305
288
306
289
d_createSignaler.disconnectAllSlots ();
307
290
d_limitSignaler.disconnectAllSlots ();
@@ -325,9 +308,9 @@ void NtcChannelFactory::listen(Status* status,
325
308
handle->reset ();
326
309
}
327
310
328
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
311
+ bmqu::AtomicValidatorGuard valGuard (&d_validator);
329
312
330
- if (d_state != e_STATE_STARTED ) {
313
+ if (!valGuard. isValid () ) {
331
314
bmqio::NtcListenerUtil::fail (status,
332
315
bmqio::StatusCategory::e_GENERIC_ERROR,
333
316
" state" ,
@@ -359,10 +342,15 @@ void NtcChannelFactory::listen(Status* status,
359
342
360
343
rc = listener->listen (status, options);
361
344
if (rc != 0 ) {
345
+ BALL_LOG_ERROR << " listener failed" ;
362
346
d_listeners.remove (catalogHandle);
363
347
return ; // RETURN
364
348
}
365
349
350
+ // Increment resource usage count for new listener
351
+ BALL_LOG_ERROR << " d_resourceMonitor.acquire()" ;
352
+ d_resourceMonitor.acquire ();
353
+
366
354
if (handle) {
367
355
bslma::ManagedPtr<bmqio::NtcListener> alias (listener.managedPtr ());
368
356
handle->loadAlias (alias, listener.get ());
@@ -389,9 +377,9 @@ void NtcChannelFactory::connect(Status* status,
389
377
handle->reset ();
390
378
}
391
379
392
- bslmt::LockGuard<bslmt::Mutex> lock (&d_stateMutex); // LOCKED
380
+ bmqu::AtomicValidatorGuard valGuard (&d_validator);
393
381
394
- if (d_state != e_STATE_STARTED ) {
382
+ if (!valGuard. isValid () ) {
395
383
bmqio::NtcChannelUtil::fail (status,
396
384
bmqio::StatusCategory::e_GENERIC_ERROR,
397
385
" state" ,
@@ -425,6 +413,7 @@ void NtcChannelFactory::connect(Status* status,
425
413
426
414
rc = channel->connect (status, options);
427
415
if (rc != 0 ) {
416
+ BALL_LOG_ERROR << " connect failed" ;
428
417
d_channels.remove (catalogHandle);
429
418
return ; // RETURN
430
419
}
@@ -434,6 +423,10 @@ void NtcChannelFactory::connect(Status* status,
434
423
handle->loadAlias (alias, channel.get ());
435
424
}
436
425
426
+ // Increment resource usage count for new channel
427
+ BALL_LOG_ERROR << " d_resourceMonitor.acquire()" ;
428
+ d_resourceMonitor.acquire ();
429
+
437
430
BALL_LOG_TRACE << " NTC channel " << AddressFormatter (channel.get ())
438
431
<< " to " << channel->peerUri () << " registered"
439
432
<< BALL_LOG_END;
0 commit comments