void CQuotesProviderBase::OnEndRun()
{
	TContracts anContacts;
	{
		mir_cslock lck(m_cs);
		anContacts = m_aContacts;
		m_aRefreshingContacts.clear();
	}

	CBoolGuard bg(m_bRefreshInProgress);
	std::for_each(anContacts.begin(), anContacts.end(), boost::bind(&SetContactStatus, _1, ID_STATUS_OFFLINE));
}
void CQuotesProviderBase::OnEndRun()
{
	TContracts anContacts;
	{// for CCritSection
		CGuard<CLightMutex> cs(m_cs);
		anContacts = m_aContacts;
		m_aRefreshingContacts.clear();
	}

	CBoolGuard bg(m_bRefreshInProgress);
	std::for_each(anContacts.begin(),anContacts.end(),boost::bind(&SetContactStatus,_1,ID_STATUS_OFFLINE));
}
void CQuotesProviderBase::Run()
{
	CQuotesProviderVisitorDbSettings visitor;
	Accept(visitor);

	DWORD nTimeout = get_refresh_timeout_miliseconds(visitor);
	m_sContactListFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbDisplayNameFormat, visitor.m_pszDefDisplayFormat);
	m_sStatusMsgFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbStatusMsgFormat, visitor.m_pszDefStatusMsgFormat);
	m_sTendencyFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbTendencyFormat, visitor.m_pszDefTendencyFormat);

	enum
	{
		STOP_THREAD = 0,
		SETTINGS_CHANGED = 1,
		REFRESH_CONTACT = 2,
		COUNT_SYNC_OBJECTS = 3
	};

	HANDLE anEvents[COUNT_SYNC_OBJECTS];
	anEvents[STOP_THREAD] = g_hEventWorkThreadStop;
	anEvents[SETTINGS_CHANGED] = m_hEventSettingsChanged;
	anEvents[REFRESH_CONTACT] = m_hEventRefreshContact;

	TContracts anContacts;
	{
		mir_cslock lck(m_cs);
		anContacts = m_aContacts;
	}

	bool bGoToBed = false;

	if (g_bAutoUpdate) {
		CBoolGuard bg(m_bRefreshInProgress);
		RefreshQuotes(anContacts);
	}

	while (false == bGoToBed) {
		anContacts.clear();

		DWORD dwBegin = ::GetTickCount();
		DWORD dwResult = ::WaitForMultipleObjects(COUNT_SYNC_OBJECTS, anEvents, FALSE, nTimeout);
		switch (dwResult) {
		case WAIT_FAILED:
			assert(!"WaitForMultipleObjects failed");
			bGoToBed = true;
			break;

		case WAIT_ABANDONED_0 + STOP_THREAD:
		case WAIT_ABANDONED_0 + SETTINGS_CHANGED:
		case WAIT_ABANDONED_0 + REFRESH_CONTACT:
			assert(!"WaitForMultipleObjects abandoned");

		case WAIT_OBJECT_0 + STOP_THREAD:
			bGoToBed = true;
			break;

		case WAIT_OBJECT_0 + SETTINGS_CHANGED:
			nTimeout = get_refresh_timeout_miliseconds(visitor);
			m_sContactListFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbDisplayNameFormat, visitor.m_pszDefDisplayFormat);
			m_sStatusMsgFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbStatusMsgFormat, visitor.m_pszDefStatusMsgFormat);
			m_sTendencyFormat = Quotes_DBGetStringT(NULL, QUOTES_PROTOCOL_NAME, visitor.m_pszDbTendencyFormat, visitor.m_pszDefTendencyFormat);
			{
				mir_cslock lck(m_cs);
				anContacts = m_aContacts;
			}
			break;
		case WAIT_OBJECT_0 + REFRESH_CONTACT:
			{
				DWORD dwTimeRest = ::GetTickCount() - dwBegin;
				if (INFINITE != nTimeout && dwTimeRest < nTimeout) {
					nTimeout -= dwTimeRest;
				}

				{
					mir_cslock lck(m_cs);
					anContacts = m_aRefreshingContacts;
					m_aRefreshingContacts.clear();
				}

				{
					CBoolGuard bg(m_bRefreshInProgress);
					RefreshQuotes(anContacts);
				}
			}
			break;
		case WAIT_TIMEOUT:
			nTimeout = get_refresh_timeout_miliseconds(visitor);
			{
				mir_cslock lck(m_cs);
				anContacts = m_aContacts;
			}
			{
				CBoolGuard bg(m_bRefreshInProgress);
				RefreshQuotes(anContacts);
			}
			break;

		default:
			assert(!"What is the hell?");
		}
	}

	OnEndRun();
}