@@ -170,10 +170,10 @@ void ClientImpl::handleCreateProducer(const Result result, const LookupDataResul
170170 if (!result) {
171171 ProducerImplBasePtr producer;
172172 if (partitionMetadata->getPartitions () > 0 ) {
173- producer = std::make_shared<PartitionedProducerImpl>(shared_from_this () , topicName,
173+ producer = std::make_shared<PartitionedProducerImpl>(* this , topicName,
174174 partitionMetadata->getPartitions (), conf);
175175 } else {
176- producer = std::make_shared<ProducerImpl>(shared_from_this () , *topicName, conf);
176+ producer = std::make_shared<ProducerImpl>(* this , *topicName, conf);
177177 }
178178 producer->getProducerCreatedFuture ().addListener (
179179 std::bind (&ClientImpl::handleProducerCreated, shared_from_this (), std::placeholders::_1,
@@ -189,9 +189,15 @@ void ClientImpl::handleCreateProducer(const Result result, const LookupDataResul
189189void ClientImpl::handleProducerCreated (Result result, ProducerImplBaseWeakPtr producerBaseWeakPtr,
190190 CreateProducerCallback callback, ProducerImplBasePtr producer) {
191191 if (result == ResultOk) {
192- Lock lock (mutex_);
193- producers_.push_back (producer);
194- lock.unlock ();
192+ auto pair = producers_.emplace (producer.get (), producer);
193+ if (!pair.second ) {
194+ auto existingProducer = pair.first ->second .lock ();
195+ LOG_ERROR (" Unexpected existing producer at the same address: "
196+ << pair.first ->first << " , producer: "
197+ << (existingProducer ? existingProducer->getProducerName () : " (null)" ));
198+ callback (ResultUnknownError, {});
199+ return ;
200+ }
195201 callback (result, Producer (producer));
196202 } else {
197203 callback (result, {});
@@ -236,14 +242,23 @@ void ClientImpl::handleReaderMetadataLookup(const Result result, const LookupDat
236242 return ;
237243 }
238244
239- ReaderImplPtr reader = std::make_shared<ReaderImpl>(shared_from_this () , topicName->toString (), conf,
245+ ReaderImplPtr reader = std::make_shared<ReaderImpl>(* this , topicName->toString (), conf,
240246 getListenerExecutorProvider ()->get (), callback);
241247 ConsumerImplBasePtr consumer = reader->getConsumer ().lock ();
242248 auto self = shared_from_this ();
243249 reader->start (startMessageId, [this , self](const ConsumerImplBaseWeakPtr& weakConsumerPtr) {
244- Lock lock (mutex_);
245- consumers_.push_back (weakConsumerPtr);
246- lock.unlock ();
250+ auto consumer = weakConsumerPtr.lock ();
251+ if (consumer) {
252+ auto pair = consumers_.emplace (consumer.get (), consumer);
253+ if (!pair.second ) {
254+ auto existingConsumer = pair.first ->second .lock ();
255+ LOG_ERROR (" Unexpected existing consumer at the same address: "
256+ << pair.first ->first
257+ << " , consumer: " << (existingConsumer ? existingConsumer->getName () : " (null)" ));
258+ }
259+ } else {
260+ LOG_ERROR (" Unexpected case: the consumer is somehow expired" );
261+ }
247262 });
248263}
249264
@@ -286,7 +301,7 @@ void ClientImpl::createPatternMultiTopicsConsumer(const Result result, const Nam
286301 PatternMultiTopicsConsumerImpl::topicsPatternFilter (*topics, pattern);
287302
288303 consumer = std::make_shared<PatternMultiTopicsConsumerImpl>(
289- shared_from_this () , regexPattern, *matchTopics, subscriptionName, conf, lookupServicePtr_);
304+ * this , regexPattern, *matchTopics, subscriptionName, conf, lookupServicePtr_);
290305
291306 consumer->getConsumerCreatedFuture ().addListener (
292307 std::bind (&ClientImpl::handleConsumerCreated, shared_from_this (), std::placeholders::_1,
@@ -324,7 +339,7 @@ void ClientImpl::subscribeAsync(const std::vector<std::string>& topics, const st
324339 }
325340
326341 ConsumerImplBasePtr consumer = std::make_shared<MultiTopicsConsumerImpl>(
327- shared_from_this () , topics, subscriptionName, topicNamePtr, conf, lookupServicePtr_);
342+ * this , topics, subscriptionName, topicNamePtr, conf, lookupServicePtr_);
328343
329344 consumer->getConsumerCreatedFuture ().addListener (std::bind (&ClientImpl::handleConsumerCreated,
330345 shared_from_this (), std::placeholders::_1,
@@ -374,12 +389,12 @@ void ClientImpl::handleSubscribe(const Result result, const LookupDataResultPtr
374389 callback (ResultInvalidConfiguration, Consumer ());
375390 return ;
376391 }
377- consumer = std::make_shared<MultiTopicsConsumerImpl>(shared_from_this () , topicName,
392+ consumer = std::make_shared<MultiTopicsConsumerImpl>(* this , topicName,
378393 partitionMetadata->getPartitions (),
379394 subscriptionName, conf, lookupServicePtr_);
380395 } else {
381- auto consumerImpl = std::make_shared<ConsumerImpl>(
382- shared_from_this (), topicName-> toString (), subscriptionName, conf, topicName->isPersistent ());
396+ auto consumerImpl = std::make_shared<ConsumerImpl>(* this , topicName-> toString (), subscriptionName,
397+ conf, topicName->isPersistent ());
383398 consumerImpl->setPartitionIndex (topicName->getPartitionIndex ());
384399 consumer = consumerImpl;
385400 }
@@ -397,9 +412,15 @@ void ClientImpl::handleSubscribe(const Result result, const LookupDataResultPtr
397412void ClientImpl::handleConsumerCreated (Result result, ConsumerImplBaseWeakPtr consumerImplBaseWeakPtr,
398413 SubscribeCallback callback, ConsumerImplBasePtr consumer) {
399414 if (result == ResultOk) {
400- Lock lock (mutex_);
401- consumers_.push_back (consumer);
402- lock.unlock ();
415+ auto pair = consumers_.emplace (consumer.get (), consumer);
416+ if (!pair.second ) {
417+ auto existingConsumer = pair.first ->second .lock ();
418+ LOG_ERROR (" Unexpected existing consumer at the same address: "
419+ << pair.first ->first
420+ << " , consumer: " << (existingConsumer ? existingConsumer->getName () : " (null)" ));
421+ callback (ResultUnknownError, {});
422+ return ;
423+ }
403424 callback (result, Consumer (consumer));
404425 } else {
405426 callback (result, {});
@@ -478,12 +499,11 @@ void ClientImpl::getPartitionsForTopicAsync(const std::string& topic, GetPartiti
478499
479500void ClientImpl::closeAsync (CloseCallback callback) {
480501 Lock lock (mutex_);
481- ProducersList producers (producers_);
482- ConsumersList consumers (consumers_);
483-
484- if (state_ != Open && callback) {
502+ if (state_ != Open) {
485503 lock.unlock ();
486- callback (ResultAlreadyClosed);
504+ if (callback) {
505+ callback (ResultAlreadyClosed);
506+ }
487507 return ;
488508 }
489509 // Set the state to Closing so that no producers could get added
@@ -492,12 +512,15 @@ void ClientImpl::closeAsync(CloseCallback callback) {
492512
493513 memoryLimitController_.close ();
494514
515+ auto producers = producers_.move ();
516+ auto consumers = consumers_.move ();
517+
495518 SharedInt numberOfOpenHandlers = std::make_shared<int >(producers.size () + consumers.size ());
496519 LOG_INFO (" Closing Pulsar client with " << producers.size () << " producers and " << consumers.size ()
497520 << " consumers" );
498521
499- for (ProducersList::iterator it = producers. begin (); it != producers. end (); ++it ) {
500- ProducerImplBasePtr producer = it-> lock ();
522+ for (auto && kv : producers) {
523+ ProducerImplBasePtr producer = kv. second . lock ();
501524 if (producer && !producer->isClosed ()) {
502525 producer->closeAsync (std::bind (&ClientImpl::handleClose, shared_from_this (),
503526 std::placeholders::_1, numberOfOpenHandlers, callback));
@@ -507,8 +530,8 @@ void ClientImpl::closeAsync(CloseCallback callback) {
507530 }
508531 }
509532
510- for (ConsumersList::iterator it = consumers. begin (); it != consumers. end (); ++it ) {
511- ConsumerImplBasePtr consumer = it-> lock ();
533+ for (auto && kv : consumers) {
534+ ConsumerImplBasePtr consumer = kv. second . lock ();
512535 if (consumer && !consumer->isClosed ()) {
513536 consumer->closeAsync (std::bind (&ClientImpl::handleClose, shared_from_this (),
514537 std::placeholders::_1, numberOfOpenHandlers, callback));
@@ -562,23 +585,18 @@ void ClientImpl::handleClose(Result result, SharedInt numberOfOpenHandlers, Resu
562585}
563586
564587void ClientImpl::shutdown () {
565- Lock lock (mutex_);
566- ProducersList producers;
567- ConsumersList consumers;
568-
569- producers.swap (producers_);
570- consumers.swap (consumers_);
571- lock.unlock ();
588+ auto producers = producers_.move ();
589+ auto consumers = consumers_.move ();
572590
573- for (ProducersList::iterator it = producers. begin (); it != producers. end (); ++it ) {
574- ProducerImplBasePtr producer = it-> lock ();
591+ for (auto && kv : producers) {
592+ ProducerImplBasePtr producer = kv. second . lock ();
575593 if (producer) {
576594 producer->shutdown ();
577595 }
578596 }
579597
580- for (ConsumersList::iterator it = consumers. begin (); it != consumers. end (); ++it ) {
581- ConsumerImplBasePtr consumer = it-> lock ();
598+ for (auto && kv : consumers) {
599+ ConsumerImplBasePtr consumer = kv. second . lock ();
582600 if (consumer) {
583601 consumer->shutdown ();
584602 }
@@ -631,26 +649,24 @@ uint64_t ClientImpl::newRequestId() {
631649}
632650
633651uint64_t ClientImpl::getNumberOfProducers () {
634- Lock lock (mutex_);
635652 uint64_t numberOfAliveProducers = 0 ;
636- for ( const auto & producer : producers_ ) {
653+ producers_. forEachValue ([&numberOfAliveProducers]( const ProducerImplBaseWeakPtr & producer) {
637654 const auto & producerImpl = producer.lock ();
638655 if (producerImpl) {
639656 numberOfAliveProducers += producerImpl->getNumberOfConnectedProducer ();
640657 }
641- }
658+ });
642659 return numberOfAliveProducers;
643660}
644661
645662uint64_t ClientImpl::getNumberOfConsumers () {
646- Lock lock (mutex_);
647663 uint64_t numberOfAliveConsumers = 0 ;
648- for ( const auto & consumer : consumers_ ) {
664+ consumers_. forEachValue ([&numberOfAliveConsumers]( const ConsumerImplBaseWeakPtr & consumer) {
649665 const auto consumerImpl = consumer.lock ();
650666 if (consumerImpl) {
651667 numberOfAliveConsumers += consumerImpl->getNumberOfConnectedConsumer ();
652668 }
653- }
669+ });
654670 return numberOfAliveConsumers;
655671}
656672
0 commit comments