~ubuntu-branches/ubuntu/intrepid/gpac/intrepid-proposed

« back to all changes in this revision

Viewing changes to src/utils/wce/os_thread.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2007-01-24 23:34:57 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070124233457-zzlls8afkt0nyakj
Tags: 0.4.2~rc2-0ubuntu1
* New upstream release
  * Most notably MP4 tagging support via MP4Box -itags
* debian/patches/01_64bits.dpatch: dropped; included upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *                      GPAC - Multimedia Framework C SDK
3
 
 *
4
 
 *                      Copyright (c) Jean Le Feuvre 2000-2005
5
 
 *                                      All rights reserved
6
 
 *
7
 
 *  This file is part of GPAC / common tools sub-project
8
 
 *
9
 
 *  GPAC is free software; you can redistribute it and/or modify
10
 
 *  it under the terms of the GNU Lesser General Public License as published by
11
 
 *  the Free Software Foundation; either version 2, or (at your option)
12
 
 *  any later version.
13
 
 *   
14
 
 *  GPAC is distributed in the hope that it will be useful,
15
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 
 *  GNU Lesser General Public License for more details.
18
 
 *   
19
 
 *  You should have received a copy of the GNU Lesser General Public
20
 
 *  License along with this library; see the file COPYING.  If not, write to
21
 
 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
22
 
 *
23
 
 */
24
 
 
25
 
#include <gpac/thread.h>
26
 
 
27
 
#include <windows.h>
28
 
 
29
 
typedef HANDLE TH_HANDLE ;
30
 
 
31
 
 
32
 
/*********************************************************************
33
 
                                                OS-Specific Thread Object
34
 
**********************************************************************/
35
 
struct __tag_thread
36
 
{
37
 
 
38
 
        u32 status;
39
 
        TH_HANDLE threadH;
40
 
        u32 stackSize;
41
 
        /* the thread procedure */
42
 
        u32 (*Run)(void *param);
43
 
        void *args;
44
 
        /* lock for signal */
45
 
        GF_Semaphore *_signal;
46
 
};
47
 
 
48
 
GF_Thread *gf_th_new()
49
 
{
50
 
        GF_Thread *tmp = malloc(sizeof(GF_Thread));
51
 
        memset(tmp, 0, sizeof(GF_Thread));
52
 
        tmp->status = GF_THREAD_STATUS_STOP;
53
 
        return tmp;
54
 
}
55
 
 
56
 
DWORD WINAPI RunThread(void *ptr)
57
 
{
58
 
        DWORD ret;
59
 
        GF_Thread *t = (GF_Thread *)ptr;
60
 
 
61
 
        /* Signal the caller */
62
 
        if (! t->_signal) goto exit;
63
 
 
64
 
        t->status = GF_THREAD_STATUS_RUN;
65
 
        
66
 
        gf_sema_notify(t->_signal, 1);
67
 
        /* Run our thread */
68
 
        ret = t->Run(t->args);
69
 
 
70
 
exit:
71
 
        t->status = GF_THREAD_STATUS_DEAD;
72
 
        return ret;
73
 
}
74
 
 
75
 
GF_Err gf_th_run(GF_Thread *t, u32 (*Run)(void *param), void *param)
76
 
{
77
 
        DWORD id;
78
 
        if (!t || t->Run || t->_signal) return GF_BAD_PARAM;
79
 
        t->Run = Run;
80
 
        t->args = param;
81
 
        t->_signal = gf_sema_new(1, 0);
82
 
 
83
 
        t->threadH = CreateThread(NULL,  t->stackSize, &(RunThread), (void *)t, 0, &id);
84
 
        if (t->threadH == NULL) {
85
 
                t->status = GF_THREAD_STATUS_DEAD;
86
 
                return GF_IO_ERR;
87
 
        }
88
 
        /*wait for the child function to call us - do NOT return bedfore, otherwise the thread status would
89
 
        be unknown*/    
90
 
        gf_sema_wait(t->_signal);
91
 
        gf_sema_del(t->_signal);
92
 
        t->_signal = NULL;
93
 
        return GF_OK;
94
 
}
95
 
 
96
 
 
97
 
/* Stops a thread. If Destroy is not 0, thread is destroyed DANGEROUS as no cleanup */
98
 
void Thread_Stop(GF_Thread *t, Bool Destroy)
99
 
{
100
 
        if (gf_th_status(t) == GF_THREAD_STATUS_RUN) {
101
 
                if (Destroy) {
102
 
                        DWORD dw = 1;
103
 
                        TerminateThread(t->threadH, dw);
104
 
                        t->threadH = NULL;
105
 
                } else {
106
 
                        WaitForSingleObject(t->threadH, INFINITE);                      
107
 
                }
108
 
        }
109
 
        t->status = GF_THREAD_STATUS_DEAD;
110
 
}
111
 
 
112
 
void gf_th_stop(GF_Thread *t)
113
 
{
114
 
        Thread_Stop(t, 0);
115
 
}
116
 
 
117
 
void gf_th_del(GF_Thread *t)
118
 
{
119
 
        Thread_Stop(t, 0);
120
 
        if (t->threadH) CloseHandle(t->threadH);
121
 
        free(t);
122
 
}
123
 
 
124
 
/*damn WinCE, threading scheduling is just a pain*/
125
 
void gf_th_set_priority(GF_Thread *t, s32 priority)
126
 
{
127
 
//      SetThreadPriority(t ? t->threadH : GetCurrentThread(), priority);
128
 
}
129
 
 
130
 
u32 gf_th_status(GF_Thread *t)
131
 
