1 /* thread_init.cpp
2 **
3 ** Copyright 2007, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "playerdriver.h"
19 #include <media/thread_init.h>
20 //#include <android_runtime/AndroidRuntime.h>
21 #include <utils/threads.h>
22 #include "android_log_appender.h"
23 #include "pvlogger_time_and_id_layout.h"
24
25 #include "oscl_mem.h"
26 #include "oscl_error.h"
27
28 #include "OMX_Core.h"
29
30 #if (PVLOGGER_INST_LEVEL > 0)
31 #include "android_logger_config.h"
32 #endif
33
34 using namespace android;
35 static pthread_key_t ptkey=NULL;
36
keydestructor(void *)37 static void keydestructor(void*)
38 {
39 // This thread is about to exit, so we can un-initialize
40 // PV for this thread.
41 UninitializeForThread();
42 }
43
44 static pthread_once_t create_tls_entry_once = PTHREAD_ONCE_INIT;
45
CreateTLSEntry()46 static void CreateTLSEntry() {
47 LOG_ALWAYS_FATAL_IF(
48 0 != pthread_key_create(&ptkey, keydestructor),
49 "Ran out of TLS entries");
50 }
51
52 template<class DestructClass>
53 class LogAppenderDestructDealloc : public OsclDestructDealloc
54 {
55 public:
destruct_and_dealloc(OsclAny * ptr)56 virtual void destruct_and_dealloc(OsclAny *ptr)
57 {
58 delete((DestructClass*)ptr);
59 }
60 };
61
InitializeForThread()62 bool InitializeForThread()
63 {
64 pthread_once(&create_tls_entry_once, &CreateTLSEntry);
65
66 if (NULL == pthread_getspecific(ptkey)) {
67 // PV hasn't yet been initialized for this thread;
68 int error = OsclBase::Init();
69 if(error)
70 {
71 LOGE("OsclBase::Init error %d", error);
72 return false;
73 }
74 error = OsclErrorTrap::Init();
75 if(error)
76 {
77 LOGE("OsclErrorTrap::Init error %d", error);
78 return false;
79 }
80 OsclMem::Init();
81 PVLogger::Init();
82
83 void *data = &ptkey;
84 error = pthread_setspecific(ptkey,data);
85 if(error)
86 {
87 LOGE("pthread_setspecific error %d", error);
88 return false;
89 }
90 #if (PVLOGGER_INST_LEVEL > 0)
91 PVLoggerConfigFile obj;
92 if(obj.IsLoggerConfigFilePresent())
93 {
94 obj.SetLoggerSettings();
95 }
96 #endif
97 }
98 return true;
99 }
100
101
UninitializeForThread()102 void UninitializeForThread() {
103 PVLogger::Cleanup();
104 OsclMem::Cleanup();
105 OsclErrorTrap::Cleanup();
106 OsclBase::Cleanup();
107 // In case this didn't get called from keydestructor(), set the key
108 // to NULL for this thread, which prevents the keydestructor() from
109 // running once the thread actually exits.
110 void *data = NULL;
111 pthread_setspecific(ptkey,data);
112 }
113
114
115