1 /*
2  * Created on Sep 28, 2004
3  * Created by Alon Rohter
4  * Copyright (C) Azureus Software, Inc, All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  */
19 
20 package com.aelitis.azureus.core.networkmanager.impl;
21 
22 import java.io.IOException;
23 
24 import org.gudy.azureus2.core3.util.AEDiagnostics;
25 import org.gudy.azureus2.core3.util.Debug;
26 
27 import com.aelitis.azureus.core.networkmanager.*;
28 
29 
30 /**
31  * A fast read entity backed by a single peer connection.
32  */
33 public class SinglePeerDownloader implements RateControlledEntity {
34 
35   private final NetworkConnectionBase connection;
36   private final RateHandler rate_handler;
37 
38 
SinglePeerDownloader( NetworkConnectionBase connection, RateHandler rate_handler )39   public SinglePeerDownloader( NetworkConnectionBase connection, RateHandler rate_handler ) {
40     this.connection = connection;
41     this.rate_handler = rate_handler;
42   }
43 
44 	public RateHandler
getRateHandler()45 	getRateHandler()
46 	{
47 		return( rate_handler );
48 	}
49 
canProcess( EventWaiter waiter )50   public boolean canProcess( EventWaiter waiter ) {
51 
52     if( connection.getTransportBase().isReadyForRead( waiter ) != 0 )  {
53       return false;  //underlying transport not ready
54     }
55 
56     int[] allowed = rate_handler.getCurrentNumBytesAllowed();
57 
58     if ( allowed[0] < 1 ){ // Not yet fully supporting free-protocol for downloading  && allowed[1] == 0 ) {
59 
60       return false;  //not allowed to receive any bytes
61     }
62 
63     return true;
64   }
65 
doProcessing( EventWaiter waiter, int max_bytes )66   public int doProcessing( EventWaiter waiter, int max_bytes ) {
67     if( connection.getTransportBase().isReadyForRead(waiter) != 0 )  {
68       return 0;
69     }
70 
71     int[] allowed = rate_handler.getCurrentNumBytesAllowed();
72 
73     int num_bytes_allowed = allowed[0];
74 
75     boolean protocol_is_free = allowed[1] > 0;
76 
77     if ( num_bytes_allowed < 1 ){
78 
79     	// Not yet fully supporting free-protocol for downloading
80 
81       return 0;
82     }
83 
84 	if ( max_bytes > 0 && max_bytes < num_bytes_allowed ){
85 		num_bytes_allowed = max_bytes;
86 	}
87 
88     //int mss = NetworkManager.getTcpMssSize();
89     //if( num_bytes_allowed > mss )  num_bytes_allowed = mss;
90 
91     int bytes_read = 0;
92 
93     int data_bytes_read		= 0;
94     int protocol_bytes_read	= 0;
95 
96     try {
97       int[] read = connection.getIncomingMessageQueue().receiveFromTransport( num_bytes_allowed, protocol_is_free );
98 
99       data_bytes_read 		= read[0];
100       protocol_bytes_read	= read[1];
101 
102       bytes_read = data_bytes_read + protocol_bytes_read;
103     }
104     catch( Throwable e ) {
105 
106       if( AEDiagnostics.TRACE_CONNECTION_DROPS ) {
107         if( e.getMessage() == null ) {
108           Debug.out( "null read exception message: ", e );
109         }
110         else {
111           if( e.getMessage().indexOf( "end of stream on socket read" ) == -1 &&
112               e.getMessage().indexOf( "An existing connection was forcibly closed by the remote host" ) == -1 &&
113               e.getMessage().indexOf( "Connection reset by peer" ) == -1 &&
114               e.getMessage().indexOf( "An established connection was aborted by the software in your host machine" ) == -1 ) {
115 
116             System.out.println( "SP: read exception [" +connection.getTransportBase().getDescription()+ "]: " +e.getMessage() );
117           }
118         }
119       }
120 
121       if (! (e instanceof IOException )){
122 
123     	  Debug.printStackTrace(e);
124       }
125 
126       connection.notifyOfException( e );
127       return 0;
128     }
129 
130     if( bytes_read < 1 )  {
131       return 0;
132     }
133 
134     rate_handler.bytesProcessed( data_bytes_read, protocol_bytes_read );
135 
136     return bytes_read;
137   }
138 
139 
getPriority()140   public int getPriority() {
141     return RateControlledEntity.PRIORITY_NORMAL;
142   }
143 
getPriorityBoost()144   public boolean getPriorityBoost(){ return false; }
145 
146   public long
getBytesReadyToWrite()147   getBytesReadyToWrite()
148   {
149 	  return( 0 );
150   }
151 
152   public int
getConnectionCount( EventWaiter waiter )153   getConnectionCount( EventWaiter waiter )
154   {
155 	  return( 1 );
156   }
157 
158   public int
getReadyConnectionCount( EventWaiter waiter )159   getReadyConnectionCount(
160 	EventWaiter	waiter )
161   {
162 	  if ( connection.getTransportBase().isReadyForRead( waiter) == 0 ){
163 
164 		  return( 1 );
165 	  }
166 
167 	  return( 0 );
168   }
169 
170   public String
getString()171   getString()
172   {
173 	  return( "SPD: " + connection.getString());
174   }
175 }
176