Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
1.8.0
-
None
-
None
Description
pendingAck is accessed by multiple threads; in most places where it is written, it is done along with accessing deliveredMessages, so it is written within a lock(this.deliveredMessages) block.
However, this call stack shows where pendingAck gets assigned to a new MessageAck object, NOT within the lock... and it is subject to being overwritten by another thread (usually the other thread is in MessageConsumer.Acknowledge() :
Apache.NMS.ActiveMQ.MessageConsumer.AckLater(Apache.NMS.ActiveMQ.Commands.MessageDispatch, Apache.NMS.ActiveMQ.AckType)
Apache.NMS.ActiveMQ.MessageConsumer.AfterMessageIsConsumed(Apache.NMS.ActiveMQ.Commands.MessageDispatch, Boolean)
Apache.NMS.ActiveMQ.MessageConsumer.Dispatch(Apache.NMS.ActiveMQ.Commands.MessageDispatch)
Apache.NMS.ActiveMQ.SessionExecutor.Dispatch(Apache.NMS.ActiveMQ.Commands.MessageDispatch)
Apache.NMS.ActiveMQ.SessionExecutor.Iterate()
Apache.NMS.ActiveMQ.Threads.DedicatedTaskRunner.Run()
The usual symptom I see is a NullReferenceException in this section of code within AckLater; because pendingAck has been set to null by another thread:
if(oldPendingAck == null)
{ pendingAck.FirstMessageId = pendingAck.LastMessageId; }else if(oldPendingAck.AckType == pendingAck.AckType)
{ pendingAck.FirstMessageId = oldPendingAck.FirstMessageId; }