[
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:
muse-dev-unsubscribe@...
For additional commands, e-mail:
muse-dev-help@...