[
http://jira.jboss.com/jira/browse/JBAS-5228?page=all ]
Adrian Brock updated JBAS-5228:
-------------------------------
Description:
There is a race condition when maintaining/checking message acknowledgements
for a subscription when messages are pushed to the client.
i.e. when the client asks for a message and there are none, the client is registered
as wanting a message and when a message arrives, the message is sent to the client.
This involves maintaining a "list" of unacknowledged messages for that
client/subscription
which must be checked before we allow removal of the the subscription during close.
However, for pushing the maintenance of the unacknowledged messages can
race with the close of the subscription because they are not maintained in the same
synchronized block
as deciding the client wants the message.
BasicQueue::internalAddMessage()
try
{
Subscription found = null;
// In this synchronized block we decide that a client wants the message
synchronized (receivers)
{
if (receivers.size() != 0)
{
for (Iterator it = receivers.iterator(); it.hasNext();)
{
Subscription sub = (Subscription) it.next();
if (sub.accepts(message.getHeaders()))
{
it.remove();
found = sub;
break;
}
}
}
...
But only later outside this block do we maintain the unacknowledged messages
// Queue to the receiver
if (found != null)
queueMessageForSending(found, message);
This means that during the ... above a close of the subscription which leads to an
invocation
of hasUnackedMessages() could decide there are no unacknoweldged messages.
was:
There is a race condition when maintaining/checking message acknowledgements
for a subscription when messages are pushed to the client.
i.e. when the client asks for a message and there are none, the client is registered
as wanting a message and when a message arrives, the message is sent to the client.
This involves maintaining a "list" of unacknowledged messages for that
client/subscription
which must be checked before we allow removal of the the subscription during close.
However, for pushing the maintanance of the unacknowledged messages can
race with the close of the subscription because they are not maintained in the same
synchronized block
as deciding the client wants the message.
BasicQueue::internalAddMessage()
try
{
Subscription found = null;
// In this synchronized block we decide that a client wants the message
synchronized (receivers)
{
if (receivers.size() != 0)
{
for (Iterator it = receivers.iterator(); it.hasNext();)
{
Subscription sub = (Subscription) it.next();
if (sub.accepts(message.getHeaders()))
{
it.remove();
found = sub;
break;
}
}
}
...
But only later outside this block do we maintain the unacknowledged messages
// Queue to the receiver
if (found != null)
queueMessageForSending(found, message);
This means that during the ... above a close of the subscription which leads to an
invocation
of hasUnackedMessages() could decide there are no unacknoweldged messages.
Race condition maintaining acknowledgements when pushing messages to
the client
-------------------------------------------------------------------------------
Key: JBAS-5228
URL:
http://jira.jboss.com/jira/browse/JBAS-5228
Project: JBoss Application Server
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: JMS service
Affects Versions: JBossAS-4.2.2.GA
Reporter: Adrian Brock
Assigned To: Adrian Brock
Fix For: JBossAS-4.2.3.GA, JBossAS-5.0.0.CR1
There is a race condition when maintaining/checking message acknowledgements
for a subscription when messages are pushed to the client.
i.e. when the client asks for a message and there are none, the client is registered
as wanting a message and when a message arrives, the message is sent to the client.
This involves maintaining a "list" of unacknowledged messages for that
client/subscription
which must be checked before we allow removal of the the subscription during close.
However, for pushing the maintenance of the unacknowledged messages can
race with the close of the subscription because they are not maintained in the same
synchronized block
as deciding the client wants the message.
BasicQueue::internalAddMessage()
try
{
Subscription found = null;
// In this synchronized block we decide that a client wants the message
synchronized (receivers)
{
if (receivers.size() != 0)
{
for (Iterator it = receivers.iterator(); it.hasNext();)
{
Subscription sub = (Subscription) it.next();
if (sub.accepts(message.getHeaders()))
{
it.remove();
found = sub;
break;
}
}
}
...
But only later outside this block do we maintain the unacknowledged messages
// Queue to the receiver
if (found != null)
queueMessageForSending(found, message);
This means that during the ... above a close of the subscription which leads to an
invocation
of hasUnackedMessages() could decide there are no unacknoweldged messages.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.jboss.com/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira