media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp

branch
TOR_BUG_9701
changeset 10
ac0c01689b40
equal deleted inserted replaced
-1:000000000000 0:b1ab2bd4bd5f
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdarg.h>
8
9 #include "CSFLog.h"
10 #include "base/basictypes.h"
11
12 #include <map>
13 #include "cpr_threads.h"
14 #include "prrwlock.h"
15 #include "prthread.h"
16 #include "nsThreadUtils.h"
17 #ifndef WIN32
18 #include <pthread.h>
19 #endif
20 #ifdef OS_MACOSX
21 #include <dlfcn.h>
22 #endif
23 #ifdef OS_LINUX
24 #include <sys/prctl.h>
25 #endif
26
27 static PRLogModuleInfo *gLogModuleInfo = nullptr;
28
29 PRLogModuleInfo *GetSignalingLogInfo()
30 {
31 if (gLogModuleInfo == nullptr)
32 gLogModuleInfo = PR_NewLogModule("signaling");
33
34 return gLogModuleInfo;
35 }
36
37 static PRLogModuleInfo *gWebRTCLogModuleInfo = nullptr;
38 int gWebrtcTraceLoggingOn = 0;
39
40 PRLogModuleInfo *GetWebRTCLogInfo()
41 {
42 if (gWebRTCLogModuleInfo == nullptr)
43 gWebRTCLogModuleInfo = PR_NewLogModule("webrtc_trace");
44
45 return gWebRTCLogModuleInfo;
46 }
47
48 extern "C" {
49 void CSFLogRegisterThread(const cprThread_t thread);
50 void CSFLogUnregisterThread(const cprThread_t thread);
51 #ifndef WIN32
52 pthread_t cprGetThreadId(cprThread_t thread);
53 #endif
54 }
55
56 #ifdef WIN32
57 typedef unsigned int thread_key_t;
58 #else
59 typedef pthread_t thread_key_t;
60 #endif
61 static PRRWLock *maplock = PR_NewRWLock(0,"thread map");
62 typedef std::map<thread_key_t,const cpr_thread_t*> threadMap_t;
63 static threadMap_t threadMap;
64
65 void CSFLogRegisterThread(const cprThread_t thread) {
66 const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
67 thread_key_t key;
68 #ifdef WIN32
69 key = t->threadId;
70 #else
71 key = cprGetThreadId(thread);
72 #endif
73
74 CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
75 "Registering new thread with logging system: %s", t->name);
76 PR_RWLock_Wlock(maplock);
77 threadMap[key] = t;
78 PR_RWLock_Unlock(maplock);
79 }
80
81 void CSFLogUnregisterThread(const cprThread_t thread) {
82 const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
83 thread_key_t key;
84 #ifdef WIN32
85 key = t->threadId;
86 #else
87 key = cprGetThreadId(thread);
88 #endif
89 CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
90 "Unregistering thread from logging system: %s", t->name);
91 PR_RWLock_Wlock(maplock);
92 threadMap.erase(key);
93 PR_RWLock_Unlock(maplock);
94 }
95
96 const char *CSFCurrentThreadName() {
97 const char *name = nullptr;
98 #ifdef WIN32
99 thread_key_t key = GetCurrentThreadId();
100 #else
101 thread_key_t key = pthread_self();
102 #endif
103 PR_RWLock_Rlock(maplock);
104 threadMap_t::iterator i = threadMap.find(key);
105 if (i != threadMap.end()) {
106 name = i->second->name;
107 }
108 PR_RWLock_Unlock(maplock);
109 return name;
110 }
111
112 #ifdef OS_MACOSX
113 // pthread_getname_np isn't available on all versions of OS X, so
114 // we need to load it in dynamically and check for its presence
115 static int (*dynamic_pthread_getname_np)(pthread_t,char*,size_t);
116 bool init_pthread_getname() {
117 *reinterpret_cast<void**>(&dynamic_pthread_getname_np) =
118 dlsym(RTLD_DEFAULT, "pthread_getname_np");
119 return dynamic_pthread_getname_np;
120 }
121 static bool have_pthread_getname_np = init_pthread_getname();
122 #endif
123
124 void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args)
125 {
126 #ifdef STDOUT_LOGGING
127 printf("%s\n:",tag);
128 vprintf(format, args);
129 #else
130
131 PRLogModuleLevel level = static_cast<PRLogModuleLevel>(priority);
132
133 GetSignalingLogInfo();
134
135 // Skip doing any of this work if we're not logging the indicated level...
136 if (!PR_LOG_TEST(gLogModuleInfo,level)) {
137 return;
138 }
139
140 // Trim the path component from the filename
141 const char *lastSlash = sourceFile;
142 while (*sourceFile) {
143 if (*sourceFile == '/' || *sourceFile == '\\') {
144 lastSlash = sourceFile;
145 }
146 sourceFile++;
147 }
148 sourceFile = lastSlash;
149 if (*sourceFile == '/' || *sourceFile == '\\') {
150 sourceFile++;
151 }
152
153 #define MAX_MESSAGE_LENGTH 1024
154 char message[MAX_MESSAGE_LENGTH];
155 char buffer[64] = "";
156
157 const char *threadName = CSFCurrentThreadName();
158
159 // Check if we're the main thread...
160 if (!threadName && NS_IsMainThread()) {
161 threadName = "main";
162 }
163
164 // If null, the name wasn't set up by CPR -- try NSPR
165 if (!threadName) {
166 threadName = PR_GetThreadName(PR_GetCurrentThread());
167 }
168
169 // If not NSPR, it might be from some other imported library that uses
170 // one of the variety of non-portable means of naming threads.
171 #ifdef OS_LINUX
172 if (!threadName &&
173 !prctl(PR_GET_NAME,reinterpret_cast<uintptr_t>(buffer),0,0,0)) {
174 buffer[16]='\0';
175 if (buffer[0] != '\0') {
176 threadName = buffer;
177 }
178 }
179 #endif
180 #ifdef OS_MACOSX
181 if (!threadName && have_pthread_getname_np) {
182 dynamic_pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
183 if (buffer[0] != '\0') {
184 threadName = buffer;
185 }
186 }
187 #endif
188
189 // If we can't find it anywhere, use a blank string
190 if (!threadName) {
191 threadName = "";
192 }
193
194 vsnprintf(message, MAX_MESSAGE_LENGTH, format, args);
195 PR_LOG(gLogModuleInfo, level, ("[%s|%s] %s:%d: %s",
196 threadName, tag, sourceFile, sourceLine,
197 message));
198 #endif
199
200 }
201
202 void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...)
203 {
204 va_list ap;
205 va_start(ap, format);
206
207 CSFLogV(priority, sourceFile, sourceLine, tag, format, ap);
208 va_end(ap);
209 }
210

mercurial