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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: solaristhreads.cpp,v 1.3.2.3 2004/07/09 01:43:30 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. //This is used to turn off threads in libc5 builds.
  50. #ifdef _UNIX_THREADS_SUPPORTED
  51. #include <errno.h>
  52. #include "hxtypes.h"
  53. #include "hxresult.h"
  54. #include <synch.h>
  55. #include <thread.h>
  56. #include "solaristhreads.h"
  57. //=======================================================================
  58. //
  59. //                      HXSolarisThread
  60. //                   ----------------------
  61. //
  62. //=======================================================================
  63. HXSolarisThread::HXSolarisThread()
  64.     : HXUnixThread()
  65. {}
  66. HXSolarisThread::~HXSolarisThread()
  67. {}
  68. HX_RESULT HXSolarisThread::_thread_create( ULONG32& ulThreadID, void*(pfExecFunc(void*)), void* pArg )
  69. {
  70.     HX_RESULT retVal = HXR_OK;
  71.     thread_t threadID=0;
  72.     int nCode = thr_create(NULL, 0, pfExecFunc, pArg, 0, &threadID);
  73.     ulThreadID = threadID;
  74.     if (nCode!=0)
  75.     {
  76.         ulThreadID = 0;
  77.         retVal = HXR_FAIL;
  78.     }
  79.     return retVal;
  80. }
  81. ULONG32 HXSolarisThread::_thread_self()
  82. {
  83.     return thr_self();
  84. }
  85. void HXSolarisThread::_thread_exit(UINT32 unExitCode)
  86. {
  87.     thr_exit( (void*)unExitCode );
  88. }
  89. void HXSolarisThread::_thread_cancel(ULONG32 ulThreadID)
  90. {
  91.     HX_ASSERT( "_thread_cancel not supported on Solaris threads" == NULL );
  92. }
  93. ULONG32 HXSolarisThread::_thread_join(ULONG32 ulThreadID)
  94. {
  95.     void* pvRetVal = NULL;
  96.     thr_join( ulThreadID, NULL, &pvRetVal );
  97.     return (ULONG32)(PTR_INT)pvRetVal;
  98. }
  99. //=======================================================================
  100. //
  101. //                      HXSolarisMutex
  102. //                   ------------------
  103. //
  104. //=======================================================================
  105. HXSolarisMutex::HXSolarisMutex()
  106.     : HXUnixMutex(),
  107.       m_ulOwnerThread(0),
  108.       m_ulLockCount(0)
  109. {
  110.     mutex_init( &m_mutex, USYNC_THREAD, NULL ); 
  111.     mutex_init( &m_mtxLockLock, USYNC_THREAD, NULL );
  112. }
  113.     
  114. HXSolarisMutex::~HXSolarisMutex()
  115. {
  116.     mutex_destroy( &m_mutex );
  117.     m_ulLockCount   = 0;
  118.     m_ulOwnerThread = 0;
  119. }
  120.     
  121. HX_RESULT HXSolarisMutex::_Lock()
  122. {
  123.     //We simulate recursive mutexes.
  124.     //No one owns this mutex.
  125.     if( m_ulOwnerThread != thr_self() )
  126.     {
  127.         //We are going to block for sure.
  128.         mutex_lock(&m_mutex);
  129.         //Take ownership.
  130.         mutex_lock(&m_mtxLockLock);
  131.         m_ulOwnerThread = thr_self();
  132.         m_ulLockCount   = 1;
  133.         mutex_unlock(&m_mtxLockLock);        
  134.     }
  135.     else
  136.     {
  137.         //We alread have it locked. Just increment the lock count
  138.         mutex_lock(&m_mtxLockLock);
  139.         m_ulLockCount++;
  140.         mutex_unlock(&m_mtxLockLock);        
  141.     }
  142.     return HXR_OK;
  143. }
  144.     
  145. HX_RESULT HXSolarisMutex::_Unlock()
  146. {
  147.     //Sanity checks.
  148.     HX_ASSERT( m_ulLockCount != 0 && m_ulOwnerThread == thr_self() );
  149.     if( m_ulLockCount == 0 || m_ulOwnerThread!=thr_self() )
  150.         return HXR_FAIL;
  151.     mutex_lock(&m_mtxLockLock);
  152.     m_ulLockCount--;
  153.     if( m_ulLockCount == 0 )
  154.     {
  155.         //We are really done with it. Do the real unlock now.
  156.         m_ulOwnerThread = 0;
  157.         mutex_unlock(&m_mutex);
  158.     }
  159.     mutex_unlock(&m_mtxLockLock);  
  160.     return HXR_OK;
  161. }
  162.     
  163. HX_RESULT HXSolarisMutex::_TryLock()
  164. {
  165. //    HX_ASSERT( "Trylock isn't compatible with our home-grown recursive mutexes yet!" ==NULL );
  166.     //Warning: this is just a blind wrapper around trylock. It doesn't take into accout
  167.     //our simulation or recursive mutexes.
  168.     return (mutex_trylock(&m_mutex)==0) ? HXR_OK : HXR_FAIL;
  169. }
  170. //=======================================================================
  171. //
  172. //                      HXSolarisSemaphore
  173. //                   ------------------
  174. //
  175. //=======================================================================
  176. HXSolarisSemaphore::HXSolarisSemaphore(UINT32 unInitialCount)
  177.     : HXUnixSemaphore( unInitialCount )
  178. {
  179.     //Init the sem to non-shared and count passed in.
  180.     if( sema_init( &m_semaphore, m_unInitialCount, USYNC_THREAD, NULL ) < 0 )
  181.     {
  182. #ifdef _DEBUG
  183.         fprintf( stderr, "Can't init semaphore: %d %sn", errno, strerror(errno) );
  184. #endif
  185.     }
  186. }
  187. HXSolarisSemaphore::~HXSolarisSemaphore()
  188. {
  189.     sema_destroy( &m_semaphore );
  190. }
  191. HX_RESULT HXSolarisSemaphore::_Post()
  192. {
  193.     HX_RESULT retVal = HXR_OK;
  194.     //Init the sem to non-shared and count passed in.
  195.     if( sema_post(&m_semaphore) < 0 )
  196.     {
  197. #ifdef _DEBUG
  198.         fprintf( stderr, "Can't post to semaphore: %d %sn", errno, strerror(errno) );
  199. #endif
  200.         retVal = HXR_FAIL;
  201.     }
  202.     return retVal;
  203. }
  204. HX_RESULT HXSolarisSemaphore::_Wait()
  205. {
  206.     //sem_wait always returns zero.
  207.     sema_wait( &m_semaphore );
  208.     return HXR_OK;
  209. }
  210. HX_RESULT HXSolarisSemaphore::_TryWait()
  211. {
  212.     HX_RESULT retVal  = HXR_OK;
  213.     int       nResult = 0;
  214.     
  215.     nResult = sema_trywait( &m_semaphore );
  216.     if( nResult != 0 )
  217.     {
  218.         retVal = HXR_WOULD_BLOCK;
  219.     }
  220.     return retVal;
  221. }
  222. HX_RESULT HXSolarisSemaphore::_GetValue( int* pnCount)
  223. {
  224.     //sem_getvalue always returns zero.
  225.     HX_ASSERT( "_GetValue is not supported by Solaris threads"==NULL );
  226.     
  227.     return HXR_OK;
  228. }
  229. HXSolarisCondition::HXSolarisCondition(HXUnixMutex*& pMutex)
  230. {
  231.     HX_ASSERT( pMutex == NULL );
  232.     //Create the mutex we need to associate with this cond.
  233.     
  234.     m_pMutex = new HXSolarisMutex();
  235.     pMutex = (HXUnixMutex*)m_pMutex;
  236.     //Init our cond var.
  237.     cond_init( &m_cond, NULL, NULL );
  238. }
  239. HXSolarisCondition::~HXSolarisCondition()
  240. {
  241.     cond_destroy(&m_cond);
  242.     HX_DELETE( m_pMutex );
  243. }
  244. HX_RESULT HXSolarisCondition::_Signal()
  245. {
  246.     cond_signal(&m_cond);
  247.     return HXR_OK;
  248. }
  249. HX_RESULT HXSolarisCondition::_Broadcast()
  250. {
  251.     cond_broadcast(&m_cond);
  252.     return HXR_OK;
  253. }
  254. HX_RESULT HXSolarisCondition::_Wait()
  255. {
  256.     HX_ASSERT( m_pMutex );
  257.     //m_pMuex MUST BE LOCKED ALL READY!
  258.     cond_wait(&m_cond, m_pMutex->_GetSolarisMutex());
  259.     return HXR_OK;
  260. }
  261. HX_RESULT HXSolarisCondition::_TimedWait(UINT32 unTimeOut)
  262. {
  263.     //m_pMuex MUST BE LOCKED ALL READY!
  264.     HX_RESULT      ret = HXR_OK;
  265.     struct timeval now;
  266.     timestruc_t    timeout;
  267.     int            retcode;
  268.     gettimeofday(&now, NULL);
  269.     long int waitSeconds = unTimeOut/1000;
  270.     long int nanoSeconds = (unTimeOut-(waitSeconds*1000))*1000000;
  271.     timeout.tv_sec  = now.tv_sec+waitSeconds;
  272.     timeout.tv_nsec = now.tv_usec*1000+nanoSeconds;
  273.     if( timeout.tv_nsec >= 1000000000 )
  274.     {
  275.         timeout.tv_nsec -= 1000000000;
  276.         timeout.tv_sec  += 1;
  277.     }
  278.     retcode = cond_timedwait(&m_cond, m_pMutex->_GetSolarisMutex(), &timeout);
  279.     
  280.     if(retcode==-1)
  281.     {
  282.         ret = HXR_FAIL;
  283.         //We really could use a HXR_TIMEDOUT.
  284.         if( errno == ETIMEDOUT )
  285.             ret = HXR_WOULD_BLOCK;
  286.     }
  287.     return ret;
  288. }
  289. #endif //_UNIX_THREADS_SUPPORTED