Skip to content

Commit

Permalink
Fix for unsynchronized access in DaoNotificationWebSocketHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
terrypacker committed Feb 19, 2016
1 parent f68b917 commit 6ba67cb
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 10 deletions.
3 changes: 2 additions & 1 deletion Core/RELEASE-NOTES
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*Version 2.7.3*
*Version 2.7.4*
* Adding multi-threading to data source initialization
* Change to allow i-frame embedding of Mango hosted pages on Mango Hosted pages
* Change to ensure NONE level events do not make it into the User's Live events list
Expand All @@ -15,6 +15,7 @@
* Added system settings to allow Site Analytics code to be added into the HTML of all pages
* Fixed bug where deleting a user linked to an email event handler would break the event handler
* Adding support for HTML5 Audio to play Alarm sounds on all pages
* Performance enhancements to improve maximum poll rates for data sources

*Version 2.7.2*
* Fixed bug where uploading point values was being reject as a security breach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
*/
package com.serotonin.m2m2.web.mvc.websocket;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
Expand All @@ -23,17 +24,28 @@
public abstract class DaoNotificationWebSocketHandler<T extends AbstractVO<T>> extends MangoWebSocketHandler {
private static final Log LOG = LogFactory.getLog(DaoNotificationWebSocketHandler.class);

final Set<WebSocketSession> sessions = Collections.synchronizedSet(new HashSet<WebSocketSession>());
final Set<WebSocketSession> sessions = new HashSet<WebSocketSession>();
final ReadWriteLock lock = new ReentrantReadWriteLock();

@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
super.afterConnectionEstablished(session);
sessions.add(session);
lock.writeLock().lock();
try{
sessions.add(session);
}finally{
lock.writeLock().unlock();
}
}

@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
sessions.remove(session);
lock.writeLock().lock();
try{
sessions.remove(session);
}finally{
lock.writeLock().unlock();
}
}

/**
Expand All @@ -50,11 +62,16 @@ public void notify(String action, T vo) {
* @param initiatorId random string to identify who initiated the event
*/
public void notify(String action, T vo, String initiatorId) {
for (WebSocketSession session : sessions) {
if (hasPermission(getUser(session), vo)) {
notify(session, action, vo, initiatorId);
}
}
lock.readLock().lock();
try{
for (WebSocketSession session : sessions) {
if (hasPermission(getUser(session), vo)) {
notify(session, action, vo, initiatorId);
}
}
}finally{
lock.readLock().unlock();
}
}

abstract protected boolean hasPermission(User user, T vo);
Expand Down

0 comments on commit 6ba67cb

Please sign in to comment.