[
https://issues.apache.org/jira/browse/MUSE-283?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12556221#action_12556221
]
Chris Twiner commented on MUSE-283:
-----------------------------------
Unmodifiable collections only stop changes being made to them, they don't stop
changes to the underlying structure from other pieces of code. Iterating on an
unmodifiable is the same as iterating on the original collection. Iterating
with changes is enough to throw ConcurrentModificationException which happens
regardless of the shutdown state of the subscriptionManager.
Currently the implementation, sensibly I believe, uses synchronized blocks
around the data structure modifcations (with the exception of this bug). This
implies for most stable subscription lists there is only a small cost in making
a "copy" of the subscriptions to publish on, not the entire publish function.
for example if, in the copy version:
Thread 1 Thread 2 Thread 3
addSub removeSub getSubscriptions (and use the results)
these are all ordered operations, one cannot affect the other.
If the copy is not made in getSubscriptions (as with the current svn code) the
follow scenarios will fail *maybe/sometimes/possibly* :
Thread 1 Thread 2 Thread 3
addSub getSubscriptions (and use the
results)
Thread 1 Thread 2 Thread 3
removeSub getSubscriptions (and use the
results)
Thread 1 Thread 2 Thread 3
addSub removeSub getSubscriptions (and use the results)
as the added subscription changes the structure as well.
The only way for these scenarios to be correct and keep a high level of
concurrency and is to make a copy within the getSubscriptions function. This
would hold true of any other function that manipulated the subscriptions
structure outside of synchronized blocks.
As mentioned above this still allows the case when a remove (or expire)
receieves an update after (or during) its removeSubscription call (or expiry).
This is however an acceptable tradeoff in an mt system imo.
As a side note the hasSubscription / resourceRemoved function is also at risk
here (different race condition - not iterator based) from multiple remove
subscription calls (handled by different threads in the resourceRemoved
function). Only way to solve that is to have resourceRemoved synchronized, but
thats straight forward enough.
> SimpleNotificationProducer.getSubscriptions() returns a not-syncronized
> collection
> ----------------------------------------------------------------------------------
>
> Key: MUSE-283
> URL: https://issues.apache.org/jira/browse/MUSE-283
> Project: Muse
> Issue Type: Bug
> Components: WSN NotificationProducer
> Affects Versions: 2.2.0
> Environment: os: unix on solaris
> Reporter: Asaf Zafran
> Assignee: Dan Jemiolo
> Priority: Critical
>
> we have extended the SimpleNotificationProducer.
> in the method
> public void publish(QName topicName, Element[] content, EndpointReference
> consumer) throws SoapFault
> we have called the method:
> Iterator i = getSubsriptions().iterator();
> and the line
> iterator.next();
> has caused a ConcurrentModificationException.
> the stack trace is :
> java.util.ConcurrentModificationException
> at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)
> at java.util.HashMap$ValueIterator.next(HashMap.java:871)
> at
> java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.notification.NotificationProducer.publish(NotificationProducer.java:182)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.notification.NotificationProducer.publish(NotificationProducer.java:253)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.CommandCallback.publish(CommandCallback.java:256)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.CommandCallback.publish(CommandCallback.java:243)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.provservice.WorkflowCallback.gotResult(WorkflowCallback.java:92)
> at
> com.cisco.nm.cmp.nbi.mediator.core.CommandExecutor.setNotifyResult(CommandExecutor.java:270)
> at
> com.cisco.nm.cmp.nbi.mediator.core.MediatorOutputListener.callTranslator(MediatorOutputListener.java:379)
> at
> com.cisco.nm.cmp.nbi.wsdm.server.mediation.provisioning.workflow.run.RunWFResponseListener.notification(RunWFResponseListener.java:86)
> at
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessageObject(Unknown
> Source)
> at
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessageObject(Unknown
> Source)
> at
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessage(Unknown
> Source)
> at
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessage(Unknown
> Source)
> at
> com.cisco.nm.cmp.client.mediator.handlers.ResponseHandlerThread.run(Unknown
> Source)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]