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