Description
sdrtrunk Version
master
Describe the bug
The DMR traffic channel manager is using a combination of 'synchronized' and a reentrant lock for controlling access to the traffic channels controlled by the manager. This is allowing two threads to get into a deadlock. It looks like the sole method that has the synchronized method signature can have that removed since the content of the method is already protected by the lock.
As reported by a user:
sdrtrunk detected a critical application error with a threading deadlock, described as follows:
Thread ID[7018] Name [sdrtrunk channel [5/DMR] MULTI FREQ thread 1] Lock [io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor@47f4b248] Owned By [ID:8573 | NAME:io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor@47f4b248]
Thread ID[8573] Name [sdrtrunk channel [32/DMR] 478700000 thread 1] Lock [java.util.concurrent.locks.ReentrantLock$NonfairSync@217d06ea] Owned By [ID:7018 | NAME:java.util.concurrent.locks.ReentrantLock$NonfairSync@217d06ea]
Thread[#7018,sdrtrunk channel [5/DMR] MULTI FREQ thread 1,5,main] BLOCKED
at app//io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor.receive(DMRTrafficChannelManager.java:810)
at app//io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor.receive(DMRTrafficChannelManager.java:731)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.module.ProcessingChain.receive(ProcessingChain.java:1001)
at app//io.github.dsheirer.module.ProcessingChain.receive(ProcessingChain.java:103)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.controller.channel.ChannelProcessingManager.startProcessing(ChannelProcessingManager.java:533)
at app//io.github.dsheirer.controller.channel.ChannelProcessingManager.startChannelRequest(ChannelProcessingManager.java:321)
at [email protected]/java.lang.invoke.DirectMethodHandle$Holder.invokeVirtual(DirectMethodHandle$Holder)
at [email protected]/java.lang.invoke.LambdaForm$MH/0x0000000800931c00.invoke(LambdaForm$MH)
at [email protected]/java.lang.invoke.Invokers$Holder.invokeExact_MT(Invokers$Holder)
at [email protected]/jdk.internal.reflect.DirectMethodHandleAccessor.invokeImpl(Unknown Source)
at [email protected]/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
at [email protected]/java.lang.reflect.Method.invoke(Unknown Source)
at app//com.google.common.eventbus.Subscriber.invokeSubscriberMethod(Subscriber.java:85)
at app//com.google.common.eventbus.Subscriber$SynchronizedSubscriber.invokeSubscriberMethod(Subscriber.java:142)
at app//com.google.common.eventbus.Subscriber.lambda$dispatchEvent$0(Subscriber.java:71)
at app//com.google.common.eventbus.Subscriber$$Lambda$913/0x000000080085cd48.run(Unknown Source)
at app//com.google.common.util.concurrent.DirectExecutor.execute(DirectExecutor.java:31)
at app//com.google.common.eventbus.Subscriber.dispatchEvent(Subscriber.java:68)
at app//com.google.common.eventbus.Dispatcher$PerThreadQueuedDispatcher.dispatch(Dispatcher.java:109)
at app//com.google.common.eventbus.EventBus.post(EventBus.java:267)
at app//io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager.processChannelGrant(DMRTrafficChannelManager.java:473)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoderState.processCSBK(DMRDecoderState.java:1048)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoderState.processData(DMRDecoderState.java:623)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoderState.receive(DMRDecoderState.java:305)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoderState.receive(DMRDecoderState.java:116)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.sample.Broadcaster.receive(Broadcaster.java:52)
at app//io.github.dsheirer.module.decode.Decoder$MessageDistributor.receive(Decoder.java:115)
at app//io.github.dsheirer.module.decode.Decoder$MessageDistributor.receive(Decoder.java:108)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageProcessor.dispatch(DMRMessageProcessor.java:316)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageProcessor.receive(DMRMessageProcessor.java:168)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageProcessor.receive(DMRMessageProcessor.java:62)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageFramer.burstDetected(DMRMessageFramer.java:217)
at app//io.github.dsheirer.module.decode.dmr.DMRBurstFramer.dispatch(DMRBurstFramer.java:243)
at app//io.github.dsheirer.module.decode.dmr.DMRBurstFramer.receive(DMRBurstFramer.java:152)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageFramer.receive(DMRMessageFramer.java:167)
at app//io.github.dsheirer.module.decode.dmr.DMRMessageFramer.receive(DMRMessageFramer.java:60)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.sample.Broadcaster.receive(Broadcaster.java:52)
at app//io.github.dsheirer.dsp.psk.PSKDemodulator.broadcast(PSKDemodulator.java:87)
at app//io.github.dsheirer.dsp.psk.DQPSKDecisionDirectedDemodulator.calculateSymbol(DQPSKDecisionDirectedDemodulator.java:88)
at app//io.github.dsheirer.dsp.psk.PSKDemodulator.receive(PSKDemodulator.java:146)
at app//io.github.dsheirer.dsp.psk.PSKDemodulator.receive(PSKDemodulator.java:121)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoder.receive(DMRDecoder.java:175)
at app//io.github.dsheirer.module.decode.dmr.DMRDecoder.receive(DMRDecoder.java:57)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.sample.Broadcaster.receive(Broadcaster.java:52)
at app//io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelSource.receive(PolyphaseChannelSource.java:145)
at app//io.github.dsheirer.dsp.filter.channelizer.PolyphaseChannelSource.receive(PolyphaseChannelSource.java:40)
at app//io.github.dsheirer.dsp.filter.channelizer.output.OneChannelOutputProcessor.process(OneChannelOutputProcessor.java:113)
at app//io.github.dsheirer.dsp.filter.channelizer.output.ChannelOutputProcessor.lambda$new$0(ChannelOutputProcessor.java:56)
at app//io.github.dsheirer.dsp.filter.channelizer.output.ChannelOutputProcessor$$Lambda$865/0x00000008007dd838.receive(Unknown Source)
at app//io.github.dsheirer.util.Dispatcher.process(Dispatcher.java:184)
at app//io.github.dsheirer.util.Dispatcher$ProcessorWithHeartbeat.run(Dispatcher.java:226)
at [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at [email protected]/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at [email protected]/java.lang.Thread.runWith(Unknown Source)
at [email protected]/java.lang.Thread.run(Unknown Source)
Thread[#8573,sdrtrunk channel [32/DMR] 478700000 thread 1,5,main] WAITING
at [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
at [email protected]/java.util.concurrent.locks.LockSupport.park(Unknown Source)
at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Unknown Source)
at [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(Unknown Source)
at [email protected]/java.util.concurrent.locks.ReentrantLock$Sync.lock(Unknown Source)
at [email protected]/java.util.concurrent.locks.ReentrantLock.lock(Unknown Source)
at app//io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor.receive(DMRTrafficChannelManager.java:820)
at app//io.github.dsheirer.module.decode.dmr.DMRTrafficChannelManager$TrafficChannelTeardownMonitor.receive(DMRTrafficChannelManager.java:731)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.module.ProcessingChain.receive(ProcessingChain.java:1001)
at app//io.github.dsheirer.module.ProcessingChain.receive(ProcessingChain.java:103)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.controller.channel.ChannelProcessingManager.stopProcessing(ChannelProcessingManager.java:643)
at app//io.github.dsheirer.controller.channel.ChannelProcessingManager.receive(ChannelProcessingManager.java:286)
at app//io.github.dsheirer.controller.channel.ChannelProcessingManager.receive(ChannelProcessingManager.java:75)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.sample.Broadcaster.receive(Broadcaster.java:52)
at app//io.github.dsheirer.channel.state.MultiChannelState.broadcast(MultiChannelState.java:455)
at app//io.github.dsheirer.channel.state.MultiChannelState.checkTeardown(MultiChannelState.java:209)
at app//io.github.dsheirer.channel.state.MultiChannelState.stateChanged(MultiChannelState.java:171)
at app//io.github.dsheirer.channel.state.StateMachine.setState(StateMachine.java:189)
at app//io.github.dsheirer.channel.state.StateMachine.checkState(StateMachine.java:107)
at app//io.github.dsheirer.channel.state.MultiChannelState.checkState(MultiChannelState.java:237)
at app//io.github.dsheirer.channel.state.AbstractChannelState$HeartbeatReceiver.receive(AbstractChannelState.java:204)
at app//io.github.dsheirer.channel.state.AbstractChannelState$HeartbeatReceiver.receive(AbstractChannelState.java:199)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.sample.Broadcaster.receive(Broadcaster.java:52)
at app//io.github.dsheirer.sample.Broadcaster.broadcast(Broadcaster.java:128)
at app//io.github.dsheirer.source.heartbeat.HeartbeatManager.broadcast(HeartbeatManager.java:41)
at app//io.github.dsheirer.util.Dispatcher$ProcessorWithHeartbeat.run(Dispatcher.java:230)
at [email protected]/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at [email protected]/java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at [email protected]/java.lang.Thread.runWith(Unknown Source)
at [email protected]/java.lang.Thread.run(Unknown Source)