All pastes #1787465 Raw Edit

Stuff

public text v1 · immutable
#1787465 ·published 2010-02-05 21:47 UTC
rendered paste body
Index: DownloadWithSearch.cpp
===================================================================
--- DownloadWithSearch.cpp	(revision 8453)
+++ DownloadWithSearch.cpp	(working copy)
@@ -38,7 +38,7 @@
 // CDownloadWithSearch construction
 
 CDownloadWithSearch::CDownloadWithSearch()
-	: m_bUpdateSearch	( TRUE )
+	: m_bUpdateSearch	( true )
 	, m_tSearchTime		( 0 )
 	, m_tSearchCheck	( 0 )
 	, m_tLastED2KGlobal	( 0 )
@@ -53,12 +53,12 @@
 //////////////////////////////////////////////////////////////////////
 // CDownloadWithSearch Can Find Sources
 
-BOOL CDownloadWithSearch::FindSourcesAllowed(DWORD tNow) const
+bool CDownloadWithSearch::FindSourcesAllowed(DWORD tNow) const
 {
 	if ( tNow > m_tSearchTime && tNow - m_tSearchTime > 15*1000 )
-		return TRUE;
+		return true;
 	else
-		return FALSE;
+		return false;
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -74,7 +74,7 @@
 		if ( tNow - m_tSearchTime > ( Settings.Downloads.SearchPeriod / 4 ) )
 		{
 			m_tSearchTime = tNow;
-			if ( IsSearching() ) m_pSearch->Stop();
+			StopSearch();
 			bSuccess = TRUE;
 		}
 	}
@@ -120,22 +120,25 @@
 
 void CDownloadWithSearch::StartManualSearch()
 {
+	CSingleLock oSearchLock( &SearchManager.GetLock() );
+	if ( !oSearchLock.Lock( 100 ) )
+		return;
+
 	PrepareSearch();
 
 	m_pSearch->SetPriority( CManagedSearch::spHighest );
 	m_pSearch->Start();
 }
 
