Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

Transfers.cpp

Go to the documentation of this file.
00001 //
00002 // Transfers.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // CTransfers construction
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 // CTransfers list tests
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 // CTransfers thread start and stop
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 // CTransfers registration
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 // CTransfers thread run
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 }

Generated on Thu Dec 15 10:39:50 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2