winthrd.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:12k
源码类别:

Symbian

开发平台:

Visual C++

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