3975
+ − 1 /*
+ − 2 SDL - Simple DirectMedia Layer
4159
+ − 3 Copyright (C) 1997-2009 Sam Lantinga
3975
+ − 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_systhread.cpp
+ − 25 Epoc thread management routines for SDL
+ − 26
+ − 27 Epoc version by Markus Mertama (w@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 }