blob: 407e1765172ede3829ddddd4d6eec8e439039dd1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 IBM, 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
*
* Contributors:
* IBM Corporation - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.provider.filetransfer.httpclient;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.ecf.core.util.Trace;
import org.eclipse.ecf.filetransfer.events.socket.ISocketClosedEvent;
import org.eclipse.ecf.filetransfer.events.socket.ISocketConnectedEvent;
import org.eclipse.ecf.filetransfer.events.socket.ISocketCreatedEvent;
import org.eclipse.ecf.filetransfer.events.socket.ISocketEvent;
import org.eclipse.ecf.filetransfer.events.socket.ISocketListener;
public class ConnectingSocketMonitor implements ISocketListener {
private Map connectingSockets;
public ConnectingSocketMonitor(int initialCapacity) {
connectingSockets = Collections.synchronizedMap(new HashMap(initialCapacity));
}
public ConnectingSocketMonitor() {
connectingSockets = Collections.synchronizedMap(new HashMap());
}
/**
* Callers of this method should not iterate through the returned
* Collection, as a CME is possible...as reported by bug
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=430704
* Rather than call this method and iterate through the Collection,
* to close the connecting sockets call closeConnectingSockets
* instead.
* @return Collection the existing collection of underlying connecting
* Socket instances
*/
public Collection getConnectingSockets() {
return Collections.unmodifiableCollection(connectingSockets.keySet());
}
public void clear() {
connectingSockets.clear();
}
/**
* Method added to synchronize access to underlying keySet
* to prevent CME as reported in bug
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=430704
*/
public void closeSockets() {
// synchronize on the connectingSockets map
// so all changes caused by handleSocketEvent
// are prevented via synchronized Map
synchronized (connectingSockets) {
for (Iterator iterator = connectingSockets.keySet().iterator(); iterator.hasNext();) {
Socket socket = (Socket) iterator.next();
try {
Trace.trace(Activator.PLUGIN_ID, "Call socket.close() for socket=" + socket.toString()); //$NON-NLS-1$
socket.close();
} catch (IOException e) {
Trace.catching(Activator.PLUGIN_ID, DebugOptions.EXCEPTIONS_CATCHING, this.getClass(), "cancel", e); //$NON-NLS-1$
}
}
}
}
public void handleSocketEvent(ISocketEvent event) {
if (event instanceof ISocketCreatedEvent) {
connectingSockets.put(event.getFactorySocket(), event);
} else if (event instanceof ISocketConnectedEvent) {
connectingSockets.remove(event.getFactorySocket());
} else if (event instanceof ISocketClosedEvent) {
connectingSockets.remove(event.getFactorySocket());
}
}
}