Skip to content

Commit eacd3ad

Browse files
authored
Fix: Queue::configure deadlocks with QueueHandle::deconfigure (#900)
Signed-off-by: dorjesinpo <[email protected]>
1 parent 8f789be commit eacd3ad

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

src/groups/mqb/mqbblp/mqbblp_queue.cpp

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,51 @@ namespace mqbblp {
6262
// class Queue
6363
// -----------
6464

65-
void Queue::configureDispatched(int* result,
66-
bsl::ostream* errorDescription,
67-
bool isReconfigure)
65+
void Queue::configureDispatchedAndPost(int* result,
66+
bsl::ostream* errorDescription,
67+
bool isReconfigure,
68+
bslmt::Semaphore* sync)
6869
{
6970
// executed by the *QUEUE* dispatcher thread
7071

7172
// PRECONDITIONS
7273
BSLS_ASSERT_SAFE(dispatcher()->inDispatcherThread(this));
73-
74-
bmqu::MemOutStream throwaway(d_allocator_p);
75-
bsl::ostream& errStream = (errorDescription ? *errorDescription
76-
: throwaway);
74+
BSLS_ASSERT_SAFE(result);
75+
BSLS_ASSERT_SAFE(errorDescription);
76+
BSLS_ASSERT_SAFE(sync);
7777

7878
int rc = 0;
7979
if (d_localQueue_mp) {
80-
rc = d_localQueue_mp->configure(errStream, isReconfigure);
80+
rc = d_localQueue_mp->configure(*errorDescription, isReconfigure);
8181
}
8282
else if (d_remoteQueue_mp) {
83-
rc = d_remoteQueue_mp->configure(errStream, isReconfigure);
83+
rc = d_remoteQueue_mp->configure(*errorDescription, isReconfigure);
8484
}
8585
else {
8686
BSLS_ASSERT_OPT(false && "Uninitialized queue");
8787
}
8888

89-
if (result) {
90-
*result = rc;
89+
*result = rc;
90+
sync->post();
91+
}
92+
93+
void Queue::configureDispatched(bool isReconfigure)
94+
{
95+
// executed by the *QUEUE* dispatcher thread
96+
97+
// PRECONDITIONS
98+
BSLS_ASSERT_SAFE(dispatcher()->inDispatcherThread(this));
99+
100+
bmqu::MemOutStream throwaway(d_allocator_p);
101+
102+
if (d_localQueue_mp) {
103+
d_localQueue_mp->configure(throwaway, isReconfigure);
104+
}
105+
else if (d_remoteQueue_mp) {
106+
d_remoteQueue_mp->configure(throwaway, isReconfigure);
107+
}
108+
else {
109+
BSLS_ASSERT_OPT(false && "Uninitialized queue");
91110
}
92111
}
93112

@@ -584,18 +603,27 @@ int Queue::configure(bsl::ostream* errorDescription_p,
584603

585604
// Enqueue a configure callback in the queue-dispatcher thread.
586605
int result = 0;
587-
dispatcher()->execute(
588-
bdlf::BindUtil::bind(&Queue::configureDispatched,
589-
this,
590-
(wait ? &result : NULL),
591-
(wait ? errorDescription_p : NULL),
592-
isReconfigure),
593-
this);
594-
if (!wait) {
595-
return 0; // RETURN
606+
607+
if (wait) {
608+
bslmt::Semaphore sync;
609+
dispatcher()->execute(
610+
bdlf::BindUtil::bind(&Queue::configureDispatchedAndPost,
611+
this,
612+
&result,
613+
errorDescription_p,
614+
isReconfigure,
615+
&sync),
616+
this);
617+
618+
sync.wait();
619+
}
620+
else {
621+
dispatcher()->execute(bdlf::BindUtil::bind(&Queue::configureDispatched,
622+
this,
623+
isReconfigure),
624+
this);
596625
}
597626

598-
dispatcher()->synchronize(this);
599627
return result;
600628
}
601629

src/groups/mqb/mqbblp/mqbblp_queue.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,11 @@ class Queue BSLS_CPP11_FINAL : public mqbi::Queue {
122122

123123
private:
124124
// PRIVATE MANIPULATORS
125-
void configureDispatched(int* result,
126-
bsl::ostream* errorDescription,
127-
bool isReconfigure);
125+
void configureDispatchedAndPost(int* result,
126+
bsl::ostream* errorDescription,
127+
bool isReconfigure,
128+
bslmt::Semaphore* sync);
129+
void configureDispatched(bool isReconfigure);
128130

129131
void getHandleDispatched(
130132
const bsl::shared_ptr<mqbi::QueueHandleRequesterContext>&

src/groups/mqb/mqbi/mqbi_cluster.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ const char* ClusterErrorCode::toAscii(ClusterErrorCode::Enum value)
6363
CASE(NOT_FOLLOWER)
6464
CASE(NOT_REPLICA)
6565
CASE(CSL_FAILURE)
66+
CASE(STORAGE_FAILURE)
6667
default: return "(* UNKNOWN *)";
6768
}
6869

0 commit comments

Comments
 (0)