-BOOL CDownloadWithSearch::IsSearching() const
-{
-	return m_pSearch && m_pSearch->IsActive();
-}
-
 //////////////////////////////////////////////////////////////////////
 // CDownloadWithSearch start (or continue) an automatic search
 
 void CDownloadWithSearch::StartAutomaticSearch()
 {
+	CSingleLock oSearchLock( &SearchManager.GetLock() );
+	if ( !oSearchLock.Lock( 100 ) )
+		return;
+
 	PrepareSearch();
 
 	m_pSearch->SetPriority( CManagedSearch::spLowest );
@@ -145,18 +148,18 @@
 //////////////////////////////////////////////////////////////////////
 // CDownloadWithSearch check if we can actually search
 
-BOOL CDownloadWithSearch::CanSearch() const
+bool CDownloadWithSearch::CanSearch() const
 {
 	if ( IsMoving() || IsCompleted() )
-		return FALSE;
+		return false;
 	if ( ( m_oSHA1 || m_oTiger ) && ( Settings.Gnutella1.EnableToday || Settings.Gnutella2.EnableToday ) )
-		return TRUE;
+		return true;
 	if ( m_oED2K && ( Settings.Gnutella2.EnableToday || Settings.eDonkey.EnableToday ) )
-		return TRUE;
+		return true;
 	if ( ( m_oBTH || m_oMD5 ) && Settings.Gnutella2.EnableToday )
-		return TRUE;
+		return true;
 
-	return FALSE;
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -169,8 +172,9 @@
 	else if ( ! m_bUpdateSearch )
 		// Search not changed
 		return;
-	m_bUpdateSearch = FALSE;
 
+	m_bUpdateSearch = false;
+
 	CQuerySearchPtr pSearch = m_pSearch->GetSearch();
 
 	pSearch->m_bAndG1 = Settings.Gnutella1.EnableToday;
@@ -236,9 +240,18 @@
 
 void CDownloadWithSearch::StopSearch()
 {
+	CQuickLock oSearchLock( SearchManager.GetLock() );
+
 	if ( IsSearching() )
 	{
 		m_pSearch->Stop();
-		m_bUpdateSearch = TRUE;
+		m_bUpdateSearch = true;
 	}
 }
+
+bool CDownloadWithSearch::IsSearching() const
+{
+	CQuickLock oSearchLock( SearchManager.GetLock() );
+
+	return m_pSearch && m_pSearch->IsActive();
+}
Index: DownloadWithSearch.h
===================================================================
--- DownloadWithSearch.h	(revision 8453)
+++ DownloadWithSearch.h	(working copy)
@@ -29,29 +29,35 @@
 
 class CDownloadWithSearch : public CDownloadWithTiger
 {
-public:
-	BOOL			m_bUpdateSearch;	// Search must be updated
-	DWORD			m_tLastED2KGlobal;	// Time the last ed2k UDP GetSources was done on this download
-	DWORD			m_tLastED2KLocal;	// Time the last ed2k TCP GetSources was done on this download
-
-	virtual BOOL	FindMoreSources();
-	BOOL			IsSearching() const;
-
+// Construction
 protected:
 	CDownloadWithSearch();
 	virtual ~CDownloadWithSearch();
 
-	BOOL			FindSourcesAllowed(DWORD tNow) const;
-	void			RunSearch(DWORD tNow);
-	void			StopSearch();
-
+// Attributes
+public:
+	bool			m_bUpdateSearch;	// Search must be updated
+	DWORD			m_tLastED2KGlobal;	// Time the last ed2k UDP GetSources was done on this download
+	DWORD			m_tLastED2KLocal;	// Time the last ed2k TCP GetSources was done on this download
 private:
 	CSearchPtr		m_pSearch;			// Managed search object
 	DWORD			m_tSearchTime;		// Timer for manual search
 	DWORD			m_tSearchCheck;		// Limit auto searches
 
-	void			StartManualSearch();
-	void			StartAutomaticSearch();
-	BOOL			CanSearch() const;
-	void			PrepareSearch();
+// Operations
+public:
+	bool	IsSearching() const;
+protected:
+	bool	FindSourcesAllowed(DWORD tNow) const;
+	void	RunSearch(DWORD tNow);
+	void	StopSearch();
+private:
+	void	StartManualSearch();
+	void	StartAutomaticSearch();
+	bool	CanSearch() const;
+	void	PrepareSearch();
+
+// Overrides
+public:
+	virtual BOOL	FindMoreSources();
 };
Index: DownloadWithSources.cpp
===================================================================
--- DownloadWithSources.cpp	(revision 8453)
+++ DownloadWithSources.cpp	(working copy)
@@ -337,7 +337,7 @@
 	}
 
 	if ( bUpdated )
-		((CDownload*)this)->m_bUpdateSearch = TRUE;
+		((CDownload*)this)->m_bUpdateSearch = true;
 
 	/*
 	if ( pHit->m_nProtocol == PROTOCOL_ED2K )
Index: ManagedSearch.cpp
===================================================================
--- ManagedSearch.cpp	(revision 8453)
+++ ManagedSearch.cpp	(working copy)
@@ -75,15 +75,46 @@
 
 CManagedSearch::~CManagedSearch()
 {
+	CQuickLock oSearchLock( SearchManager.GetLock() );
 	Stop();
 }
 
+CQuerySearchPtr CManagedSearch::GetSearch() const
+{
+	return m_pSearch;
+}
+
+bool CManagedSearch::IsEqualGUID(const Hashes::Guid& oGUID) const
+{
+	return m_pSearch && validAndEqual( m_pSearch->m_oGUID, oGUID );
+}
+
+CSchemaPtr CManagedSearch::GetSchema() const
+{
+	return m_pSearch ? m_pSearch->m_pSchema : NULL;
+}
+
+bool CManagedSearch::IsActive() const
+{
+	return ( m_bActive != FALSE );
+}
+
+void CManagedSearch::SetActive(BOOL bActive)
+{
+	InterlockedExchange( (LONG*)&m_bActive, bActive );
+}
+
+void CManagedSearch::SetPriority(int nPriority)
+{
+	InterlockedExchange( (LONG*)&m_nPriority, nPriority );
+}
+
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch serialize
 
 void CManagedSearch::Serialize(CArchive& ar)
 {
-	CQuickLock oLock( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	int nVersion = 3;
 
@@ -127,13 +158,13 @@
 
 void CManagedSearch::Start()
 {
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
+
 	if ( InterlockedCompareExchange( (LONG*)&m_bActive, TRUE, FALSE ) )
 		return;
 
-	if ( ! InterlockedCompareExchange( (LONG*)&m_bStarted, TRUE, FALSE ) )
+	if ( !InterlockedCompareExchange( (LONG*)&m_bStarted, TRUE, FALSE ) )
 	{
-		CQuickLock oLock( SearchManager.m_pSection );
-
 		m_tStarted		= static_cast< DWORD >( time( NULL ) );
 		m_tExecute		= 0;
 		m_tLastED2K		= 0;
@@ -148,10 +179,10 @@
 
 void CManagedSearch::Stop()
 {
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
+
 	if ( InterlockedCompareExchange( (LONG*)&m_bStarted, FALSE, TRUE ) )
 	{
-		CQuickLock oLock( SearchManager.m_pSection );
-
 		SearchManager.Remove( this );
 	}
 
@@ -168,12 +199,12 @@
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch execute
 
-BOOL CManagedSearch::Execute(int nPriorityClass)
+bool CManagedSearch::Execute(int nPriorityClass)
 {
-	ASSUME_LOCK( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	if ( m_nPriority != nPriorityClass || ! m_bActive || ! m_pSearch )
-		return FALSE;
+		return false;
 
 	// Throttle this individual search (so it doesn't take up too many resources)
 	DWORD nThrottle = Settings.Search.GeneralThrottle;
@@ -186,11 +217,12 @@
 	const DWORD tSecs = static_cast< DWORD >( time( NULL ) );
 
 	if ( tTicks - m_tExecute < nThrottle )
-		return FALSE;
+		return false;
+
 	m_tExecute = tTicks;
 
 	// Search local neighbours: hubs, servers and ultrapeers. (TCP)
-	BOOL bSuccess = ExecuteNeighbours( tTicks, tSecs );
+	bool bSuccess = ExecuteNeighbours( tTicks, tSecs );
 
 	// G2 global search. (UDP)
 	if ( Settings.Gnutella2.EnableToday && m_bAllowG2 )
@@ -211,7 +243,8 @@
 		m_tLastED2K = tTicks;
 	}
 
-	if ( bSuccess ) m_nQueryCount++;
+	if ( bSuccess )
+		++m_nQueryCount;
 
 	return bSuccess;
 }
@@ -219,9 +252,9 @@
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch execute the search on G1 / G2 / ED2K neighbours
 
-BOOL CManagedSearch::ExecuteNeighbours(const DWORD tTicks, const DWORD tSecs)
+bool CManagedSearch::ExecuteNeighbours(const DWORD tTicks, const DWORD tSecs)
 {
-	ASSUME_LOCK( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	int nCount = 0;
 	for ( POSITION pos = Neighbours.GetIterator() ; pos ; )
@@ -229,19 +262,23 @@
 		CNeighbour* pNeighbour = Neighbours.GetNext( pos );
 
 		// Must be connected
-		if ( pNeighbour->m_nState != nrsConnected ) continue;
+		if ( pNeighbour->m_nState != nrsConnected )
+			continue;
 
 		// Check network flags
 		switch ( pNeighbour->m_nProtocol )
 		{
 		case PROTOCOL_G1:
-			if ( ! m_bAllowG1 ) continue;
+			if ( !m_bAllowG1 )
+				continue;
 			break;
 		case PROTOCOL_G2:
-			if ( ! m_bAllowG2 ) continue;
+			if ( !m_bAllowG2 )
+				continue;
 			break;
 		case PROTOCOL_ED2K:
-			if ( ! m_bAllowED2K ) continue;
+			if ( !m_bAllowED2K )
+				continue;
 			break;
 		default:
 			continue;
@@ -293,7 +330,7 @@
 						m_tMoreResults = tTicks;
 						// Display message in system window
 						theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-							_T("Asking ed2k neighbour for additional search results") );
+							_T("[ED2k] Asking neighbour for additional search results") );
 					}
 				}
 
@@ -373,9 +410,7 @@
 
 					// Set the "last ED2K search" value if we sent a text search (to find the search later).
 					if ( ! m_pSearch->m_oED2K )
-					{
-						SearchManager.m_oLastED2KSearch = m_pSearch->m_oGUID;
-					}
+						SearchManager.SetLastED2KSearch( m_pSearch->m_oGUID );
 				}
 			}
 			pPacket->Release();
@@ -390,21 +425,24 @@
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch execute the search on the G2 mesh
 
-BOOL CManagedSearch::ExecuteG2Mesh(const DWORD /*tTicks*/, const DWORD tSecs)
+bool CManagedSearch::ExecuteG2Mesh(const DWORD /*tTicks*/, const DWORD tSecs)
 {
-	ASSUME_LOCK( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	// Look at all known Gnutella2 hubs, newest first
 
 	CQuickLock oLock( HostCache.Gnutella2.m_pSection );
 
-	for ( CHostCacheIterator i = HostCache.Gnutella2.Begin() ;
-		i != HostCache.Gnutella2.End();	++i )
+	CHostCacheIterator pItr = HostCache.Gnutella2.Begin();
+	const CHostCacheIterator pEnd = HostCache.Gnutella2.End();
+	for ( ; pItr != pEnd; ++pItr )
 	{
-		CHostCacheHost* pHost = (*i);
+		CHostCacheHost* pHost = (*pItr);
 		// Must be Gnutella2
 
 		ASSERT( pHost->m_nProtocol == PROTOCOL_G2 );
+		if ( pHost->m_nProtocol != PROTOCOL_G2 )
+			continue;
 
 		// If this host is a neighbour, don't UDP to it
 		if ( Neighbours.Get( &pHost->m_pAddress ) )
@@ -437,7 +475,8 @@
 			// Make sure we have a query key via one of our neighbours,
 			// and ensure we have queried this neighbour
 
-			if ( CNeighbour* pNeighbour = Neighbours.Get( (IN_ADDR*)&pHost->m_nKeyHost ) )
+			CNeighbour* pNeighbour = Neighbours.Get( (IN_ADDR*)&pHost->m_nKeyHost );
+			if ( pNeighbour )
 			{
 				DWORD nTemp;
 				if ( m_pNodes.Lookup( pHost->m_nKeyHost, nTemp ) )
@@ -452,14 +491,12 @@
 		}
 
 		// Now, if we still have a query key, send the query
-
 		if ( pHost->m_nKeyValue != 0 )
 		{
 			DWORD tLastQuery;
 			ASSERT( pReceiver != NULL );
 
 			// Lookup the host
-
 			if ( m_pNodes.Lookup( pHost->m_pAddress.s_addr, tLastQuery ) )
 			{
 				// Check per-hub re-query time
@@ -475,32 +512,33 @@
 				}
 				else
 					nFrequency = Settings.Gnutella2.RequeryDelay * ( m_nPriority + 1 );
+
 				if ( tSecs - tLastQuery < nFrequency )
 					continue;
 			}
 
 			// Set the last query time for this host for this search
-
 			m_pNodes.SetAt( pHost->m_pAddress.s_addr, tSecs );
 
 			// Record the query time on the host, for all searches
-
 			pHost->m_tQuery = tSecs;
 			if ( pHost->m_tAck == 0 )
 				pHost->m_tAck = tSecs;
 
 			// Try to create a packet
-
 			m_pSearch->m_bAndG1 = ( Settings.Gnutella1.EnableToday && m_bAllowG1 );
+			CPacket* pPacket = m_pSearch->ToG2Packet( pReceiver, pHost->m_nKeyValue );
 
-			if ( CPacket* pPacket = m_pSearch->ToG2Packet( pReceiver, pHost->m_nKeyValue ) )
+			// Send the packet if it was created
+			if ( pPacket )
 			{
 				if ( Datagrams.Send( &pHost->m_pAddress, pHost->m_nPort, pPacket, TRUE, this, TRUE ) )
 				{
 					theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-						_T("Querying %s"),
+						_T("[G2] Querying %s"),
 						(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
-					return TRUE;
+
+					return true;
 				}
 			}
 		}
@@ -508,7 +546,6 @@
 		{
 			// Timing wise, we can request a query key now -- but first we must figure
 			// out who should be the receiver
-
 			CNeighbour* pCacheHub = NULL;
 			pReceiver = NULL;
 
@@ -545,10 +582,11 @@
 			{
 				// The receiver is a cache-capable hub, so we ask it to return
 				// a cached key, or fetch a fresh one
-				if ( CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_KEY_REQ, TRUE ) )
+				CG2Packet* pPacket = CG2Packet::New( G2_PACKET_QUERY_KEY_REQ, TRUE );
+				if ( pPacket )
 				{
 					pPacket->WritePacket( G2_PACKET_QUERY_ADDRESS, 6 );
-					pPacket->WriteLongLE( pHost->m_pAddress.S_un.S_addr );
+					pPacket->WriteLongLE( pHost->m_pAddress.s_addr );
 					pPacket->WriteShortBE( pHost->m_nPort );
 
 					if ( pCacheHub->Send( pPacket ) )
@@ -559,10 +597,11 @@
 						pHost->m_nKeyValue = 0;
 
 						theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-							_T("Requesting query key from %s through %s"),
+							_T("[G2] Requesting query key from %s through %s"),
 							(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ),
 							(LPCTSTR)CString( inet_ntoa( pReceiver->sin_addr ) ) );
-						return TRUE;
+
+						return true;
 					}
 				}
 			}
@@ -589,40 +628,45 @@
 						if ( pReceiver == &Network.m_pHost )
 						{
 							theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-								_T("Requesting query key from %s"),
+								_T("[G2] Requesting query key from %s"),
 								(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
 						}
 						else
 						{
 							theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-								_T("Requesting query key from %s for %s"),
+								_T("[G2] Requesting query key from %s for %s"),
 								(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ),
 								(LPCTSTR)CString( inet_ntoa( pReceiver->sin_addr ) ) );
 						}
-						return TRUE;
+
+						return true;
 					}
 				}
 			}
 		}
 	}
 
