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:
parent
8db8a6662e
commit
6392f63296
4 changed files with 179 additions and 87 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue