/*
* File : PRUDPPacketReceiverFactoryImpl.java
* Created : 20-Jan-2004
* By : parg
*
* Azureus - a Java Bittorrent client
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package com.aelitis.net.udp.uc.impl;
/**
* @author parg
*
*/
import java.net.InetAddress;
import java.util.*;
import org.gudy.azureus2.core3.util.AEMonitor;
import org.gudy.azureus2.core3.util.Debug;
import com.aelitis.net.udp.uc.PRUDPPacketHandler;
import com.aelitis.net.udp.uc.PRUDPReleasablePacketHandler;
import com.aelitis.net.udp.uc.PRUDPRequestHandler;
public class
PRUDPPacketHandlerFactoryImpl
{
private static Map receiver_map = new HashMap();
private static AEMonitor class_mon = new AEMonitor( "PRUDPPHF" );
private static Map releasable_map = new HashMap();
private static Set non_releasable_set = new HashSet();
public static PRUDPPacketHandler
getHandler(
int port,
InetAddress bind_ip,
PRUDPRequestHandler request_handler)
{
final Integer f_port = new Integer( port );
try{
class_mon.enter();
non_releasable_set.add( f_port );
PRUDPPacketHandlerImpl receiver = (PRUDPPacketHandlerImpl)receiver_map.get( f_port );
if ( receiver == null ){
receiver = new PRUDPPacketHandlerImpl( port, bind_ip );
receiver_map.put( f_port, receiver );
}
// only set the incoming request handler if one has been specified. This is important when
// the port is shared (e.g. default udp tracker and dht) and only one usage has need to handle
// unsolicited inbound requests as we don't want the tracker null handler to erase the dht's
// one
if ( request_handler != null ){
receiver.setRequestHandler( request_handler );
}
return( receiver );
}finally{
class_mon.exit();
}
}
public static PRUDPReleasablePacketHandler
getReleasableHandler(
int port,
PRUDPRequestHandler request_handler)
{
final Integer f_port = new Integer( port );
try{
class_mon.enter();
PRUDPPacketHandlerImpl receiver = (PRUDPPacketHandlerImpl)receiver_map.get( f_port );
if ( receiver == null ){
receiver = new PRUDPPacketHandlerImpl( port, null );
receiver_map.put( f_port, receiver );
}
// only set the incoming request handler if one has been specified. This is important when
// the port is shared (e.g. default udp tracker and dht) and only one usage has need to handle
// unsolicited inbound requests as we don't want the tracker null handler to erase the dht's
// one
if ( request_handler != null ){
receiver.setRequestHandler( request_handler );
}
final PRUDPPacketHandlerImpl f_receiver = receiver;
final PRUDPReleasablePacketHandler rel =
new PRUDPReleasablePacketHandler()
{
public PRUDPPacketHandler
getHandler()
{
return( f_receiver );
}
public void
release()
{
try{
class_mon.enter();
List l = (List)releasable_map.get( f_port );
if ( l == null ){
Debug.out( "hmm" );
}else{
if ( !l.remove( this )){
Debug.out( "hmm" );
}else{
if ( l.size() == 0 ){
if ( !non_releasable_set.contains( f_port )){
f_receiver.destroy();
receiver_map.remove( f_port );
}
releasable_map.remove( f_port );
}
}
}
}finally{
class_mon.exit();
}
}
};
List l = (List)releasable_map.get( f_port );
if ( l == null ){
l = new ArrayList();
releasable_map.put( f_port, l );
}
l.add( rel );
if ( l.size() > 1024 ){
Debug.out( "things going wrong here" );
}
return( rel );
}finally{
class_mon.exit();
}
}
}