Skip to content

Commit 1aad565

Browse files
author
Roel Rymenants
committed
Reverse lock order to avoid deadlock
In class AutorecoveringConnection: maybeDeleteRecordedAutoDeleteExchange takes the locks on - recordedExchanges - consumers maybeDeleteRecordedAutoDeleteQueue takes the locks on - recordedQueues - consumers Since the latter one also calls the former, the following deadlock may occur Thread1: maybeDeleteRecordedAutoDeleteExchange - locked recordedExchanges - waiting for consumers (locked by thread2) Thread2: maybeDeleteRecordedAutoDeleteQueue - locked recordedQueues - locked consumers maybeDeleteRecordedAutoDeleteExchange - waiting for recordedExchanges (locked by thread1) By reversing the locks, both flows will first lock consumers, avoiding taking other locks in a different order
1 parent 9863c16 commit 1aad565

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

src/main/java/com/rabbitmq/client/impl/recovery/AutorecoveringConnection.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,8 @@ RecordedConsumer deleteRecordedConsumer(String consumerTag) {
772772
}
773773

774774
void maybeDeleteRecordedAutoDeleteQueue(String queue) {
775-
synchronized (this.recordedQueues) {
776-
synchronized (this.consumers) {
775+
synchronized (this.consumers) {
776+
synchronized (this.recordedQueues) {
777777
if(!hasMoreConsumersOnQueue(this.consumers.values(), queue)) {
778778
RecordedQueue q = this.recordedQueues.get(queue);
779779
// last consumer on this connection is gone, remove recorded queue
@@ -787,8 +787,8 @@ void maybeDeleteRecordedAutoDeleteQueue(String queue) {
787787
}
788788

789789
void maybeDeleteRecordedAutoDeleteExchange(String exchange) {
790-
synchronized (this.recordedExchanges) {
791-
synchronized (this.consumers) {
790+
synchronized (this.consumers) {
791+
synchronized (this.recordedExchanges) {
792792
if(!hasMoreDestinationsBoundToExchange(Utility.copy(this.recordedBindings), exchange)) {
793793
RecordedExchange x = this.recordedExchanges.get(exchange);
794794
// last binding where this exchange is the source is gone, remove recorded exchange

0 commit comments

Comments
 (0)