-	return FALSE;
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch execute the search on eDonkey2000 servers
 
-BOOL CManagedSearch::ExecuteDonkeyMesh(const DWORD /*tTicks*/, const DWORD tSecs)
+bool CManagedSearch::ExecuteDonkeyMesh(const DWORD /*tTicks*/, const DWORD tSecs)
 {
-	ASSUME_LOCK( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	CQuickLock oLock( HostCache.eDonkey.m_pSection );
 
-	for ( CHostCacheIterator i = HostCache.eDonkey.Begin() ; i != HostCache.eDonkey.End();	++i )
+	CHostCacheIterator pItr = HostCache.eDonkey.Begin();
+	CHostCacheIterator pEnd = HostCache.eDonkey.End();
+	for ( ; pItr != pEnd ; ++pItr )
 	{
-		CHostCacheHost* pHost = (*i);
+		CHostCacheHost* pHost = (*pItr);
 
 		ASSERT( pHost->m_nProtocol == PROTOCOL_ED2K );
+		if ( pHost->m_nProtocol != PROTOCOL_ED2K )
+			continue;
 
 		// If this host is a neighbour, don't UDP to it
 		if ( Neighbours.Get( &pHost->m_pAddress ) )
@@ -646,9 +690,11 @@
 			pHost->m_tAck = tSecs;
 
 		// Create a packet in the appropriate format
-		if ( CPacket* pPacket = m_pSearch->ToEDPacket( TRUE, pHost->m_nUDPFlags ) )
+			CPacket* pPacket = m_pSearch->ToEDPacket( TRUE, pHost->m_nUDPFlags );
+
+		// Send the datagram if possible
+		if( pPacket )
 		{
-			// Send the datagram if possible
 			if ( Datagrams.Send( &pHost->m_pAddress, pHost->m_nPort + 4, pPacket, TRUE ) )
 			{
 				// Add to ED2K search counts
@@ -656,14 +702,15 @@
 				m_nEDClients += pHost->m_nUserCount;
 
 				theApp.Message( MSG_DEBUG | MSG_FACILITY_SEARCH,
-					_T("Sending UDP query to %s"),
+					_T("[ED2K] Sending UDP query to %s"),
 					(LPCTSTR)CString( inet_ntoa( pHost->m_pAddress ) ) );
-				return TRUE;
+
+				return true;
 			}
 		}
 	}
 
-	return FALSE;
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -671,7 +718,7 @@
 
 void CManagedSearch::OnHostAcknowledge(DWORD nAddress)
 {
-	ASSUME_LOCK( SearchManager.m_pSection );
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
 
 	m_pNodes.SetAt( nAddress, static_cast< DWORD >( time( NULL ) ) );
 }
@@ -679,7 +726,7 @@
 //////////////////////////////////////////////////////////////////////
 // CManagedSearch check if we were the most recent ed2k text search. (Not find more sources)
 
-BOOL CManagedSearch::IsLastED2KSearch()
+bool CManagedSearch::IsLastED2KSearch()
 {
-	return IsEqualGUID( SearchManager.m_oLastED2KSearch );
+	return IsEqualGUID( SearchManager.GetLastED2KSearch() );
 }
Index: ManagedSearch.h
===================================================================
--- ManagedSearch.h	(revision 8453)
+++ ManagedSearch.h	(working copy)
@@ -34,51 +34,17 @@
 class CManagedSearch : public CComObject
 {
 public:
-	CManagedSearch(CQuerySearch* pSearch = NULL, int nPriority = 0);
-	virtual ~CManagedSearch();
-
 	typedef CMap< DWORD, DWORD, DWORD, DWORD > CDwordDwordMap;
-	
+
 	enum { spHighest, spMedium, spLowest, spMax };
 
-	inline CQuerySearchPtr GetSearch() const
-	{
-		return m_pSearch;
-	}
+// Construction
+public:
+	CManagedSearch(CQuerySearch* pSearch = NULL, int nPriority = 0);
+	virtual ~CManagedSearch();
 
-	inline bool IsEqualGUID(const Hashes::Guid& oGUID) const
-	{
-		return m_pSearch && validAndEqual( m_pSearch->m_oGUID, oGUID );
-	}
-
-	inline CSchemaPtr GetSchema() const
-	{
-		return m_pSearch ? m_pSearch->m_pSchema : NULL;
-	}
-
-	inline bool IsActive() const
-	{
-		return ( m_bActive != FALSE );
-	}
-
-	inline void SetActive(BOOL bActive)
-	{
-		InterlockedExchange( (LONG*)&m_bActive, bActive );
-	}
-
-	inline void SetPriority(int nPriority)
-	{
-		InterlockedExchange( (LONG*)&m_nPriority, nPriority );
-	}
-
-	void	Serialize(CArchive& ar);
-	void	Start();
-	void	Stop();
-	BOOL	Execute(int nPriorityClass);		// Run search of specified priority class
-	void	OnHostAcknowledge(DWORD nAddress);
-	BOOL	IsLastED2KSearch();
-	void	CreateGUID();
-
+// Attributes
+public:
 	BOOL			m_bAllowG2;
 	BOOL			m_bAllowG1;
 	BOOL			m_bAllowED2K;
@@ -93,8 +59,7 @@
 	DWORD			m_nQueryCount;				// Total Gnutella2 queries sent
 	DWORD			m_tLastED2K;				// Time an ed2k server was last searched
 	DWORD			m_tMoreResults;				// Time more results were requested from an ed2k server
-
-protected:
+private:
 	int				m_nPriority;
 	BOOL			m_bStarted;					// Search started (and managed by SearchManager)
 	BOOL			m_bActive;
@@ -106,7 +71,23 @@
 	CDwordDwordMap	m_pG1Nodes;					// Pair of IP and last sent packet TTL
 	DWORD			m_tExecute;					// Search execute time (ticks)
 
-	BOOL	ExecuteNeighbours(const DWORD tTicks, const DWORD tSecs);
-	BOOL	ExecuteG2Mesh(const DWORD tTicks, const DWORD tSecs);
-	BOOL	ExecuteDonkeyMesh(const DWORD tTicks, const DWORD tSecs);
+// Operations
+public:
+	CQuerySearchPtr	GetSearch() const;
+	bool			IsEqualGUID(const Hashes::Guid& oGUID) const;
+	CSchemaPtr		GetSchema() const;
+	bool			IsActive() const;
+	void			SetActive(BOOL bActive);
+	void			SetPriority(int nPriority);
+	void			Serialize(CArchive& ar);
+	void			Start();
+	void			Stop();
+	bool			Execute(int nPriorityClass);		// Run search of specified priority class
+	void			OnHostAcknowledge(DWORD nAddress);
+	bool			IsLastED2KSearch();
+	void			CreateGUID();
+private:
+	bool			ExecuteNeighbours(const DWORD tTicks, const DWORD tSecs);
+	bool			ExecuteG2Mesh(const DWORD tTicks, const DWORD tSecs);
+	bool			ExecuteDonkeyMesh(const DWORD tTicks, const DWORD tSecs);
 };
Index: SearchManager.cpp
===================================================================
--- SearchManager.cpp	(revision 8453)
+++ SearchManager.cpp	(working copy)
@@ -1,7 +1,7 @@
 //
 // SearchManager.cpp
 //
-// Copyright (c) Shareaza Development Team, 2002-2009.
+// Copyright (c) Shareaza Development Team, 2002-2010.
 // This file is part of SHAREAZA (shareaza.sourceforge.net)
 //
 // Shareaza is free software; you can redistribute it
@@ -51,30 +51,48 @@
 
 CSearchManager::~CSearchManager()
 {
-	ASSERT( m_pList.IsEmpty() );
+	ASSERT( m_oList.IsEmpty() );
 }
 
+CMutexEx& CSearchManager::GetLock()
+{
+	return m_oSection;
+}
+
+const Hashes::Guid& CSearchManager::GetLastED2KSearch() const
+{
+	CQuickLock oSearchLock( m_oSection );
+
+	return m_oLastED2KSearch;
+}
+
+void CSearchManager::SetLastED2KSearch(const Hashes::Guid& oGUID)
+{
+	ASSUME_SINGLE_LOCK( SearchManager.GetLock() );
+
+	m_oLastED2KSearch = oGUID;
+}
+
 //////////////////////////////////////////////////////////////////////
 // CSearchManager add and remove
 
 void CSearchManager::Add(CManagedSearch* pSearch)
 {
-	ASSUME_LOCK( m_pSection );
+	ASSUME_SINGLE_LOCK( m_oSection );
+	POSITION pos = m_oList.Find( pSearch );
 
-	POSITION pos = m_pList.Find( pSearch );
-	ASSERT( pos == NULL );
-	if ( pos == NULL )
-		m_pList.AddHead( pSearch );
+	ASSERT( !pos );
+	if ( !pos )
+		m_oList.AddHead( pSearch );
 }
 
 void CSearchManager::Remove(CManagedSearch* pSearch)
 {
-	ASSUME_LOCK( m_pSection );
+	ASSUME_SINGLE_LOCK( m_oSection );
+	POSITION pos = m_oList.Find( pSearch );
 
-	POSITION pos = m_pList.Find( pSearch );
-	ASSERT( pos != NULL );
-	if ( pos != NULL )
-		m_pList.RemoveAt( pos );
+	if ( pos )
+		m_oList.RemoveAt( pos );
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -82,11 +100,11 @@
 
 CSearchPtr CSearchManager::Find(const Hashes::Guid& oGUID) const
 {
-	ASSUME_LOCK( m_pSection );
+	ASSUME_SINGLE_LOCK( m_oSection );
 
-	for ( POSITION pos = m_pList.GetHeadPosition() ; pos ; )
+	for ( POSITION pos = m_oList.GetHeadPosition() ; pos ; )
 	{
-		CSearchPtr pManaged = m_pList.GetNext( pos );
+		CSearchPtr pManaged = m_oList.GetNext( pos );
 
 		if ( pManaged->IsEqualGUID( oGUID ) )
 			return pManaged;
@@ -102,17 +120,20 @@
 {
 	// Don't run too often to avoid excess CPU use (and router flooding)
 	DWORD tNow = GetTickCount();
-	if ( ( tNow - m_tLastTick ) < 125 ) return;
+	if ( ( tNow - m_tLastTick ) < 125 )
+		return;
+
 	m_tLastTick = tNow;
 
 	// Don't run if we aren't connected
-	if ( ! Network.IsWellConnected() ) return;
+	if ( !Network.IsWellConnected() )
+		return;
 
 	if ( Settings.Gnutella2.EnableToday )
 		HostCache.Gnutella2.PruneByQueryAck();
 
-	CSingleLock pLock( &m_pSection );
-	if ( ! pLock.Lock( 100 ) )
+	CSingleLock oSearchLock( &m_oSection );
+	if ( !oSearchLock.Lock( 100 ) )
 		return;
 
 	const int nPriorityFactor[ 3 ] = { 8, 4, 1 };
@@ -125,16 +146,15 @@
 
 	for ( int nClass = 0 ; nClass <= CManagedSearch::spMax ; nClass++ )
 	{
-		for ( POSITION pos = m_pList.GetHeadPosition(); pos ; )
+		for ( POSITION pos = m_oList.GetHeadPosition(); pos ; m_oList.GetNext( pos ) )
 		{
-			POSITION posCur = pos;
-			CSearchPtr pSearch = m_pList.GetNext( pos );
+			CSearchPtr pSearch = m_oList.GetAt( pos );
 
 			if ( pSearch->Execute( m_nPriorityClass ) )
 			{
-				m_pList.RemoveAt( posCur );
-				m_pList.AddTail( pSearch );
-				m_nPriorityCount++;
+				m_oList.RemoveAt( pos );
+				m_oList.AddTail( pSearch );
+				++m_nPriorityCount;
 				return;
 			}
 		}
@@ -147,12 +167,12 @@
 //////////////////////////////////////////////////////////////////////
 // CSearchManager query acknowledgment
 
-BOOL CSearchManager::OnQueryAck(CG2Packet* pPacket, const SOCKADDR_IN* pAddress, Hashes::Guid& oGUID)
+bool CSearchManager::OnQueryAck(CG2Packet* pPacket, const SOCKADDR_IN* pAddress, Hashes::Guid& oGUID)
 {
 	if ( ! pPacket->m_bCompound )
 		AfxThrowUserException();
 
-	DWORD nFromIP = pAddress->sin_addr.S_un.S_addr;
+	DWORD nFromIP = pAddress->sin_addr.s_addr;
 	LONG tAdjust = 0;
 	DWORD tNow = static_cast< DWORD >( time( NULL ) );
 	DWORD nHubs = 0, nLeaves = 0, nSuggestedHubs = 0;
@@ -233,70 +253,74 @@
 		(LPCTSTR)CString( inet_ntoa( pAddress->sin_addr ) ), tAdjust,
 		nHubs, nLeaves, nSuggestedHubs, nRetryAfter );
 	
-	CSingleLock oLock( &m_pSection );
-	if ( ! oLock.Lock( 100 ) )
+	CSingleLock oSearchLock( &m_oSection );
+	if ( !oSearchLock.Lock( 100 ) )
 	{
 		theApp.Message( MSG_ERROR | MSG_FACILITY_SEARCH,
 			_T("Rejecting query ack operation, search manager overloaded.") );
-		return FALSE;
+		return false;
 	}
 
 	// Is it our search?
-	if ( CSearchPtr pSearch = Find( oGUID ) )
-	{
-		pSearch->m_nHubs += nHubs;
-		pSearch->m_nLeaves += nLeaves;
+	CSearchPtr pSearch = Find( oGUID );
 
-		// (technically not required, but..)
-		pSearch->OnHostAcknowledge( nFromIP );
+	// Not our search, route it!
+	if ( !pSearch )
+		return true;
 
-		for ( int nItem = 0 ; nItem < pDone.GetSize() ; nItem++ )
-		{
-			DWORD nAddress = pDone.GetAt( nItem );
-			pSearch->OnHostAcknowledge( nAddress );
-		}
+	// Our search
+	pSearch->m_nHubs += nHubs;
+	pSearch->m_nLeaves += nLeaves;
 
-		return FALSE;
+	// (technically not required, but..)
+	pSearch->OnHostAcknowledge( nFromIP );
+
+	for ( int nItem = 0 ; nItem < pDone.GetSize() ; nItem++ )
+	{
+		DWORD nAddress = pDone.GetAt( nItem );
+		pSearch->OnHostAcknowledge( nAddress );
 	}
 
-	// Route it!
-	return TRUE;
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////
 // CSearchManager query hits
 
-BOOL CSearchManager::OnQueryHits(const CQueryHit* pHits)
+bool CSearchManager::OnQueryHits(const CQueryHit* pHits)
 {
-	CSingleLock oLock( &m_pSection );
-	if ( ! oLock.Lock( 100 ) )
+	CSingleLock oSearchLock( &m_oSection );
+	if ( !oSearchLock.Lock( 100 ) )
 	{
 		theApp.Message( MSG_ERROR | MSG_FACILITY_SEARCH,
 			_T("Rejecting query hit operation, search manager overloaded.") );
-		return FALSE;
+		return false;
 	}
 
-	if ( CSearchPtr pSearch = Find( pHits->m_oSearchID ) )
-	{
-		pSearch->OnHostAcknowledge( *(DWORD*)&pHits->m_pAddress );
+	// Is it our search?
+	CSearchPtr pSearch = Find( pHits->m_oSearchID );
 
-		while ( pHits != NULL )
-		{
-			pSearch->m_nHits ++;
-			if ( pHits->m_nProtocol == PROTOCOL_G1 )
-				pSearch->m_nG1Hits++;
-			else if ( pHits->m_nProtocol == PROTOCOL_G2 )
-				pSearch->m_nG2Hits++;
-			else if ( pHits->m_nProtocol == PROTOCOL_ED2K )
-				pSearch->m_nEDHits++;
-			pHits = pHits->m_pNext;
-		}
+	// Not our search, route it!
+	if ( !pSearch )
+		return true;
 
-		return FALSE;
+	// Our search
+	ASSERT( *(DWORD*)&pHits->m_pAddress == pHits->m_pAddress.s_addr );
+	pSearch->OnHostAcknowledge( pHits->m_pAddress.s_addr );
+
+	while ( pHits )
+	{
+		++pSearch->m_nHits;
+		if ( pHits->m_nProtocol == PROTOCOL_G1 )
+			++pSearch->m_nG1Hits;
+		else if ( pHits->m_nProtocol == PROTOCOL_G2 )
+			++pSearch->m_nG2Hits;
+		else if ( pHits->m_nProtocol == PROTOCOL_ED2K )
+			++pSearch->m_nEDHits;
+		pHits = pHits->m_pNext;
 	}
 
-	// Route it!
-	return TRUE;
+	return false;
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -304,13 +328,13 @@
 
 WORD CSearchManager::OnQueryStatusRequest(const Hashes::Guid& oGUID)
 {
-	CSingleLock pLock( &m_pSection );
-	if ( pLock.Lock( 100 ) )
-	{
-		if ( CSearchPtr pSearch = Find( oGUID ) )
-		{
-			return (WORD)min( DWORD(0xFFFE), pSearch->m_nHits );
-		}
-	}
-	return 0xFFFF;
+	CSingleLock oSearchLock( &m_oSection );
+	if ( !oSearchLock.Lock( 100 ) )
+		return 0xFFFF;
+	
+	CManagedSearch* pSearch = Find( oGUID );
+	if ( !pSearch )
+		return 0xFFFF;
+
+	return (WORD)min( DWORD(0xFFFE), pSearch->m_nHits );
 }
Index: SearchManager.h
===================================================================
--- SearchManager.h	(revision 8453)
+++ SearchManager.h	(working copy)
@@ -1,7 +1,7 @@
 //
 // SearchManager.h
 //
-// Copyright (c) Shareaza Development Team, 2002-2009.
+// Copyright (c) Shareaza Development Team, 2002-2010.
 // This file is part of SHAREAZA (shareaza.sourceforge.net)
 //
 // Shareaza is free software; you can redistribute it
@@ -30,30 +30,35 @@
 class CSearchManager
 {
 public:
+	typedef CList< CManagedSearch* > CSearchList;
+
+// Construction
+public:
 	CSearchManager();
 	~CSearchManager();
 
-	CMutexEx		m_pSection;
+// Attributes
+private:
+	mutable CMutexEx	m_oSection;
+	Hashes::Guid		m_oLastED2KSearch;
+	CSearchList			m_oList;
+	DWORD				m_tLastTick;
+	int					m_nPriorityClass;
+	int					m_nPriorityCount;
 
-	void			OnRun();
-	BOOL			OnQueryAck(CG2Packet* pPacket, const SOCKADDR_IN* pAddress, Hashes::Guid& oGUID);
-	BOOL			OnQueryHits(const CQueryHit* pHits);
-	WORD			OnQueryStatusRequest(const Hashes::Guid& oGUID);
-
-protected:
-	typedef CList< CManagedSearch* > CSearchList;
-
-	CSearchList		m_pList;
-	DWORD			m_tLastTick;
-	int				m_nPriorityClass;
-	int				m_nPriorityCount;
-	Hashes::Guid	m_oLastED2KSearch;
-
-	void			Add(CManagedSearch* pSearch);
-	void			Remove(CManagedSearch* pSearch);
-	CSearchPtr		Find(const Hashes::Guid& oGUID) const;
-
-	friend class CManagedSearch;	// m_pSection, m_oLastED2KSearch, Add(), Remove()
+// Operations
+public:
+	CMutexEx&			GetLock();
+	void				OnRun();
+	bool				OnQueryAck(CG2Packet* pPacket, const SOCKADDR_IN* pAddress, Hashes::Guid& oGUID);
+	bool				OnQueryHits(const CQueryHit* pHits);
+	WORD				OnQueryStatusRequest(const Hashes::Guid& oGUID);
+	void				Add(CManagedSearch* pSearch);
+	void				Remove(CManagedSearch* pSearch);
+	const Hashes::Guid&	GetLastED2KSearch() const;
+	void				SetLastED2KSearch(const Hashes::Guid& oGUID);
+private:
+	CSearchPtr			Find(const Hashes::Guid& oGUID) const;
 };
 
 extern CSearchManager SearchManager;
Index: WndSearch.cpp
===================================================================
--- WndSearch.cpp	(revision 8453)
+++ WndSearch.cpp	(working copy)
@@ -543,6 +543,7 @@
 
 		if ( ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) != 0x8000 )
 		{
+			CQuickLock oSearchLock( SearchManager.GetLock() );
 			for_each( begin(), end(), std::mem_fun( &CManagedSearch::Stop ) );
 		}
 
@@ -595,11 +596,13 @@
 		}
 	}
 
+	CSingleLock oSearchLock( &SearchManager.GetLock(), TRUE );
 	for ( iterator pManaged = begin(); pManaged != end(); ++pManaged )
 	{
 		(*pManaged)->Stop();
 		(*pManaged)->m_bReceive = FALSE;
 	}
+	oSearchLock.Unlock();
 
 	m_bPaused = TRUE;
 
@@ -689,8 +692,11 @@
 				m_tSearch			= GetTickCount();
 				m_bWaitMore			= FALSE;
 
-				pManaged->Stop();
-				pManaged->Start();
+				{
+					CQuickLock oSearchLock( SearchManager.GetLock() );
+					pManaged->Stop();
+					pManaged->Start();
+				}
 
 				m_nMaxResults = m_pMatches->m_nGnutellaHits + Settings.Gnutella.MaxResults;
 				m_nMaxED2KResults = m_pMatches->m_nED2KHits + Settings.eDonkey.MaxResults;
@@ -956,6 +962,7 @@
 
 		ar.WriteCount( size() );
 
+		CQuickLock oSearchLock( SearchManager.GetLock() );
 		for( iterator pManaged = begin(); pManaged != end(); ++pManaged )
 		{
 			(*pManaged)->Serialize( ar );
@@ -964,8 +971,10 @@
 	else
 	{
 		ar >> nVersion;
-		if ( nVersion != 1 ) AfxThrowUserException();
+		if ( nVersion != 1 )
+			AfxThrowUserException();
 
+		CQuickLock oSearchLock( SearchManager.GetLock() );
 		for ( DWORD_PTR nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
 		{
 			CSearchPtr pManaged( new CManagedSearch() );