SDL_syssem.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:4k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. /*
  19.     SDL_syssem.cpp
  20.     Epoc version by Markus Mertama  (w@iki.fi)
  21. */
  22. #ifdef SAVE_RCSID
  23. static char rcsid =
  24.  "@(#) $Id: SDL_syssem.cpp,v 1.2 2002/04/22 21:38:02 wmay Exp $";
  25. #endif
  26. /* Semaphore functions using the Win32 API */
  27. //#include <stdio.h>
  28. //#include <stdlib.h>
  29. #include <e32std.h>
  30. #include "SDL_error.h"
  31. #include "SDL_thread.h"
  32. #define SDL_MUTEX_TIMEOUT -2
  33. struct SDL_semaphore
  34.  {
  35.  TInt handle;
  36.  TInt count;
  37.  };
  38. extern TInt CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny*, TAny*);
  39. extern TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2);
  40. TInt NewSema(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) 
  41.     {
  42.     TInt value = *((TInt*) aPtr2);
  43.     return ((RSemaphore*)aPtr1)->CreateGlobal(aName, value);
  44.     }
  45. /* Create a semaphore */
  46. SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
  47. {
  48.    RSemaphore s;
  49.    TInt status = CreateUnique(NewSema, &s, &initial_value);
  50.    if(status != KErrNone)
  51.  {
  52. SDL_SetError("Couldn't create semaphore");
  53. }
  54.     SDL_semaphore* sem = new /*(ELeave)*/ SDL_semaphore;  
  55.     sem->handle = s.Handle();
  56. sem->count = initial_value;
  57. return(sem);
  58. }
  59. /* Free the semaphore */
  60. void SDL_DestroySemaphore(SDL_sem *sem)
  61. {
  62. if ( sem ) 
  63. {
  64.     RSemaphore sema;
  65.     sema.SetHandle(sem->handle);
  66. sema.Signal(sema.Count());
  67.     sema.Close();
  68.     delete sem;
  69. sem = NULL;
  70. }
  71. }
  72.   struct TInfo
  73.     {
  74.         TInfo(TInt aTime, TInt aHandle) : 
  75.         iTime(aTime), iHandle(aHandle), iVal(0) {}
  76.         TInt iTime;
  77.         TInt iHandle;
  78.         TInt iVal; 
  79.     };
  80. TBool ThreadRun(TAny* aInfo)
  81.     {
  82.         TInfo* info = STATIC_CAST(TInfo*, aInfo);
  83.         User::After(info->iTime);
  84.         RSemaphore sema;
  85.         sema.SetHandle(info->iHandle);
  86.         sema.Signal();
  87.         info->iVal = SDL_MUTEX_TIMEOUT;
  88.         return 0;
  89.     }
  90.     
  91.   
  92.     
  93.     
  94. void _WaitAll(SDL_sem *sem)
  95.     {
  96.        //since SemTryWait may changed the counter.
  97.        //this may not be atomic, but hopes it works.
  98.     RSemaphore sema;
  99.     sema.SetHandle(sem->handle);
  100.     sema.Wait();
  101.     while(sem->count < 0)
  102.         {
  103.         sema.Wait();
  104.         }    
  105.     }
  106. int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  107. {
  108. if ( ! sem ) {
  109. SDL_SetError("Passed a NULL sem");
  110. return -1;
  111. }
  112. if ( timeout == SDL_MUTEX_MAXWAIT )
  113.     {
  114.     _WaitAll(sem);
  115. return SDL_MUTEX_MAXWAIT;
  116.     } 
  117. RThread thread;
  118. TInfo* info = new (ELeave)TInfo(timeout, sem->handle);
  119.     TInt status = CreateUnique(NewThread, &thread, info);
  120.   
  121. if(status != KErrNone)
  122.     return status;
  123. thread.Resume();
  124. _WaitAll(sem);
  125. if(thread.ExitType() == EExitPending)
  126.     {
  127.         thread.Kill(SDL_MUTEX_TIMEOUT);
  128.     }
  129. thread.Close();
  130. return info->iVal;
  131. }
  132. int SDL_SemTryWait(SDL_sem *sem)
  133. {
  134.     if(sem->count > 0)
  135.         {
  136.         sem->count--;
  137.         }
  138.     return SDL_MUTEX_TIMEOUT;
  139. }
  140. int SDL_SemWait(SDL_sem *sem)
  141. {
  142. return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
  143. }
  144. /* Returns the current count of the semaphore */
  145. Uint32 SDL_SemValue(SDL_sem *sem)
  146. {
  147. if ( ! sem ) {
  148. SDL_SetError("Passed a NULL sem");
  149. return 0;
  150. }
  151. return sem->count;
  152. }
  153. int SDL_SemPost(SDL_sem *sem)
  154. {
  155. if ( ! sem ) {
  156. SDL_SetError("Passed a NULL sem");
  157. return -1;
  158. }
  159. sem->count++;
  160.     RSemaphore sema;
  161.     sema.SetHandle(sem->handle);
  162. sema.Signal();
  163. return 0;
  164. }