winthrd.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxtypes.h"
  36. #include "hlxclib/windows.h"
  37. #if defined(_WIN32) && !defined(WIN32_PLATFORM_PSPC)
  38. #undef _MT
  39. #define _MT
  40. #include <process.h>
  41. #endif /*_WIN32*/
  42. #include "hxresult.h"
  43. #include "hxassert.h"
  44. #include "hxthread.h"
  45. #include "hxmsgs.h"
  46. #include "winthrd.h"
  47. #include "conn.h"
  48. #include "hxheap.h"
  49. #ifdef _DEBUG
  50. #undef HX_THIS_FILE
  51. static const char HX_THIS_FILE[] = __FILE__;
  52. #endif  
  53. #define ALLFS 0xFFFFFFFF
  54. #if defined( WIN32_PLATFORM_PSPC )
  55. #define _beginthreadex(a1, a2, a3, a4, a5, a6) (ULONG32) ::CreateThread(a1, a2, (unsigned long(__stdcall *)(void*)) a3, a4, a5, (unsigned long*) a6)
  56. #define _endthreadex ::ExitThread
  57. #endif
  58. HXWinThread::HXWinThread (void)
  59.     : m_ThreadHandle(0)
  60.     , m_ulThreadId(0)
  61.     , m_ulFlags(0)
  62. {
  63. #if defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  64.     m_bUseReaderWriter = FALSE;
  65.     m_pConn = NULL;
  66. #endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  67. }
  68. HXWinThread::~HXWinThread (void)
  69. {
  70.     Exit(0);
  71. }
  72. HX_RESULT
  73. HXWinThread::CreateThread(void* (pExecAddr(void*)), void* pArg, ULONG32 ulCreationFlags)
  74. {
  75. #ifdef _WIN32
  76.     if (m_ArgsAndAddr.m_pExecAddr)
  77.     {
  78. return HXR_UNEXPECTED;
  79.     }
  80.     if (!pExecAddr)
  81.     {
  82. return HXR_INVALID_PARAMETER;
  83.     }
  84.     m_ArgsAndAddr.m_pExecAddr = pExecAddr;
  85.     m_ArgsAndAddr.m_pArg = pArg;
  86.     if (ulCreationFlags & HX_CREATE_SUSPENDED)
  87.     {
  88. m_ulFlags = CREATE_SUSPENDED;
  89.     }
  90.     if (!ThreadCreated())
  91.     {
  92. return HXR_FAIL;
  93.     }
  94. #endif
  95.     return HXR_OK;
  96. }
  97. HX_RESULT
  98. HXWinThread::Suspend (void)
  99. {
  100. #ifdef _WIN32
  101.     HX_ASSERT(m_ThreadHandle);
  102.     if (::SuspendThread((HANDLE) m_ThreadHandle) == ALLFS)
  103.     {
  104. return HXR_FAIL;
  105.     }
  106. #endif
  107.     return HXR_OK;
  108. }
  109.     
  110. HX_RESULT
  111. HXWinThread::Resume (void)
  112. {
  113. #ifdef _WIN32
  114.     HX_ASSERT(m_ThreadHandle);
  115.     if (::ResumeThread((HANDLE) m_ThreadHandle) == ALLFS)
  116.     {
  117. return HXR_FAIL;
  118.     }
  119. #endif
  120.     return HXR_OK;
  121. }
  122. HX_RESULT
  123. HXWinThread::SetPriority (UINT32 ulPriority)
  124. {
  125. #ifdef _WIN32
  126.     HX_ASSERT(m_ThreadHandle);
  127.     if (::SetThreadPriority((HANDLE) m_ThreadHandle, ulPriority) == FALSE)
  128.     {
  129. return HXR_FAIL;
  130.     }
  131. #endif
  132.     return HXR_OK;
  133. }
  134. HX_RESULT
  135. HXWinThread::GetPriority (UINT32& ulPriority)
  136. {
  137. #ifdef _WIN32
  138.     HX_ASSERT(m_ThreadHandle);
  139.     if ((ulPriority = ::GetThreadPriority((HANDLE) m_ThreadHandle)) == 
  140.     THREAD_PRIORITY_ERROR_RETURN)
  141.     {
  142. return HXR_FAIL;
  143.     }
  144. #endif
  145.     return HXR_OK;
  146. }
  147. HX_RESULT
  148. HXWinThread::YieldTimeSlice (void)
  149. {
  150. #ifdef _WIN32
  151. //    HX_ASSERT(m_ThreadHandle);
  152.     ::Sleep(0);
  153. #endif
  154.     return HXR_OK;
  155. }
  156. HX_RESULT
  157. HXWinThread::Exit  (UINT32 ulExitCode)
  158. {
  159. #ifdef _WIN32
  160.     if (!m_ThreadHandle)
  161.     {
  162. return HXR_UNEXPECTED;
  163.     }
  164.     // Do not allow us to exit until this thread terminates
  165.     if (GetCurrentThreadId() != m_ulThreadId)
  166.     {
  167. WaitForSingleObject((HANDLE)m_ThreadHandle, INFINITE);
  168.     }
  169.     CloseHandle((HANDLE) m_ThreadHandle);
  170.     m_ThreadHandle  = 0;
  171.     m_ulThreadId    = 0;
  172. #endif
  173.     return HXR_OK;
  174. }
  175. HX_RESULT
  176. HXWinThread::GetThreadId (UINT32& ulThreadId)
  177. {
  178. #ifdef _WIN32
  179.     HX_ASSERT(m_ThreadHandle);
  180.     ulThreadId = m_ulThreadId; 
  181. #endif
  182.     return HXR_OK;
  183. }
  184. ULONG32 HXWinThread::GetCurrentThreadID()
  185. {
  186. #ifdef _WIN32
  187.     return ::GetCurrentThreadId();
  188. #endif
  189.     return 0;
  190. }
  191. #if defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  192. void 
  193. HXWinThread::SetNetworkMessageConnection(conn* pConn)
  194. {
  195.     m_pConn = pConn;
  196. }
  197. HX_RESULT
  198. HXWinThread::PostNetworkMessage(HXThreadMessage* pMsg)
  199. {
  200.     if (!m_pConn || !m_pConn->get_callback())
  201. return HXR_FAIL;
  202.     m_pConn->get_callback()->Func(SEND_BUFFER_NOTIFICATION, (BOOL)pMsg, (conn *)m_pConn);
  203. //    m_pConn->get_callback()->Func(WRITE_NOTIFICATION, TRUE, (conn *)m_pConn);
  204.     return HXR_OK;
  205. }
  206. #endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  207. HX_RESULT
  208. HXWinThread::PostMessage(HXThreadMessage* pMsg, void* pWindowHandle)
  209. {
  210.     BOOL    bResult = TRUE;
  211. #if defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  212. if (m_bUseReaderWriter && m_pConn)
  213. {
  214.     return PostNetworkMessage(pMsg);
  215. }
  216. #endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  217. #ifdef _WIN32
  218.     if (pWindowHandle)
  219.     {
  220. bResult = ::PostMessage((HWND)pWindowHandle, pMsg->m_ulMessage, 
  221.     (WPARAM) pMsg->m_pParam1, (LPARAM) pMsg->m_pParam2);
  222.     }
  223.     else 
  224.     {
  225. if(!m_ThreadHandle)
  226. {
  227.     return HXR_NOT_INITIALIZED;
  228. }
  229. /*
  230.  * Must wait until this thread has a message queue
  231.  */
  232. while(!m_ArgsAndAddr.m_bThreadCanReceiveMessages)
  233. {
  234.     Sleep(0);
  235. }
  236. bResult = ::PostThreadMessage(m_ulThreadId, pMsg->m_ulMessage, 
  237.     (WPARAM) pMsg->m_pParam1, (LPARAM) pMsg->m_pParam2);
  238.     }
  239.     if (!bResult)
  240.     {
  241. UINT32 ulErrorCode = ::GetLastError();
  242. ulErrorCode += 1;
  243.     }
  244. #endif
  245.     return bResult ? HXR_OK : HXR_FAIL;
  246. }
  247. HX_RESULT
  248. HXWinThread::GetMessage(HXThreadMessage* pMsg, UINT32 ulMsgFilterMix, UINT32 ulMsgFilterMax)
  249. {
  250. #ifdef _WIN32
  251.     MSG msg;
  252.     if (::GetMessage(&msg, NULL, ulMsgFilterMix, ulMsgFilterMax) == TRUE)
  253.     {
  254. pMsg->m_ulMessage = msg.message;
  255. pMsg->m_pParam1 = (void*) msg.wParam;
  256. pMsg->m_pParam2 = (void*) msg.lParam;
  257. pMsg->m_pPlatformSpecificData = (void*) msg.hwnd;
  258. return HXR_OK;
  259.     }
  260.     else
  261.     {
  262. return HXR_FAIL;
  263.     }
  264. #endif 
  265.     return HXR_OK;
  266. }
  267. HX_RESULT
  268. HXWinThread::DispatchMessage(HXThreadMessage* pMsg)
  269. {
  270. #ifdef _WIN32
  271.     MSG msg;
  272.     msg.message = pMsg->m_ulMessage;
  273.     msg.wParam = (WPARAM) pMsg->m_pParam1;
  274.     msg.lParam = (LPARAM) pMsg->m_pParam2;
  275.     msg.hwnd = (HWND)   pMsg->m_pPlatformSpecificData;
  276.     ::DispatchMessage(&msg);
  277. #endif 
  278.     return HXR_OK;
  279. }
  280. unsigned int 
  281. HXWinThread::HXWinThreadStartRoutine(void* p)
  282. {
  283. #ifdef _WIN32
  284.     MSG msg;
  285.     HXWinThreadArgsAndAddr* pArgsAndAddr = (HXWinThreadArgsAndAddr *)p;
  286.     /*
  287.      * Need to call this to make sure our thread creates his message queue.
  288.      */
  289.     PeekMessage(&msg,  NULL, WM_USER, WM_USER, PM_NOREMOVE);
  290.     pArgsAndAddr->m_bThreadCanReceiveMessages = TRUE;
  291.     
  292.     UINT32 ulReturnValue = ((LPTHREAD_START_ROUTINE)pArgsAndAddr->m_pExecAddr)(
  293. pArgsAndAddr->m_pArg);
  294.     _endthreadex(ulReturnValue);
  295.     return ulReturnValue;
  296. #else
  297.     return 0;
  298. #endif
  299. }
  300. BOOL
  301. HXWinThread::ThreadCreated()
  302. {
  303. #ifdef _WIN32
  304.     if (!m_ThreadHandle)
  305.     {
  306. m_ThreadHandle = _beginthreadex( NULL, 0, HXWinThreadStartRoutine,
  307.     (void*) &m_ArgsAndAddr, m_ulFlags, &m_ulThreadId );
  308.     }
  309.     if (!m_ThreadHandle)
  310.     {
  311. return FALSE;
  312.     }
  313. #endif
  314.     return TRUE;
  315. }
  316. //===========================================================================
  317. HXWinMutex::HXWinMutex    (void)
  318. {
  319. #ifdef _WIN32
  320.     ::InitializeCriticalSection(&m_Mutex);
  321. #endif
  322. }
  323. HXWinMutex::~HXWinMutex   (void)
  324. {
  325. #ifdef _WIN32
  326.     ::DeleteCriticalSection(&m_Mutex);
  327. #endif
  328. }
  329. HX_RESULT
  330. HXWinMutex::Lock     (void)
  331. {
  332. #ifdef _WIN32
  333.     ::EnterCriticalSection(&m_Mutex); 
  334. #endif
  335.     return HXR_OK;
  336. }
  337. HX_RESULT   
  338. HXWinMutex::Unlock     (void)
  339. {
  340. #ifdef _WIN32
  341.     ::LeaveCriticalSection(&m_Mutex); 
  342. #endif
  343.     return HXR_OK;
  344. }
  345. HX_RESULT   
  346. HXWinMutex::Trylock     (void)
  347. {
  348. #ifdef _WIN32
  349. #if(_WIN32_WINNT >= 0x0400)
  350.     if (::TryEnterCriticalSection(&m_Mutex))
  351.     {
  352. return HXR_OK;
  353.     }
  354.     else
  355.     {
  356. return HXR_FAIL;
  357.     }
  358. #endif /*(_WIN32_WINNT >= 0x0400)*/
  359. #endif
  360.     return HXR_NOTIMPL;
  361. }
  362. //===========================================================================
  363. HXWinNamedMutex::HXWinNamedMutex    (char* name)
  364. {
  365. #ifdef _WIN32
  366.     m_Mutex = ::CreateMutex(NULL, FALSE, OS_STRING(name));
  367. #endif
  368. }
  369. HXWinNamedMutex::~HXWinNamedMutex   (void)
  370. {
  371. #ifdef _WIN32
  372.     ::CloseHandle(m_Mutex);
  373. #endif
  374. }
  375. HX_RESULT
  376. HXWinNamedMutex::Lock     (void)
  377. {
  378. #ifdef _WIN32
  379.     ::WaitForSingleObject(m_Mutex, INFINITE);
  380. #endif
  381.     return HXR_OK;
  382. }
  383. HX_RESULT   
  384. HXWinNamedMutex::Unlock     (void)
  385. {
  386. #ifdef _WIN32
  387.     ::ReleaseMutex(m_Mutex);
  388. #endif
  389.     return HXR_OK;
  390. }
  391. HX_RESULT   
  392. HXWinNamedMutex::Trylock     (void)
  393. {
  394. #ifdef _WIN32
  395. #if(_WIN32_WINNT >= 0x0400)
  396.     if (::WaitForSingleObject(0) == WAIT_OBJECT_0)
  397.     {
  398. return HXR_OK;
  399.     }
  400.     else
  401.     {
  402. return HXR_FAIL;
  403.     }
  404. #endif /*(_WIN32_WINNT >= 0x0400)*/
  405. #endif
  406.     return HXR_NOTIMPL;
  407. }
  408. HXWinEvent::HXWinEvent(const char* pEventName, BOOL bManualReset)
  409. {
  410. #ifdef _WIN32
  411.     m_Handle = ::CreateEvent(NULL, bManualReset, FALSE, OS_STRING(pEventName));
  412.     HX_ASSERT(m_Handle != NULL);
  413. #endif /*_WIN32*/
  414. }
  415. HXWinEvent::~HXWinEvent(void)
  416. {
  417. #ifdef _WIN32
  418.     if (m_Handle)
  419.     {
  420. ::CloseHandle(m_Handle);
  421.     }
  422. #endif /*_WIN32*/
  423. }
  424. HX_RESULT
  425. HXWinEvent::SignalEvent(void)
  426. {
  427. #ifdef _WIN32
  428.     if (::SetEvent(m_Handle) == TRUE)
  429.     {
  430. return HXR_OK;
  431.     }
  432.     else
  433.     {
  434. return HXR_FAIL;
  435.     }
  436. #else
  437.     return HXR_UNEXPECTED;
  438. #endif /*_WIN32*/
  439. }
  440. HX_RESULT
  441. HXWinEvent::ResetEvent(void)
  442. {
  443. #ifdef _WIN32
  444.     if (::ResetEvent(m_Handle) == TRUE)
  445.     {
  446. return HXR_OK;
  447.     }
  448.     else
  449.     {
  450. return HXR_FAIL;
  451.     }
  452. #else
  453.     return HXR_UNEXPECTED;
  454. #endif /*_WIN32*/
  455. }
  456. void*
  457. HXWinEvent::GetEventHandle(void)
  458. {  
  459.     return (void*) m_Handle;
  460. }
  461. HX_RESULT
  462. HXWinEvent::Wait(UINT32 uTimeoutPeriod)
  463. {
  464. #ifdef _WIN32
  465.     if (uTimeoutPeriod == ALLFS)
  466.     {
  467. uTimeoutPeriod = INFINITE;
  468.     }
  469.     UINT32 ulReturnVal = ::WaitForSingleObject(m_Handle, uTimeoutPeriod);
  470.     if (ulReturnVal == WAIT_OBJECT_0)
  471.     {
  472. return HXR_OK;
  473.     }
  474.     else if ( ulReturnVal == WAIT_TIMEOUT )
  475.     {
  476.         return HXR_WOULD_BLOCK;
  477.     }
  478.     else
  479.     {
  480. return HXR_FAIL;
  481.     }
  482. #else
  483.     return HXR_UNEXPECTED;
  484. #endif /*_WIN32*/
  485. }