1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 23:25:26 +02:00

[218659] Make *EventManager, *ChangeManager thread-safe

This commit is contained in:
Martin Oberhuber 2008-02-12 17:53:07 +00:00
parent 8db8a6662e
commit 6392f63296
4 changed files with 179 additions and 87 deletions

View file

@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2002, 2007 IBM Corporation and others. All rights reserved.
* Copyright (c) 2002, 2008 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -12,10 +12,12 @@
*
* Contributors:
* Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core
* Martin Oberhuber (Wind River) - [218659] Make *EventManager, *ChangeManager thread-safe
********************************************************************************/
package org.eclipse.rse.internal.core.model;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.rse.core.events.ISystemModelChangeEvent;
import org.eclipse.rse.core.events.ISystemModelChangeListener;
@ -26,7 +28,8 @@ import org.eclipse.rse.core.events.ISystemModelChangeListener;
*/
public class SystemModelChangeEventManager
{
private Vector listeners = new Vector();
private List listeners = new ArrayList();
private Object lockObject = new Object();
/**
* Constructor
@ -36,34 +39,48 @@ public class SystemModelChangeEventManager
}
/**
* Add a listener to list of listeners. If this object is already in
* the list, this does nothing.
* Add a listener to list of listeners.
* If this object is already in the list, this does nothing.
* @param l the listener to add
*/
public void addSystemModelChangeListener(ISystemModelChangeListener l)
{
if (!listeners.contains(l))
listeners.addElement(l);
synchronized(lockObject) {
if (!listeners.contains(l))
listeners.add(l);
}
}
/**
* Remove a listener to list of listeners. If this object is not in
* the list, this does nothing.
* Remove a listener from the list of listeners.
* If this object is not in the list, this does nothing.
* @param l the listener to remove
*/
public void removeSystemModelChangeListener(ISystemModelChangeListener l)
{
if (listeners.contains(l))
listeners.removeElement(l);
synchronized(lockObject) {
//Thread-safety: create a new List when removing, to avoid problems in notify()
listeners = new ArrayList(listeners);
listeners.remove(l);
}
}
/**
* Notify all registered listeners of the given event
* Notify all registered listeners of the given event.
* @param event the event to send
*/
public void notify(ISystemModelChangeEvent event)
{
for (int idx=0; idx<listeners.size(); idx++)
{
ISystemModelChangeListener l = (ISystemModelChangeListener)listeners.elementAt(idx);
l.systemModelResourceChanged(event);
//Thread-safe event firing: fire events on a current snapshot of the list.
//If not done that way, and a thread removes a listener while event firing
//is in progress, an ArrayIndexOutOfBoundException might occur.
List currentListeners;
synchronized(lockObject) {
currentListeners = listeners;
}
for (int idx=0; idx<currentListeners.size(); idx++) {
ISystemModelChangeListener l = (ISystemModelChangeListener)currentListeners.get(idx);
l.systemModelResourceChanged(event);
}
}

View file

@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2002, 2007 IBM Corporation and others. All rights reserved.
* Copyright (c) 2002, 2008 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -12,10 +12,12 @@
*
* Contributors:
* Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core
* Martin Oberhuber (Wind River) - [218659] Make *EventManager, *ChangeManager thread-safe
********************************************************************************/
package org.eclipse.rse.internal.core.model;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.rse.core.events.ISystemPreferenceChangeEvent;
import org.eclipse.rse.core.events.ISystemPreferenceChangeListener;
@ -26,7 +28,8 @@ import org.eclipse.rse.core.events.ISystemPreferenceChangeListener;
*/
public class SystemPreferenceChangeManager
{
private Vector listeners = new Vector();
private List listeners = new ArrayList();
private Object lockObject = new Object();
/**
* Constructor
@ -36,33 +39,47 @@ public class SystemPreferenceChangeManager
}
/**
* Add a listener to list of listeners. If this object is already in
* the list, this does nothing.
* Add a listener to list of listeners.
* If this object is already in the list, this does nothing.
* @param l the listener to add
*/
public void addSystemPreferenceChangeListener(ISystemPreferenceChangeListener l)
{
if (!listeners.contains(l))
listeners.addElement(l);
synchronized(lockObject) {
if (!listeners.contains(l))
listeners.add(l);
}
}
/**
* Remove a listener to list of listeners. If this object is not in
* the list, this does nothing.
* Remove a listener from the list of listeners.
* If this object is not in the list, this does nothing.
* @param l the listener to remove
*/
public void removeSystemPreferenceChangeListener(ISystemPreferenceChangeListener l)
{
if (listeners.contains(l))
listeners.removeElement(l);
synchronized(lockObject) {
//Thread-safety: create a new List when removing, to avoid problems in notify()
listeners = new ArrayList(listeners);
listeners.remove(l);
}
}
/**
* Notify all registered listeners of the given event
* Notify all registered listeners of the given event.
* @param event the event to send
*/
public void notify(ISystemPreferenceChangeEvent event)
{
for (int idx=0; idx<listeners.size(); idx++)
{
ISystemPreferenceChangeListener l = (ISystemPreferenceChangeListener)listeners.elementAt(idx);
//Thread-safe event firing: fire events on a current snapshot of the list.
//If not done that way, and a thread removes a listener while event firing
//is in progress, an ArrayIndexOutOfBoundException might occur.
List currentListeners;
synchronized(lockObject) {
currentListeners = listeners;
}
for (int idx=0; idx<currentListeners.size(); idx++) {
ISystemPreferenceChangeListener l = (ISystemPreferenceChangeListener)currentListeners.get(idx);
l.systemPreferenceChanged(event);
}
}

View file

@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2002, 2007 IBM Corporation and others. All rights reserved.
* Copyright (c) 2002, 2008 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -13,11 +13,10 @@
* Contributors:
* Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core
* David McKnight (IBM) - [207100] adding SystemRemoteChangeEventManager.isRegisteredSystemRemoteChangeListener
* Martin Oberhuber (Wind River) - [218659] Make *EventManager, *ChangeManager thread-safe
********************************************************************************/
package org.eclipse.rse.internal.core.model;
import java.util.Vector;
import org.eclipse.rse.core.events.ISystemRemoteChangeEvent;
import org.eclipse.rse.core.events.ISystemRemoteChangeListener;
@ -26,7 +25,8 @@ import org.eclipse.rse.core.events.ISystemRemoteChangeListener;
*/
public class SystemRemoteChangeEventManager
{
private Vector listeners = new Vector();
private ISystemRemoteChangeListener[] listeners = new ISystemRemoteChangeListener[0];
private Object lockObject = new Object();
/**
* Constructor
@ -36,11 +36,20 @@ public class SystemRemoteChangeEventManager
}
/**
* Query if the ISystemRemoteChangeListener is already listening for SystemRemoteChange events
* Query if the given listener is already listening for SystemRemoteChange events.
* @param l the listener to check
* @return <code>true</code> if the listener is already registered
*/
public boolean isRegisteredSystemRemoteChangeListener(ISystemRemoteChangeListener l)
{
return listeners.contains(l);
synchronized(lockObject) {
for(int i=0; i<listeners.length; i++) {
if(listeners[i].equals(l)) {
return true;
}
}
return false;
}
}
/**
@ -50,19 +59,38 @@ public class SystemRemoteChangeEventManager
*/
public void addSystemRemoteChangeListener(ISystemRemoteChangeListener l)
{
if (!listeners.contains(l))
listeners.addElement(l);
if (l==null) throw new IllegalArgumentException();
synchronized(lockObject) {
if (!isRegisteredSystemRemoteChangeListener(l)) {
int len = listeners.length;
ISystemRemoteChangeListener[] oldListeners = listeners;
listeners = new ISystemRemoteChangeListener[len+1];
System.arraycopy(oldListeners, 0, listeners, 0, len);
listeners[len] = l;
}
}
}
/**
* Remove a listener to list of listeners.
* Remove a listener from the list of listeners.
* If this object is not in the list, this does nothing.
* @param l the listener to remove.
* @param l the listener to remove
*/
public void removeSystemRemoteChangeListener(ISystemRemoteChangeListener l)
{
if (listeners.contains(l))
listeners.removeElement(l);
synchronized(lockObject) {
if (isRegisteredSystemRemoteChangeListener(l)) {
//Thread-safety: create a new List when removing, to avoid problems in notify()
int len = listeners.length;
ISystemRemoteChangeListener[] oldListeners = listeners;
listeners = new ISystemRemoteChangeListener[len-1];
for (int i=0, j=0; i<len; i++) {
if (!oldListeners[i].equals(l)) {
listeners[j++] = oldListeners[i];
}
}
}
}
}
/**
@ -72,10 +100,15 @@ public class SystemRemoteChangeEventManager
*/
public void notify(ISystemRemoteChangeEvent event)
{
for (int idx=0; idx<listeners.size(); idx++)
{
ISystemRemoteChangeListener l = (ISystemRemoteChangeListener)listeners.elementAt(idx);
l.systemRemoteResourceChanged(event);
//Thread-safe event firing: fire events on a current snapshot of the list.
//If not done that way, and a thread removes a listener while event firing
//is in progress, an ArrayIndexOutOfBoundException might occur.
ISystemRemoteChangeListener[] currentListeners;
synchronized(lockObject) {
currentListeners = listeners;
}
for (int idx=0; idx<currentListeners.length; idx++) {
currentListeners[idx].systemRemoteResourceChanged(event);
}
}

View file

@ -1,5 +1,5 @@
/********************************************************************************
* Copyright (c) 2002, 2007 IBM Corporation and others. All rights reserved.
* Copyright (c) 2002, 2008 IBM Corporation and others. All rights reserved.
* This program and the accompanying materials are made available under the terms
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
@ -12,10 +12,12 @@
*
* Contributors:
* Martin Oberhuber (Wind River) - [168975] Move RSE Events API to Core
* Martin Oberhuber (Wind River) - [218659] Make *EventManager, *ChangeManager thread-safe
********************************************************************************/
package org.eclipse.rse.ui.internal.model;
import java.util.Vector;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.rse.core.events.ISystemResourceChangeEvent;
import org.eclipse.rse.core.events.ISystemResourceChangeListener;
@ -26,7 +28,8 @@ import org.eclipse.rse.core.events.ISystemResourceChangeListener;
*/
public class SystemResourceChangeManager
{
private Vector listeners = new Vector();
private List listeners = new ArrayList();
private Object lockObject = new Object();
/**
* Constructor
@ -36,53 +39,75 @@ public class SystemResourceChangeManager
}
/**
* Add a listener to list of listeners. If this object is already in
* the list, this does nothing.
*/
public void addSystemResourceChangeListener(ISystemResourceChangeListener l)
{
if (!listeners.contains(l))
listeners.addElement(l);
}
/**
* Remove a listener to list of listeners. If this object is not in
* the list, this does nothing.
*/
public void removeSystemResourceChangeListener(ISystemResourceChangeListener l)
{
if (listeners.contains(l))
listeners.removeElement(l);
}
/**
* Query if the ISystemResourceChangeListener is already listening for SystemResourceChange events
* Query if the given listener is already listening for SystemResourceChange events.
* @param l the listener to check
* @return <code>true</code> if the listener is already registered
*/
public boolean isRegisteredSystemResourceChangeListener(ISystemResourceChangeListener l)
{
return listeners.contains(l);
}
/**
* Notify all registered listeners of the given event
*/
public void notify(ISystemResourceChangeEvent event)
{
for (int idx=0; idx<listeners.size(); idx++)
{
ISystemResourceChangeListener l = (ISystemResourceChangeListener)listeners.elementAt(idx);
l.systemResourceChanged(event);
synchronized(lockObject) {
return listeners.contains(l);
}
}
/**
* Post a notify to all registered listeners of the given event
* Add a listener to list of listeners.
* If this object is already in the list, this does nothing.
* @param l the listener to add
*/
public void addSystemResourceChangeListener(ISystemResourceChangeListener l)
{
synchronized(lockObject) {
if (!listeners.contains(l))
listeners.add(l);
}
}
/**
* Remove a listener from the list of listeners.
* If this object is not in the list, this does nothing.
* @param l the listener to remove
*/
public void removeSystemResourceChangeListener(ISystemResourceChangeListener l)
{
synchronized(lockObject) {
//Thread-safety: create a new List when removing, to avoid problems in notify()
listeners = new ArrayList(listeners);
listeners.remove(l);
}
}
/**
* Notify all registered listeners of the given event.
* @param event the event to send
*/
public void notify(ISystemResourceChangeEvent event)
{
//Thread-safe event firing: fire events on a current snapshot of the list.
//If not done that way, and a thread removes a listener while event firing
//is in progress, an ArrayIndexOutOfBoundException might occur.
List currentListeners;
synchronized(lockObject) {
currentListeners = listeners;
}
for (int idx=0; idx<currentListeners.size(); idx++) {
ISystemResourceChangeListener l = (ISystemResourceChangeListener)currentListeners.get(idx);
l.systemResourceChanged(event);
}
}
/**
* Post a notify to all registered listeners of the given event.
* @param event the event to send
*/
public void postNotify(ISystemResourceChangeEvent event)
{
for (int idx=0; idx<listeners.size(); idx++)
{
ISystemResourceChangeListener listener = (ISystemResourceChangeListener)listeners.elementAt(idx);
List currentListeners;
synchronized(lockObject) {
currentListeners = listeners;
}
for (int idx=0; idx<currentListeners.size(); idx++) {
ISystemResourceChangeListener listener = (ISystemResourceChangeListener)currentListeners.get(idx);
new SystemPostableEventNotifier(listener, event); // create and run the notifier
//l.systemResourceChanged(event);
}