# HG changeset patch # User Vladimir Kvashin # Date 1431589941 -10800 # Node ID cc6cd37ffb6c43c8710c7c8de08473bc07dd2723 # Parent 2bd9b21415348660af62e125ede92a8c87ad16ea fixing #251370 - org.netbeans.modules.deadlock.detector.Detector$DeadlockDetectedException: VersioningAnnotator.annotationRefresh diff -r 2bd9b2141534 -r cc6cd37ffb6c remotefs.versioning/nbproject/project.xml --- a/remotefs.versioning/nbproject/project.xml Wed May 13 20:55:59 2015 +0300 +++ b/remotefs.versioning/nbproject/project.xml Thu May 14 10:52:21 2015 +0300 @@ -80,6 +80,14 @@ + org.openide.util + + + + 9.3 + + + org.openide.util.lookup diff -r 2bd9b2141534 -r cc6cd37ffb6c remotefs.versioning/src/org/netbeans/modules/remotefs/versioning/impl/RemoteFileSystemConnectionManagerImpl.java --- a/remotefs.versioning/src/org/netbeans/modules/remotefs/versioning/impl/RemoteFileSystemConnectionManagerImpl.java Wed May 13 20:55:59 2015 +0300 +++ b/remotefs.versioning/src/org/netbeans/modules/remotefs/versioning/impl/RemoteFileSystemConnectionManagerImpl.java Thu May 14 10:52:21 2015 +0300 @@ -42,8 +42,10 @@ package org.netbeans.modules.remotefs.versioning.impl; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.netbeans.modules.nativeexecution.api.ExecutionEnvironment; import org.netbeans.modules.nativeexecution.api.util.ConnectionListener; @@ -52,6 +54,8 @@ import org.netbeans.modules.remotefs.versioning.api.RemoteFileSystemConnectionListener; import org.netbeans.modules.remotefs.versioning.api.RemoteFileSystemConnectionManager; import org.openide.filesystems.FileSystem; +import org.openide.util.Parameters; +import org.openide.util.RequestProcessor; import org.openide.util.lookup.ServiceProvider; /** @@ -60,8 +64,93 @@ */ @ServiceProvider(service=RemoteFileSystemConnectionManager.class) public class RemoteFileSystemConnectionManagerImpl extends RemoteFileSystemConnectionManager implements ConnectionListener { + private final Set listeners = new HashSet<>(); + + private final RequestProcessor RP = new RequestProcessor("RemoteFileSystemConnectionManager", 10); //NOI18N + private final Map notifiers = new HashMap<>(); + + private enum ConnectionEvent { + CONNECTED, + DISCONNECTED + } + + private class ConnectionNotifier implements Runnable { + + private final ExecutionEnvironment env; + + private ConnectionEvent eventToFire; + private ConnectionEvent lastFiredEvent; + private final Object lock = new Object(); + + + public ConnectionNotifier(ExecutionEnvironment env) { + this.env = env; + } + + public void notify(ConnectionEvent newEvent) { + Parameters.notNull("newEvent", newEvent); //NOI18N + synchronized (lock) { + ConnectionEvent event; + if (eventToFire == null) { + event = newEvent; + } else { + switch (newEvent) { + case CONNECTED: + // eventToFire hasn't yet been fired, so oppopsite events destroy each other + event = (eventToFire == ConnectionEvent.DISCONNECTED) ? null : ConnectionEvent.CONNECTED; + break; + case DISCONNECTED: + // eventToFire hasn't yet been fired, so oppopsite events destroy each other + event = (eventToFire == ConnectionEvent.CONNECTED) ? null : ConnectionEvent.DISCONNECTED; + break; + default: + throw new AssertionError(newEvent.name()); + } + } + // it seems the same event can not come twice; + // but what should we do if it comes? for now we ignore the 2-nd one + if (event != null && event != lastFiredEvent) { + RP.post(this); + } + } + } + + @Override + public void run() { + ConnectionEvent event; + synchronized (lock) { + event = eventToFire; + lastFiredEvent = eventToFire; + eventToFire = null; + } + if (event != null) { + switch (event) { + case CONNECTED: + fireConnected(env); + break; + case DISCONNECTED: + fireDisconnected(env); + break; + default: + throw new AssertionError(event.name()); + } + } + } + } + + private ConnectionNotifier getNotifier(ExecutionEnvironment env) { + synchronized (notifiers) { + ConnectionNotifier notifier = notifiers.get(env); + if (notifier == null) { + notifier = new ConnectionNotifier(env); + notifiers.put(env, notifier); + } + return notifier; + } + } + public RemoteFileSystemConnectionManagerImpl() { ConnectionManager.getInstance().addConnectionListener(this); } @@ -87,6 +176,10 @@ @Override public void connected(ExecutionEnvironment env) { + getNotifier(env).notify(ConnectionEvent.CONNECTED); + } + + private void fireConnected(ExecutionEnvironment env) { final FileSystem fileSystem = FileSystemProvider.getFileSystem(env); if (fileSystem != null) { List list = new ArrayList<>(); @@ -102,6 +195,10 @@ @Override public void disconnected(ExecutionEnvironment env) { + getNotifier(env).notify(ConnectionEvent.DISCONNECTED); + } + + private void fireDisconnected(ExecutionEnvironment env) { final FileSystem fileSystem = FileSystemProvider.getFileSystem(env); if (fileSystem != null) { List list = new ArrayList<>();