home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / com / connect / server / random.cpp < prev    next >
C/C++ Source or Header  |  1998-04-02  |  3KB  |  121 lines

  1. // Random.cpp : Implementation of CConnectApp and DLL registration.
  2.  
  3. #include "preconn.h"
  4. #include "Connect.h"
  5. #include "Random.h"
  6.  
  7. /////////////////////////////////////////////////////////////////////////////
  8. //
  9.  
  10. STDMETHODIMP CRandom::InterfaceSupportsErrorInfo(REFIID riid)
  11. {
  12.     if (riid == IID_IRandom)
  13.         return S_OK;
  14.     return S_FALSE;
  15. }
  16.  
  17. /////////////////////////////////////////////////////////////////////////////
  18. //
  19.  
  20. DWORD WINAPI RandomSessionThreadEntry(void* pv)
  21. {
  22.     CRandom::RandomSessionData* pS = (CRandom::RandomSessionData*)pv;
  23.     CRandom* p = pS->pRandom;
  24.     while (WaitForSingleObject(pS->m_hEvent, 0) != WAIT_OBJECT_0)
  25.         p->Fire(pS->m_nID);
  26.     return 0;
  27. }
  28.  
  29. CRandom::~CRandom()
  30. {
  31.     StopAll();
  32. }
  33.  
  34. void CRandom::CreateRandomSession(RandomSessionData& rs)
  35. {
  36.     DWORD dwThreadID = 0;
  37.     _ASSERTE(rs.m_hEvent == NULL);
  38.     _ASSERTE(rs.m_hThread == NULL);
  39.     rs.pRandom = this;
  40.     rs.m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  41.     rs.m_hThread = CreateThread(NULL, 0, &RandomSessionThreadEntry, &rs, 0, &dwThreadID);
  42. }
  43.  
  44. STDMETHODIMP CRandom::get_Start(long* pnID)
  45. {
  46.     if (pnID == NULL)
  47.         return E_POINTER;
  48.     *pnID = 0;
  49.     HRESULT hRes = S_OK;
  50.     m_cs.Lock();
  51.     for (long i=0;i<nMaxSessions;i++)
  52.     {
  53.         if (m_rsArray[i].m_hEvent == NULL)
  54.         {
  55.             m_rsArray[i].m_nID = i;
  56.             CreateRandomSession(m_rsArray[i]);
  57.             *pnID = i;
  58.             break;
  59.         }
  60.     }
  61.     if (i == nMaxSessions) //fell through
  62.         hRes = E_FAIL;
  63.     m_cs.Unlock();
  64.     return hRes;
  65. }
  66.  
  67.  
  68. STDMETHODIMP CRandom::put_Stop(long nID)
  69. {
  70.     HRESULT hRes = S_OK;
  71.     m_cs.Lock();
  72.     if (m_rsArray[nID].m_hEvent != NULL)
  73.     {
  74.         SetEvent(m_rsArray[nID].m_hEvent);
  75.         WaitForSingleObject(m_rsArray[nID].m_hThread, INFINITE);
  76.         CloseHandle(m_rsArray[nID].m_hThread);
  77.         memset(&m_rsArray[nID], 0, sizeof(RandomSessionData));
  78.     }
  79.     else
  80.         hRes = E_INVALIDARG;
  81.     m_cs.Unlock();
  82.     return hRes;
  83. }
  84.  
  85. STDMETHODIMP CRandom::StopAll()
  86. {
  87.     m_cs.Lock();
  88.     for (long i=0;i<nMaxSessions;i++)
  89.     {
  90.         if (m_rsArray[i].m_hEvent != NULL)
  91.         {
  92.             SetEvent(m_rsArray[i].m_hEvent);
  93.             WaitForSingleObject(m_rsArray[i].m_hThread, INFINITE);
  94.             CloseHandle(m_rsArray[i].m_hThread);
  95.             memset(&m_rsArray[i], 0, sizeof(RandomSessionData));
  96.         }
  97.     }
  98.     m_cs.Unlock();
  99.     return S_OK;
  100. }
  101.  
  102. // broadcast to all the objects
  103. HRESULT CRandom::Fire(long nID)
  104. {
  105.     IConnectionPointImpl<CRandom, &IID_IRandomEvent, CComDynamicUnkArray>* p = this;
  106.     Lock();
  107.     HRESULT hr = S_OK;
  108.     IUnknown** pp = p->m_vec.begin();
  109.     while (pp < p->m_vec.end() && hr == S_OK)
  110.     {
  111.         if (*pp != NULL)
  112.         {
  113.             IRandomEvent* pIRandomEvent = (IRandomEvent*)*pp;
  114.             hr = pIRandomEvent->put_Fire(nID);
  115.         }
  116.         pp++;
  117.     }
  118.     Unlock();
  119.     return hr;
  120. }
  121.