• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20 
21 //               O S C L _ E R R O R
22 
23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
24 
25 /*! \addtogroup osclerror OSCL Error
26  *
27  * @{
28  */
29 
30 
31 /** \file oscl_error.h
32     \brief OSCL Error trap and cleanup include file
33 */
34 
35 #ifndef OSCL_ERROR_H_INCLUDED
36 #define OSCL_ERROR_H_INCLUDED
37 
38 #ifndef OSCL_HEAPBASE_H_INCLUDED
39 #include "oscl_heapbase.h"
40 #endif
41 
42 #ifndef OSCL_DEFALLOC_H_INCLUDED
43 #include "oscl_defalloc.h"
44 #endif
45 
46 #ifndef OSCL_ERROR_CODES_H_INCLUDED
47 #include "oscl_error_codes.h"
48 #endif
49 
50 /**
51 //Per-thread Error trap init.
52 */
53 class OsclErrorTrapImp;
54 class OsclErrorTrap
55 {
56     public:
57         /**
58          * Allocate and initialize error trap for
59          * the calling thread.
60          * @param aAlloc: optional, allocator to use for
61          *   the internal implementation.
62          * @return 0 for success, or an error
63          */
64         OSCL_IMPORT_REF static int32 Init(Oscl_DefAlloc *aAlloc = NULL);
65         /**
66          * Cleanup and destroy error trap for
67          * the calling thread.
68          * @return 0 for success, or an error
69          */
70         OSCL_IMPORT_REF static int32 Cleanup();
71         /**
72          * Get the ErrorTrapImp for the current thread.
73          * Leaves on error.
74          */
75         OSCL_IMPORT_REF static OsclErrorTrapImp* GetErrorTrapImp();
76 };
77 
78 
79 /**
80 //User Error class
81 */
82 class OsclError
83 {
84     public:
85         /**
86         //Cleanup stack operations.
87         */
88 
89         /** Push an _OsclHeapBase item onto the cleanup stack.
90         */
91         OSCL_IMPORT_REF static void PushL(_OsclHeapBase * aPtr);
92 
93         /** Push an OsclAny item onto the cleanup stack.
94         */
95         OSCL_IMPORT_REF static void PushL(OsclAny* aPtr);
96 
97         /** Push an OsclTrapItem onto the cleanup stack
98         */
99         OSCL_IMPORT_REF static void PushL(OsclTrapItem anItem);
100 
101         /** Pop the cleanup stack
102         */
103         OSCL_IMPORT_REF static void Pop();
104 
105         /** Pop the cleanup stack N times
106         */
107         OSCL_IMPORT_REF static void Pop(int32 aCount);
108 
109         /** Destroy the item on the top of the cleanup
110         * stack and pop it
111         */
112         OSCL_IMPORT_REF static void PopDealloc();
113 
114         /** PopDealloc N times
115         */
116         OSCL_IMPORT_REF static void PopDealloc(int32 aCount);
117 
118         /** Do a Leave error, with the given reason code.
119         ** When a leave occurs, all items on the cleanup stack
120         ** for the current trap level will be destroyed, and
121         ** execution will jump to the trap handler.
122         */
123         OSCL_IMPORT_REF static void Leave(int32 aReason);
124 
125         /** Evaluate the input parameter, and if it is null,
126         ** do a Leave with OsclErrNoMemory reason code.
127         */
128         OSCL_IMPORT_REF static void LeaveIfNull(OsclAny *a);
129 
130         /** Evaluate the input parameter, and if it is an
131         ** error code (non-zero), then do a Leave with the
132         ** provided reason code.
133         */
134         OSCL_IMPORT_REF static void LeaveIfError(int32 aReason);
135 
136 };
137 
138 /** Cleanup Stack user macros
139 */
140 #define OSCL_TRAPSTACK_PUSH(a) OsclError::PushL(a)
141 #define OSCL_TRAPSTACK_POP() OsclError::Pop()
142 #define OSCL_TRAPSTACK_POPDEALLOC() OsclError::PopDealloc()
143 
144 /**
145 * TLS & Singleton registry calls that throw exceptions on errors.
146 */
147 
148 //Map TPVBaseErrorEnum return codes to Oscl Error leave codes
149 //Some of these codes indicate failure to init Oscl layer, in
150 //that case they map to zero and assert.
151 static const int32 _OsclBaseToErrorMap[] =
152 {
153     /*0*/OsclErrGeneral
154     ,/*EPVErrorBaseNotInstalled=1*/0
155     ,/*EPVErrorBaseAlreadyInstalled=2*/OsclErrAlreadyInstalled
156     ,/*EPVErrorBaseOutOfMemory=3*/OsclErrNoMemory
157     ,/*EPVErrorBaseSystemCallFailed=4*/OsclErrSystemCallFailed
158     ,/*EPVErrorBaseTooManyThreads=5*/0
159     ,/*EPVErrorBaseNotSupported=6*/OsclErrNotSupported
160     ,/*EPVErrorBaseNotReady=7*/OsclErrNotReady
161 };
162 
163 #include "oscl_singleton.h"
164 #include "oscl_assert.h"
165 #if(OSCL_HAS_SINGLETON_SUPPORT)
166 class OsclSingletonRegistryEx
167 {
168     public:
169         /*
170         ** Get an entry
171         ** @param ID: identifier
172         ** @returns: the entry value
173         ** @exception: leaves on error.
174         */
getInstance(uint32 ID)175         static OsclAny* getInstance(uint32 ID)
176         {
177             int32 error;
178             OsclAny* val = OsclSingletonRegistry::getInstance(ID, error);
179             if (error)
180             {
181                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
182                 OsclError::Leave(_OsclBaseToErrorMap[error]);
183             }
184             return val;
185         }
186 
187         /*
188         ** Set an entry
189         ** @param ID: identifier
190         ** @returns: the entry value
191         ** @exception: leaves on error.
192         */
registerInstance(OsclAny * ptr,uint32 ID)193         static void registerInstance(OsclAny* ptr, uint32 ID)
194         {
195             int32 error;
196             OsclSingletonRegistry::registerInstance(ptr, ID, error);
197             if (error)
198             {
199                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
200                 OsclError::Leave(_OsclBaseToErrorMap[error]);
201             }
202         }
203 
204         /*
205         //These two APIs can be used to do "test and set" operations on a singleton.
206         //Be sure to always call both APIs to avoid deadlock.
207         */
208 
209         /*
210         * Return the current value of the singleton and leave the singleton table locked
211         * on return.
212         * @param ID the singleton ID
213         * @returns the singleton value.
214         ** @exception: leaves on error.
215         */
lockAndGetInstance(uint32 ID)216         static OsclAny* lockAndGetInstance(uint32 ID)
217         {
218             int32 error;
219             OsclAny* val = OsclSingletonRegistry::lockAndGetInstance(ID, error);
220             if (error)
221             {
222                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
223                 OsclError::Leave(_OsclBaseToErrorMap[error]);
224             }
225             return val;
226         }
227 
228         /*
229         * Set the value of the singleton.  Assume the singleton table is locked on entry.
230         * @param ptr the singleton value
231         * @param ID the singleton ID
232         ** @exception: leaves on error.
233         */
registerInstanceAndUnlock(OsclAny * ptr,uint32 ID)234         static void registerInstanceAndUnlock(OsclAny* ptr, uint32 ID)
235         {
236             int32 error;
237             OsclSingletonRegistry::registerInstanceAndUnlock(ptr, ID, error);
238             if (error)
239             {
240                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
241                 OsclError::Leave(_OsclBaseToErrorMap[error]);
242             }
243         }
244 };
245 
246 template < class T, uint32 ID, class Registry = OsclSingletonRegistryEx > class OsclSingletonEx
247 {
248     private:
249         // make the copy constructor and assignment operator private
250         OsclSingletonEx& operator=(OsclSingletonEx& _Y)
251         {
252             return(*this);
253         }
254 
255     protected:
256         T* _Ptr;
257 
258     public:
OsclSingletonEx()259         OsclSingletonEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {};
260 
~OsclSingletonEx()261         ~OsclSingletonEx() {};
262 
263         /**
264         * @brief The indirection operator (*) accesses a value indirectly,
265         * through a pointer
266         *
267         * This operator ensures that the OsclSingleton can be used like the
268         * regular pointer that it was initialized with.
269         */
270         T& operator*() const
271         {
272             return(*_Ptr);
273         }
274 
275         /**
276         * @brief The indirection operator (->) accesses a value indirectly,
277         * through a pointer
278         *
279         * This operator ensures that the OsclSingleton can be used like the
280         * regular pointer that it was initialized with.
281         */
282         T *operator->() const
283         {
284             return(_Ptr);
285         }
286 
287 
288         /**
289         * @brief set() method sets ownership to the pointer, passed.
290         * This method is needed when the class is created with a default
291         * constructor. Returns false in case the class is non-empty.
292         *
293         */
set()294         bool set()
295         {
296             _Ptr = OSCL_STATIC_CAST(T*, Registry::getInstance(ID));
297             return (_Ptr ? true : false);
298         }
299 
300 };
301 #endif //OSCL_HAS_SINGLETON_SUPPORT
302 
303 #include "oscl_tls.h"
304 #include "oscl_assert.h"
305 class OsclTLSRegistryEx
306 {
307     public:
308         /*
309         ** Get an entry
310         ** @param ID: identifier
311         ** @returns: the entry value
312         ** @exception: leaves on error.
313         */
getInstance(uint32 ID)314         static OsclAny* getInstance(uint32 ID)
315         {
316             int32 error;
317             OsclAny* val = OsclTLSRegistry::getInstance(ID, error);
318             if (error)
319             {
320                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
321                 OsclError::Leave(_OsclBaseToErrorMap[error]);
322             }
323             return val;
324         }
325         /*
326         ** Set an entry
327         ** @param ID: identifier
328         ** @returns: the entry value
329         ** @exception: leaves on error.
330         */
registerInstance(OsclAny * ptr,uint32 ID)331         static void registerInstance(OsclAny* ptr, uint32 ID)
332         {
333             int32 error;
334             OsclTLSRegistry::registerInstance(ptr, ID, error);
335             if (error)
336             {
337                 OSCL_ASSERT(_OsclBaseToErrorMap[error]);
338                 OsclError::Leave(_OsclBaseToErrorMap[error]);
339             }
340         }
341 };
342 
343 template < class T, uint32 ID, class Registry = OsclTLSRegistryEx > class OsclTLSEx
344 {
345     private:
346         // make the copy constructor and assignment operator private
347         OsclTLSEx& operator=(OsclTLSEx& _Y)
348         {
349             return(*this);
350         }
351 
352     protected:
353         T* _Ptr;
354 
355     public:
OsclTLSEx()356         OsclTLSEx(): _Ptr(OSCL_STATIC_CAST(T*, Registry::getInstance(ID))) {};
357 
~OsclTLSEx()358         ~OsclTLSEx() {};
359 
360         /**
361         * @brief The indirection operator (*) accesses a value indirectly,
362         * through a pointer
363         *
364         * This operator ensures that the OsclTLS can be used like the
365         * regular pointer that it was initialized with.
366         */
367         T& operator*() const
368         {
369             return(*_Ptr);
370         }
371 
372         /**
373         * @brief The indirection operator (->) accesses a value indirectly,
374         * through a pointer
375         *
376         * This operator ensures that the OsclTLS can be used like the
377         * regular pointer that it was initialized with.
378         */
379         T *operator->() const
380         {
381             return(_Ptr);
382         }
383 
384 
385         /**
386         * @brief set() method sets ownership to the pointer, passed.
387         * This method is needed when the class is created with a default
388         * constructor. Returns false in case the class is non-empty.
389         *
390         */
set()391         bool set()
392         {
393             _Ptr = OSCL_STATIC_CAST(T*, Registry::getInstance(ID));
394             return (_Ptr ? true : false);
395         }
396 
397 };
398 
399 #endif
400 
401 /*! @} */
402