e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 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_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 | } |