{
132
 
        if (!t) return 0;
133
 
        return t->status;
134
 
}
135
 
 
136
 
 
137
 
u32 gf_th_id()
138
 
{
139
 
        return ((u32) GetCurrentThreadId());
140
 
}
141
 
 
142
 
 
143
 
/*********************************************************************
144
 
                                                OS-Specific Mutex Object
145
 
**********************************************************************/
146
 
struct __tag_mutex
147
 
{
148
 
        HANDLE hMutex;
149
 
        /* We filter recursive calls (1 thread calling Lock several times in a row only locks
150
 
        ONCE the mutex. Holder is the current ThreadID of the mutex holder*/
151
 
        u32 Holder, HolderCount;
152
 
};
153
 
 
154
 
 
155
 
GF_Mutex *gf_mx_new()
156
 
{
157
 
        GF_Mutex *tmp = malloc(sizeof(GF_Mutex));
158
 
        if (!tmp) return NULL;
159
 
        memset(tmp, 0, sizeof(GF_Mutex));
160
 
        
161
 
        tmp->hMutex = CreateMutex(NULL, FALSE, NULL);
162
 
        if (!tmp->hMutex) {
163
 
                free(tmp);
164
 
                return NULL;
165
 
        }
166
 
        return tmp;
167
 
}
168
 
 
169
 
void gf_mx_del(GF_Mutex *mx)
170
 
{
171
 
        CloseHandle(mx->hMutex);
172
 
        free(mx);
173
 
}
174
 
 
175
 
void gf_mx_v(GF_Mutex *mx)
176
 
{
177
 
        u32 caller;
178
 
        if (!mx) return;
179
 
        caller = gf_th_id();
180
 
        /*only if we own*/
181
 
        if (caller != mx->Holder) return;
182
 
 
183
 
        assert(mx->HolderCount > 0);
184
 
        mx->HolderCount -= 1;
185
 
 
186
 
        if (mx->HolderCount == 0) {
187
 
                ReleaseMutex(mx->hMutex);
188
 
                mx->Holder = 0;
189
 
        }
190
 
}
191
 
 
192
 
u32 gf_mx_p(GF_Mutex *mx)
193
 
{
194
 
        u32 caller;
195
 
        if (!mx) return 0;
196
 
        
197
 
        caller = gf_th_id();
198
 
        if (caller == mx->Holder) {
199
 
                        mx->HolderCount += 1;
200
 
                        return 1;
201
 
        }
202
 
 
203
 
        switch (WaitForSingleObject(mx->hMutex, INFINITE)) {
204
 
        case WAIT_ABANDONED:
205
 
        case WAIT_TIMEOUT:
206
 
                return 0;
207
 
        default:
208
 
                mx->HolderCount = 1;
209
 
                mx->Holder = caller;
210
 
                return 1;
211
 
        }
212
 
}
213
 
 
214
 
Bool gf_mx_try_lock(GF_Mutex *mx)
215
 
{
216
 
        u32 caller;
217
 
        if (!mx) return 0;
218
 
        caller = gf_th_id();
219
 
        if (caller == mx->Holder) {
220
 
                mx->HolderCount += 1;
221
 
                return 1;
222
 
        }
223
 
 
224
 
        /*wait for 1 ms (I can't figure out from MS doc if 0 timeout only "tests the state" or also lock the mutex ... */
225
 
        switch (WaitForSingleObject(mx->hMutex, 1)) {
226
 
        case WAIT_ABANDONED:
227
 
        case WAIT_TIMEOUT:
228
 
                return 0;
229
 
        default:
230
 
                mx->HolderCount = 1;
231
 
                mx->Holder = caller;
232
 
                return 1;
233
 
        }
234
 
}
235
 
 
236
 
 
237
 
/*********************************************************************
238
 
                                                OS-Specific Semaphore Object
239
 
**********************************************************************/
240
 
struct __tag_semaphore
241
 
{
242
 
        HANDLE hSemaphore;
243
 
};
244
 
 
245
 
 
246
 
GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount)
247
 
{
248
 
        GF_Semaphore *tmp = malloc(sizeof(GF_Semaphore));
249
 
 
250
 
 
251
 
 
252
 
        if (!tmp) return NULL;
253
 
 
254
 
        tmp->hSemaphore = CreateSemaphore(NULL, InitCount, MaxCount, NULL);
255
 
        if (!tmp->hSemaphore) {
256
 
                free(tmp);
257
 
                return NULL;
258
 
        }
259
 
        return tmp;
260
 
}
261
 
 
262
 
void gf_sema_del(GF_Semaphore *sm)
263
 
{
264
 
        CloseHandle(sm->hSemaphore);
265
 
        free(sm);
266
 
}
267
 
 
268
 
u32 gf_sema_notify(GF_Semaphore *sm, u32 NbRelease)
269
 
{
270
 
        u32 prevCount;
271
 
        
272
 
        if (!sm) return 0;
273
 
 
274
 
        ReleaseSemaphore(sm->hSemaphore, NbRelease, &prevCount);
275
 
        return prevCount;
276
 
}
277
 
 
278
 
void gf_sema_wait(GF_Semaphore *sm)
279
 
{
280
 
        WaitForSingleObject(sm->hSemaphore, INFINITE);
281
 
}
282
 
 
283
 
Bool gf_sema_wait_for(GF_Semaphore *sm, u32 TimeOut)
284
 
{
285
 
        if (WaitForSingleObject(sm->hSemaphore, TimeOut) == WAIT_TIMEOUT) return 0;
286
 
        return 1;
287
 
}
288