Skip to content

Commit a6b1f1e

Browse files
committed
GH-616 refine synchronization of DataSource
1 parent d82f875 commit a6b1f1e

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

visualvm/core/src/org/graalvm/visualvm/core/datasource/DataSource.java

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import java.beans.PropertyChangeListener;
3131
import java.beans.PropertyChangeSupport;
3232
import java.lang.ref.WeakReference;
33-
import java.util.Collections;
3433
import java.util.HashSet;
3534
import java.util.Set;
3635
import org.openide.util.RequestProcessor;
@@ -68,6 +67,7 @@ public abstract class DataSource {
6867
private boolean visible = true;
6968
private Storage storage;
7069
private DataSourceContainer repository;
70+
private final Object propertiesLock = new Object();
7171
private PropertyChangeSupport changeSupport;
7272
private Set<ComparableWeakReference<DataRemovedListener>> removedListeners;
7373

@@ -234,7 +234,9 @@ public boolean supportsUserRemove() {
234234
public final void notifyWhenRemoved(DataRemovedListener listener) {
235235
if (listener == null) throw new IllegalArgumentException("Listener cannot be null"); // NOI18N
236236
if (isRemoved()) listener.dataRemoved(this);
237-
else getRemovedListeners().add(new ComparableWeakReference<>(listener));
237+
else synchronized (propertiesLock) {
238+
getRemovedListeners().add(new ComparableWeakReference<>(listener));
239+
}
238240
}
239241

240242
/**
@@ -274,14 +276,18 @@ final void removeImpl() {
274276

275277
this.owner = null;
276278
isRemoved = true;
279+
Set<ComparableWeakReference<DataRemovedListener>> listenersCopy;
277280

278-
if (!hasRemovedListeners()) return;
279-
Set<ComparableWeakReference<DataRemovedListener>> listeners = getRemovedListeners();
280-
for (WeakReference<DataRemovedListener> listenerReference : listeners) {
281+
synchronized (propertiesLock) {
282+
if (!hasRemovedListeners()) return;
283+
Set<ComparableWeakReference<DataRemovedListener>> listeners = getRemovedListeners();
284+
listenersCopy = new HashSet<>(listeners);
285+
listeners.clear();
286+
}
287+
for (WeakReference<DataRemovedListener> listenerReference : listenersCopy) {
281288
DataRemovedListener listener = listenerReference.get();
282289
if (listener != null) listener.dataRemoved(this);
283290
}
284-
listeners.clear();
285291
}
286292

287293

@@ -300,19 +306,23 @@ protected Storage createStorage() {
300306
*
301307
* @return instance of PropertyChangeSupport used for processing property changes.
302308
*/
303-
protected final synchronized PropertyChangeSupport getChangeSupport() {
304-
if (changeSupport == null) changeSupport = new PropertyChangeSupport(this);
305-
return changeSupport;
309+
protected final PropertyChangeSupport getChangeSupport() {
310+
synchronized (propertiesLock) {
311+
if (changeSupport == null) changeSupport = new PropertyChangeSupport(this);
312+
return changeSupport;
313+
}
306314
}
307315

308316

309-
final boolean hasRemovedListeners() {
317+
private boolean hasRemovedListeners() {
310318
return removedListeners != null;
311319
}
312320

313-
final synchronized Set<ComparableWeakReference<DataRemovedListener>> getRemovedListeners() {
314-
if (!hasRemovedListeners()) removedListeners = Collections.synchronizedSet(new HashSet<>());
315-
return removedListeners;
321+
final Set<ComparableWeakReference<DataRemovedListener>> getRemovedListeners() {
322+
synchronized (propertiesLock) {
323+
if (!hasRemovedListeners()) removedListeners = new HashSet<>();
324+
return removedListeners;
325+
}
316326
}
317327

318328
}

0 commit comments

Comments
 (0)