1 /* 2 SDL - Simple DirectMedia Layer 3 Copyright (C) 1997-2012 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 (at) devolution.com 21 */ 22 23 /* 24 SDL_systhread.cpp 25 Epoc thread management routines for SDL 26 27 Epoc version by Markus Mertama (w (at) iki.fi) 28 */ 29 30 #include "epoc_sdl.h" 31 32 //#include <stdlib.h> 33 //#include <stdio.h> 34 35 36 37 extern "C" { 38 #undef NULL 39 #include "SDL_error.h" 40 #include "SDL_thread.h" 41 #include "SDL_systhread.h" 42 #include "SDL_thread_c.h" 43 } 44 45 #include <e32std.h> 46 #include "epoc_sdl.h" 47 48 49 static int object_count; 50 51 int RunThread(TAny* data) 52 { 53 CTrapCleanup* cleanup = CTrapCleanup::New(); 54 TRAPD(err, SDL_RunThread(data)); 55 EpocSdlEnv::CleanupItems(); 56 delete cleanup; 57 return(err); 58 } 59 60 61 TInt NewThread(const TDesC& aName, TAny* aPtr1, TAny* aPtr2) 62 { 63 return ((RThread*)(aPtr1))->Create(aName, 64 RunThread, 65 KDefaultStackSize, 66 NULL, 67 aPtr2); 68 } 69 70 int CreateUnique(TInt (*aFunc)(const TDesC& aName, TAny*, TAny*), TAny* aPtr1, TAny* aPtr2) 71 { 72 TBuf<16> name; 73 TInt status = KErrNone; 74 do 75 { 76 object_count++; 77 name.Format(_L("SDL_%x"), object_count); 78 status = aFunc(name, aPtr1, aPtr2); 79 } 80 while(status == KErrAlreadyExists); 81 return status; 82 } 83 84 85 int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) 86 { 87 RThread rthread; 88 89 const TInt status = CreateUnique(NewThread, &rthread, args); 90 if (status != KErrNone) 91 { 92 delete(((RThread*)(thread->handle))); 93 thread->handle = NULL; 94 SDL_SetError("Not enough resources to create thread"); 95 return(-1); 96 } 97 rthread.Resume(); 98 thread->handle = rthread.Handle(); 99 return(0); 100 } 101 102 void SDL_SYS_SetupThread(void) 103 { 104 return; 105 } 106 107 Uint32 SDL_ThreadID(void) 108 { 109 RThread current; 110 const TThreadId id = current.Id(); 111 return id; 112 } 113 114 void SDL_SYS_WaitThread(SDL_Thread *thread) 115 { 116 SDL_TRACE1("Close thread", thread); 117 RThread t; 118 const TInt err = t.Open(thread->threadid); 119 if(err == KErrNone && t.ExitType() == EExitPending) 120 { 121 TRequestStatus status; 122 t.Logon(status); 123 User::WaitForRequest(status); 124 } 125 t.Close(); 126 127 /* RUndertaker taker; 128 taker.Create(); 129 TRequestStatus status; 130 taker.Logon(status, thread->handle); 131 User::WaitForRequest(status); 132 taker.Close();*/ 133 SDL_TRACE1("Closed thread", thread); 134 } 135 136 /* WARNING: This function is really a last resort. 137 * Threads should be signaled and then exit by themselves. 138 * TerminateThread() doesn't perform stack and DLL cleanup. 139 */ 140 void SDL_SYS_KillThread(SDL_Thread *thread) 141 { 142 RThread rthread; 143 rthread.SetHandle(thread->handle); 144 rthread.Kill(0); 145 rthread.Close(); 146 } 147