1 /* |
1 /* |
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
3 * All rights reserved. |
3 * All rights reserved. |
4 * This component and the accompanying materials are made available |
4 * This component and the accompanying materials are made available |
5 * under the terms of "Eclipse Public License v1.0" |
5 * under the terms of "Eclipse Public License v1.0" |
6 * which accompanies this distribution, and is available |
6 * which accompanies this distribution, and is available |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
8 * |
8 * |
9 * Initial Contributors: |
9 * Initial Contributors: |
10 * Nokia Corporation - initial contribution. |
10 * Nokia Corporation - initial contribution. |
11 * |
11 * |
12 * Contributors: |
12 * Contributors: |
13 * |
13 * |
14 * Description: |
14 * Description: Platform Specific Utility Functions |
15 * |
15 * |
16 */ |
16 */ |
17 |
17 |
18 #include <pthread.h> |
18 #include <pthread.h> |
19 #include <semaphore.h> |
19 #include <semaphore.h> |
20 #include <stdio.h> |
20 #include <stdio.h> |
21 #include <stdlib.h> |
21 #include <stdlib.h> |
22 #include <assert.h> |
22 #include <assert.h> |
23 #include <errno.h> |
23 #include <errno.h> |
24 |
24 |
25 #include "xaplatform.h" |
25 #include "xaplatform.h" |
26 |
26 |
27 |
|
28 |
|
29 /** MACROS **/ |
27 /** MACROS **/ |
30 |
28 |
31 /********************************************************************** |
29 /********************************************************************** |
32 * mutex management |
30 * mutex management |
33 **********************************************************************/ |
31 **********************************************************************/ |
34 /* define next if platform supports posix error checking mutex type */ |
32 /* define next if platform supports posix error checking mutex type */ |
35 #undef _MUTEXERRORSUPPORT |
33 #undef _MUTEXERRORSUPPORT |
36 |
34 |
37 #ifdef _MUTEXERRORSUPPORT |
35 #ifdef _MUTEXERRORSUPPORT |
38 typedef pthread_mutex_t XA_MTX; |
36 typedef pthread_mutex_t XA_MTX; |
39 #else |
37 #else |
40 typedef struct |
38 typedef struct |
41 { |
39 { |
42 pthread_mutex_t mutex; |
40 pthread_mutex_t mutex; |
43 pthread_t owner; |
41 pthread_t owner; |
44 } XA_MTX; |
42 } XA_MTX; |
45 #endif |
43 #endif |
46 |
44 |
47 XAresult XAImpl_CreateMutex( XAImplMutexHandle *mtx ) |
45 XAresult XAImpl_CreateMutex(XAImplMutexHandle *mtx) |
48 { |
46 { |
49 XA_MTX *pMtx = (XA_MTX *)malloc(sizeof(XA_MTX)); |
47 XA_MTX *pMtx = (XA_MTX *) malloc(sizeof(XA_MTX)); |
50 assert(mtx); |
48 assert(mtx); |
51 if( pMtx ) |
49 if (pMtx) |
52 { |
50 { |
53 pthread_mutexattr_t *pAttr = NULL; |
51 pthread_mutexattr_t *pAttr = NULL; |
54 #ifdef _MUTEXERRORSUPPORT |
52 #ifdef _MUTEXERRORSUPPORT |
55 pthread_mutexattr_t attr; |
53 pthread_mutexattr_t attr; |
56 pAttr = &attr; |
54 pAttr = &attr; |
57 pthread_mutexattr_init(pAttr); |
55 pthread_mutexattr_init(pAttr); |
58 pthread_mutexattr_settype(pAttr, PTHREAD_MUTEX_ERRORCHECK); |
56 pthread_mutexattr_settype(pAttr, PTHREAD_MUTEX_ERRORCHECK); |
59 if(pthread_mutex_init(pMtx, pAttr)) |
57 if(pthread_mutex_init(pMtx, pAttr)) |
60 #else |
58 #else |
61 if(pthread_mutex_init(&(pMtx->mutex), pAttr)) |
59 if (pthread_mutex_init(&(pMtx->mutex), pAttr)) |
62 #endif |
60 #endif |
63 { |
61 { |
64 free(pMtx); |
62 free(pMtx); |
65 *mtx = NULL; |
63 *mtx = NULL; |
66 return XA_RESULT_INTERNAL_ERROR; |
64 return XA_RESULT_INTERNAL_ERROR; |
67 } |
65 } |
68 *mtx = (XAImplMutexHandle)pMtx; |
66 *mtx = (XAImplMutexHandle) pMtx; |
69 return XA_RESULT_SUCCESS; |
67 return XA_RESULT_SUCCESS; |
70 } |
68 } |
71 else |
69 else |
72 { |
70 { |
73 return XA_RESULT_MEMORY_FAILURE; |
71 return XA_RESULT_MEMORY_FAILURE; |
74 } |
72 } |
75 } |
73 } |
76 |
74 |
77 |
75 XAresult XAImpl_LockMutex(XAImplMutexHandle mtx) |
78 XAresult XAImpl_LockMutex( XAImplMutexHandle mtx ) |
76 { |
79 { |
77 XA_MTX *pMtx = (XA_MTX*) mtx; |
80 XA_MTX *pMtx = (XA_MTX*)mtx; |
|
81 assert(pMtx); |
78 assert(pMtx); |
82 #ifdef _MUTEXERRORSUPPORT |
79 #ifdef _MUTEXERRORSUPPORT |
83 if(pthread_mutex_lock(pMtx)) |
80 if(pthread_mutex_lock(pMtx)) |
84 { |
81 { |
85 return XA_RESULT_PRECONDITIONS_VIOLATED; |
82 return XA_RESULT_PRECONDITIONS_VIOLATED; |
86 } |
83 } |
87 #else |
84 #else |
88 if( pthread_self() == pMtx->owner || |
85 if (pthread_self() == pMtx->owner || pthread_mutex_unlock(&(pMtx->mutex))) |
89 pthread_mutex_unlock(&(pMtx->mutex)) ) |
86 { |
90 { |
87 return XA_RESULT_PRECONDITIONS_VIOLATED; |
91 return XA_RESULT_PRECONDITIONS_VIOLATED; |
88 } |
92 } |
|
93 pMtx->owner = pthread_self(); |
89 pMtx->owner = pthread_self(); |
94 #endif |
90 #endif |
95 return XA_RESULT_SUCCESS; |
91 return XA_RESULT_SUCCESS; |
96 } |
92 } |
97 |
93 |
98 XAresult XAImpl_TryLockMutex( XAImplMutexHandle mtx ) |
94 XAresult XAImpl_TryLockMutex(XAImplMutexHandle mtx) |
99 { |
95 { |
100 XA_MTX *pMtx = (XA_MTX*)mtx; |
96 XA_MTX *pMtx = (XA_MTX*) mtx; |
101 XAint32 mutexRet; |
97 XAint32 mutexRet; |
102 XAresult ret = XA_RESULT_SUCCESS; |
98 XAresult ret = XA_RESULT_SUCCESS; |
103 assert(pMtx); |
99 assert(pMtx); |
104 |
100 |
105 #ifdef _MUTEXERRORSUPPORT |
101 #ifdef _MUTEXERRORSUPPORT |
106 mutexRet = pthread_ mutex_trylock(pMtx); |
102 mutexRet = pthread_ mutex_trylock(pMtx); |
107 switch (mutexRet) |
103 switch (mutexRet) |
108 { |
104 { |
109 case EBUSY: |
105 case EBUSY: |
110 /* if mutex is already locked, return permission denied */ |
106 /* if mutex is already locked, return permission denied */ |
111 ret = XA_RESULT_PERMISSION_DENIED; |
107 ret = XA_RESULT_PERMISSION_DENIED; |
112 break; |
108 break; |
113 case 0: |
109 case 0: |
114 ret = XA_RESULT_SUCCESS; |
110 ret = XA_RESULT_SUCCESS; |
115 break; |
111 break; |
116 default: |
112 default: |
117 ret = XA_RESULT_PRECONDITIONS_VIOLATED; |
113 ret = XA_RESULT_PRECONDITIONS_VIOLATED; |
118 break; |
114 break; |
119 } |
115 } |
120 #else |
116 #else |
121 if( pthread_self() == pMtx->owner ) |
117 if (pthread_self() == pMtx->owner) |
122 { |
118 { |
123 return XA_RESULT_PRECONDITIONS_VIOLATED; |
119 return XA_RESULT_PRECONDITIONS_VIOLATED; |
124 } |
120 } |
125 |
121 |
126 mutexRet = pthread_mutex_trylock(&(pMtx->mutex)); |
122 mutexRet = pthread_mutex_trylock(&(pMtx->mutex)); |
127 switch (mutexRet) |
123 switch (mutexRet) |
128 { |
124 { |
129 case EBUSY: |
125 case EBUSY: |
130 /* if mutex is already locked, return permission denied */ |
126 /* if mutex is already locked, return permission denied */ |
131 ret = XA_RESULT_PERMISSION_DENIED; |
127 ret = XA_RESULT_PERMISSION_DENIED; |
132 break; |
128 break; |
133 case 0: |
129 case 0: |
134 pMtx->owner = pthread_self(); |
130 pMtx->owner = pthread_self(); |
135 ret = XA_RESULT_SUCCESS; |
131 ret = XA_RESULT_SUCCESS; |
136 break; |
132 break; |
137 default: |
133 default: |
138 ret = XA_RESULT_PRECONDITIONS_VIOLATED; |
134 ret = XA_RESULT_PRECONDITIONS_VIOLATED; |
139 break; |
135 break; |
140 } |
136 } |
141 #endif |
137 #endif |
142 return ret; |
138 return ret; |
143 } |
139 } |
144 |
140 |
145 |
141 XAresult XAImpl_UnlockMutex(XAImplMutexHandle mtx) |
146 XAresult XAImpl_UnlockMutex( XAImplMutexHandle mtx ) |
142 { |
147 { |
143 XA_MTX *pMtx = (XA_MTX*) mtx; |
148 XA_MTX *pMtx = (XA_MTX*)mtx; |
|
149 assert(pMtx); |
144 assert(pMtx); |
150 #ifdef _MUTEXERRORSUPPORT |
145 #ifdef _MUTEXERRORSUPPORT |
151 if(pthread_mutex_lock(pMtx)) |
146 if(pthread_mutex_lock(pMtx)) |
152 { |
147 { |
153 return XA_RESULT_PRECONDITIONS_VIOLATED; |
148 return XA_RESULT_PRECONDITIONS_VIOLATED; |
154 } |
149 } |
155 #else |
150 #else |
156 if( pthread_self() != pMtx->owner || |
151 if (pthread_self() != pMtx->owner || pthread_mutex_unlock(&(pMtx->mutex))) |
157 pthread_mutex_unlock(&(pMtx->mutex)) ) |
152 { |
158 { |
153 return XA_RESULT_PRECONDITIONS_VIOLATED; |
159 return XA_RESULT_PRECONDITIONS_VIOLATED; |
154 } |
160 } |
|
161 // Changing the below value to 0 since owner is an unsigned int. |
155 // Changing the below value to 0 since owner is an unsigned int. |
162 // pMtx->owner = -1; |
156 // pMtx->owner = -1; |
163 pMtx->owner = 0; |
157 pMtx->owner = 0; |
164 #endif |
158 #endif |
165 return XA_RESULT_SUCCESS; |
159 return XA_RESULT_SUCCESS; |
166 } |
160 } |
167 |
161 |
168 void XAImpl_DeleteMutex( XAImplMutexHandle mtx ) |
162 void XAImpl_DeleteMutex(XAImplMutexHandle mtx) |
169 { |
163 { |
170 XA_MTX *pMtx = (XA_MTX*)mtx; |
164 XA_MTX *pMtx = (XA_MTX*) mtx; |
171 if( pMtx ) |
165 if (pMtx) |
172 { |
166 { |
173 #ifdef _MUTEXERRORSUPPORT |
167 #ifdef _MUTEXERRORSUPPORT |
174 pthread_mutex_destroy(pMtx); |
168 pthread_mutex_destroy(pMtx); |
175 #else |
169 #else |
176 pthread_mutex_destroy(&(pMtx->mutex)); |
170 pthread_mutex_destroy(&(pMtx->mutex)); |
177 #endif |
171 #endif |
178 free(pMtx); |
172 free(pMtx); |
179 } |
173 } |
180 } |
174 } |
181 |
175 |
182 /********************************************************************** |
176 /********************************************************************** |
183 * semaphores |
177 * semaphores |
184 **********************************************************************/ |
178 **********************************************************************/ |
185 |
179 |
186 |
180 XAresult XAImpl_CreateSemaphore(XAImplSemHandle *sem) |
187 XAresult XAImpl_CreateSemaphore( XAImplSemHandle *sem ) |
181 { |
188 { |
182 sem_t *pSem = (sem_t*) malloc(sizeof(sem_t)); |
189 sem_t *pSem = (sem_t*)malloc(sizeof(sem_t)); |
|
190 assert(sem); |
183 assert(sem); |
191 if( pSem ) |
184 if (pSem) |
192 { |
185 { |
193 if(sem_init(pSem,0,0)) |
186 if (sem_init(pSem, 0, 0)) |
194 { |
187 { |
195 free(pSem); |
188 free(pSem); |
196 *sem = NULL; |
189 *sem = NULL; |
197 return XA_RESULT_INTERNAL_ERROR; |
190 return XA_RESULT_INTERNAL_ERROR; |
198 } |
191 } |
199 *sem = (XAImplSemHandle)pSem; |
192 *sem = (XAImplSemHandle) pSem; |
200 return XA_RESULT_SUCCESS; |
193 return XA_RESULT_SUCCESS; |
201 } |
194 } |
202 else |
195 else |
203 { |
196 { |
204 return XA_RESULT_MEMORY_FAILURE; |
197 return XA_RESULT_MEMORY_FAILURE; |
205 } |
198 } |
206 } |
199 } |
207 |
200 |
208 XAresult XAImpl_WaitSemaphore( XAImplSemHandle sem ) |
201 XAresult XAImpl_WaitSemaphore(XAImplSemHandle sem) |
209 { |
202 { |
210 sem_t* pSem = (sem_t*)sem; |
203 sem_t* pSem = (sem_t*) sem; |
211 assert(pSem); |
204 assert(pSem); |
212 sem_wait(pSem); |
205 sem_wait(pSem); |
213 return XA_RESULT_SUCCESS; |
206 return XA_RESULT_SUCCESS; |
214 } |
207 } |
215 |
208 |
216 XAresult XAImpl_PostSemaphore( XAImplSemHandle sem ) |
209 XAresult XAImpl_PostSemaphore(XAImplSemHandle sem) |
217 { |
210 { |
218 sem_t *pSem = (sem_t*)sem; |
211 sem_t *pSem = (sem_t*) sem; |
219 assert(pSem); |
212 assert(pSem); |
220 sem_post(pSem); |
213 sem_post(pSem); |
221 return XA_RESULT_SUCCESS; |
214 return XA_RESULT_SUCCESS; |
222 } |
215 } |
223 |
216 |
224 void XAImpl_DeleteSemaphore( XAImplSemHandle sem ) |
217 void XAImpl_DeleteSemaphore(XAImplSemHandle sem) |
225 { |
218 { |
226 sem_t *pSem = (sem_t*)sem; |
219 sem_t *pSem = (sem_t*) sem; |
227 if( pSem ) |
220 if (pSem) |
228 { |
221 { |
229 sem_destroy(pSem); |
222 sem_destroy(pSem); |
230 free(pSem); |
223 free(pSem); |
231 } |
224 } |
232 } |
225 } |
233 |
226 |
234 /********************************************************************** |
227 /********************************************************************** |
235 * THREADS |
228 * THREADS |
236 **********************************************************************/ |
229 **********************************************************************/ |
237 |
230 |
238 XAresult XAImpl_CreateThreadHandle( XAImplThreadHandle *thd ) |
231 XAresult XAImpl_CreateThreadHandle(XAImplThreadHandle *thd) |
239 { |
232 { |
240 pthread_t *pThd = (pthread_t*)malloc(sizeof(pthread_t)); |
233 pthread_t *pThd = (pthread_t*) malloc(sizeof(pthread_t)); |
241 assert(thd); |
234 assert(thd); |
242 if( !pThd ) |
235 if (!pThd) |
243 { |
236 { |
244 return XA_RESULT_MEMORY_FAILURE; |
237 return XA_RESULT_MEMORY_FAILURE; |
245 } |
238 } |
246 *thd = (XAImplThreadHandle)pThd; |
239 *thd = (XAImplThreadHandle) pThd; |
247 return XA_RESULT_SUCCESS; |
240 return XA_RESULT_SUCCESS; |
248 } |
241 } |
249 |
242 |
250 XAresult XAImpl_StartThread( XAImplThreadHandle thd, |
243 XAresult XAImpl_StartThread(XAImplThreadHandle thd, void *thdattrib, |
251 void *thdattrib, XAImplThreadFunction thdfunc, void* thdfuncargs ) |
244 XAImplThreadFunction thdfunc, void* thdfuncargs) |
252 { |
245 { |
253 pthread_t *pThd = (pthread_t*)thd; |
246 pthread_t *pThd = (pthread_t*) thd; |
254 assert(thd); |
247 assert(thd); |
255 if ( pthread_create(pThd, thdattrib, thdfunc, thdfuncargs) ) |
248 if (pthread_create(pThd, thdattrib, thdfunc, thdfuncargs)) |
256 { |
249 { |
257 return XA_RESULT_INTERNAL_ERROR; |
250 return XA_RESULT_INTERNAL_ERROR; |
258 } |
251 } |
259 return XA_RESULT_SUCCESS; |
252 return XA_RESULT_SUCCESS; |
260 } |
253 } |
261 |
254 |
262 void XAImpl_CancelThread( XAImplThreadHandle thd ) |
255 void XAImpl_CancelThread(XAImplThreadHandle thd) |
263 { |
256 { |
264 // int res; |
257 // int res; |
265 // TL: TODO: There is no pthread_cancel API in S60, need to replace |
258 // TL: TODO: There is no pthread_cancel API in S60, need to replace |
266 //res = pthread_cancel(*pThd); |
259 //res = pthread_cancel(*pThd); |
267 |
260 |
268 } |
261 } |
269 |
262 |
270 void XAImpl_ExitThread( XAImplThreadHandle thd ) |
263 void XAImpl_ExitThread(XAImplThreadHandle thd) |
271 { |
264 { |
272 pthread_exit(NULL); |
265 pthread_exit(NULL); |
273 } |
266 } |
274 |
267 |
275 void XAImpl_DeleteThreadHandle( XAImplThreadHandle thd ) |
268 void XAImpl_DeleteThreadHandle(XAImplThreadHandle thd) |
276 { |
269 { |
277 pthread_t *pThd = (pthread_t*)thd; |
270 pthread_t *pThd = (pthread_t*) thd; |
278 if( pThd ) |
271 if (pThd) |
279 { |
272 { |
280 free(pThd); |
273 free(pThd); |
281 } |
274 } |
282 } |
275 } |
283 |
276 |