00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "Transfers.h"
00026 #include "Transfer.h"
00027 #include "TransferFile.h"
00028 #include "Downloads.h"
00029 #include "Uploads.h"
00030 #include "EDClients.h"
00031
00032 #ifdef _DEBUG
00033 #undef THIS_FILE
00034 static char THIS_FILE[]=__FILE__;
00035 #define new DEBUG_NEW
00036 #endif
00037
00038 CTransfers Transfers;
00039
00040
00042
00043
00044 CTransfers::CTransfers()
00045 {
00046 m_nBuffer = 256*1024;
00047 m_pBuffer = new BYTE[ m_nBuffer ];
00048 m_hThread = NULL;
00049 m_bThread = FALSE;
00050 m_nRunCookie = 0;
00051 }
00052
00053 CTransfers::~CTransfers()
00054 {
00055 StopThread();
00056 delete [] m_pBuffer;
00057 }
00058
00060
00061
00062 int CTransfers::GetActiveCount() const
00063 {
00064 return Downloads.GetCount( TRUE ) + Uploads.GetTransferCount();
00065 }
00066
00067 BOOL CTransfers::IsConnectedTo(IN_ADDR* pAddress)
00068 {
00069 CSingleLock pLock( &m_pSection );
00070 if ( ! pLock.Lock( 100 ) ) return FALSE;
00071
00072 for ( POSITION pos = GetIterator() ; pos ; )
00073 {
00074 if ( GetNext( pos )->m_pHost.sin_addr.S_un.S_addr == pAddress->S_un.S_addr ) return TRUE;
00075 }
00076
00077 return FALSE;
00078 }
00079
00081
00082
00083 BOOL CTransfers::StartThread()
00084 {
00085 if ( m_hThread != NULL && m_bThread ) return TRUE;
00086 if ( GetCount() == 0 && Downloads.GetCount() == 0 ) return FALSE;
00087
00088 m_hThread = NULL;
00089 m_bThread = TRUE;
00090
00091 CWinThread* pThread = AfxBeginThread( ThreadStart, this, THREAD_PRIORITY_NORMAL );
00092 m_hThread = pThread->m_hThread;
00093
00094 return TRUE;
00095 }
00096
00097 void CTransfers::StopThread()
00098 {
00099 if ( m_hThread == NULL ) return;
00100
00101 m_bThread = FALSE;
00102 m_pWakeup.SetEvent();
00103
00104 int nAttempt = 40;
00105 for ( ; nAttempt > 0 ; nAttempt-- )
00106 {
00107 DWORD nCode;
00108 if ( ! GetExitCodeThread( m_hThread, &nCode ) ) break;
00109 if ( nCode != STILL_ACTIVE ) break;
00110 Sleep( 100 );
00111 }
00112
00113 if ( nAttempt == 0 )
00114 {
00115 TerminateThread( m_hThread, 0 );
00116 theApp.Message( MSG_DEBUG, _T("WARNING: Terminating CTransfers thread.") );
00117 Sleep( 100 );
00118 }
00119
00120 m_hThread = NULL;
00121
00122 Downloads.m_nTransfers = 0;
00123 Downloads.m_nBandwidth = 0;
00124 Uploads.m_nCount = 0;
00125 Uploads.m_nBandwidth = 0;
00126 }
00127
00129
00130
00131 void CTransfers::Add(CTransfer* pTransfer)
00132 {
00133 ASSERT( pTransfer->m_hSocket != INVALID_SOCKET );
00134 WSAEventSelect( pTransfer->m_hSocket, m_pWakeup, FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE );
00135
00136 POSITION pos = m_pList.Find( pTransfer );
00137 ASSERT( pos == NULL );
00138 if ( pos == NULL ) m_pList.AddHead( pTransfer );
00139
00140 if ( Settings.General.Debug && Settings.General.DebugLog ) theApp.Message( MSG_DEBUG, _T("CTransfers::Add(): %x"), pTransfer );
00141
00142 StartThread();
00143 }
00144
00145 void CTransfers::Remove(CTransfer* pTransfer)
00146 {
00147 if ( Settings.General.Debug && Settings.General.DebugLog ) theApp.Message( MSG_DEBUG, _T("CTransfers::Remove(): %x"), pTransfer );
00148
00149 if ( pTransfer->m_hSocket != INVALID_SOCKET )
00150 WSAEventSelect( pTransfer->m_hSocket, m_pWakeup, 0 );
00151
00152 CTransfers::Lock oLock;
00153 if ( POSITION pos = m_pList.Find( pTransfer ) )
00154 m_pList.RemoveAt( pos );
00155 }
00156
00158
00159
00160 UINT CTransfers::ThreadStart(LPVOID pParam)
00161 {
00162 CTransfers* pTransfers = (CTransfers*)pParam;
00163 pTransfers->OnRun();
00164 return 0;
00165 }
00166
00167 void CTransfers::OnRun()
00168 {
00169 while ( m_bThread )
00170 {
00171 Sleep( Settings.General.MinTransfersRest );
00172 WaitForSingleObject( m_pWakeup, 50 );
00173
00174 CTransfers::Lock(), EDClients.OnRun();
00175 if ( ! m_bThread ) break;
00176
00177 OnRunTransfers();
00178 if ( ! m_bThread ) break;
00179 Downloads.OnRun();
00180 if ( ! m_bThread ) break;
00181
00182 CTransfers::Lock(), Uploads.OnRun(), OnCheckExit();
00183
00184 TransferFiles.CommitDeferred();
00185 }
00186
00187 Downloads.m_nTransfers = Downloads.m_nBandwidth = 0;
00188 Uploads.m_nCount = Uploads.m_nBandwidth = 0;
00189 }
00190
00191 void CTransfers::OnRunTransfers()
00192 {
00193 CTransfers::Lock oLock;
00194 ++m_nRunCookie;
00195
00196 while ( !m_pList.IsEmpty()
00197 && static_cast< CTransfer* >( m_pList.GetHead() )->m_nRunCookie != m_nRunCookie )
00198 {
00199 CTransfer* pTransfer = static_cast< CTransfer* >( m_pList.RemoveHead() );
00200 m_pList.AddTail( pTransfer );
00201 pTransfer->m_nRunCookie = m_nRunCookie;
00202 pTransfer->DoRun();
00203 }
00204 }
00205
00206 void CTransfers::OnCheckExit()
00207 {
00208 if ( GetCount() == 0 && Downloads.GetCount() == 0 ) m_bThread = FALSE;
00209
00210 if ( Settings.Live.AutoClose && GetActiveCount() == 0 )
00211 {
00212 CSingleLock pLock( &theApp.m_pSection );
00213
00214 if ( pLock.Lock( 250 ) )
00215 {
00216 if ( CWnd* pWnd = (CWnd*)theApp.SafeMainWnd() )
00217 {
00218 Settings.Live.AutoClose = FALSE;
00219 pWnd->PostMessage( WM_CLOSE );
00220 }
00221 }
00222 }
00223 }