[ 
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]

Reply via email to