1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,210 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include <stdio.h> 1.9 +#include <string.h> 1.10 +#include <stdarg.h> 1.11 + 1.12 +#include "CSFLog.h" 1.13 +#include "base/basictypes.h" 1.14 + 1.15 +#include <map> 1.16 +#include "cpr_threads.h" 1.17 +#include "prrwlock.h" 1.18 +#include "prthread.h" 1.19 +#include "nsThreadUtils.h" 1.20 +#ifndef WIN32 1.21 +#include <pthread.h> 1.22 +#endif 1.23 +#ifdef OS_MACOSX 1.24 +#include <dlfcn.h> 1.25 +#endif 1.26 +#ifdef OS_LINUX 1.27 +#include <sys/prctl.h> 1.28 +#endif 1.29 + 1.30 +static PRLogModuleInfo *gLogModuleInfo = nullptr; 1.31 + 1.32 +PRLogModuleInfo *GetSignalingLogInfo() 1.33 +{ 1.34 + if (gLogModuleInfo == nullptr) 1.35 + gLogModuleInfo = PR_NewLogModule("signaling"); 1.36 + 1.37 + return gLogModuleInfo; 1.38 +} 1.39 + 1.40 +static PRLogModuleInfo *gWebRTCLogModuleInfo = nullptr; 1.41 +int gWebrtcTraceLoggingOn = 0; 1.42 + 1.43 +PRLogModuleInfo *GetWebRTCLogInfo() 1.44 +{ 1.45 + if (gWebRTCLogModuleInfo == nullptr) 1.46 + gWebRTCLogModuleInfo = PR_NewLogModule("webrtc_trace"); 1.47 + 1.48 + return gWebRTCLogModuleInfo; 1.49 +} 1.50 + 1.51 +extern "C" { 1.52 + void CSFLogRegisterThread(const cprThread_t thread); 1.53 + void CSFLogUnregisterThread(const cprThread_t thread); 1.54 +#ifndef WIN32 1.55 + pthread_t cprGetThreadId(cprThread_t thread); 1.56 +#endif 1.57 +} 1.58 + 1.59 +#ifdef WIN32 1.60 +typedef unsigned int thread_key_t; 1.61 +#else 1.62 +typedef pthread_t thread_key_t; 1.63 +#endif 1.64 +static PRRWLock *maplock = PR_NewRWLock(0,"thread map"); 1.65 +typedef std::map<thread_key_t,const cpr_thread_t*> threadMap_t; 1.66 +static threadMap_t threadMap; 1.67 + 1.68 +void CSFLogRegisterThread(const cprThread_t thread) { 1.69 + const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread); 1.70 + thread_key_t key; 1.71 +#ifdef WIN32 1.72 + key = t->threadId; 1.73 +#else 1.74 + key = cprGetThreadId(thread); 1.75 +#endif 1.76 + 1.77 + CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log", 1.78 + "Registering new thread with logging system: %s", t->name); 1.79 + PR_RWLock_Wlock(maplock); 1.80 + threadMap[key] = t; 1.81 + PR_RWLock_Unlock(maplock); 1.82 +} 1.83 + 1.84 +void CSFLogUnregisterThread(const cprThread_t thread) { 1.85 + const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread); 1.86 + thread_key_t key; 1.87 +#ifdef WIN32 1.88 + key = t->threadId; 1.89 +#else 1.90 + key = cprGetThreadId(thread); 1.91 +#endif 1.92 + CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log", 1.93 + "Unregistering thread from logging system: %s", t->name); 1.94 + PR_RWLock_Wlock(maplock); 1.95 + threadMap.erase(key); 1.96 + PR_RWLock_Unlock(maplock); 1.97 +} 1.98 + 1.99 +const char *CSFCurrentThreadName() { 1.100 + const char *name = nullptr; 1.101 +#ifdef WIN32 1.102 + thread_key_t key = GetCurrentThreadId(); 1.103 +#else 1.104 + thread_key_t key = pthread_self(); 1.105 +#endif 1.106 + PR_RWLock_Rlock(maplock); 1.107 + threadMap_t::iterator i = threadMap.find(key); 1.108 + if (i != threadMap.end()) { 1.109 + name = i->second->name; 1.110 + } 1.111 + PR_RWLock_Unlock(maplock); 1.112 + return name; 1.113 +} 1.114 + 1.115 +#ifdef OS_MACOSX 1.116 +// pthread_getname_np isn't available on all versions of OS X, so 1.117 +// we need to load it in dynamically and check for its presence 1.118 +static int (*dynamic_pthread_getname_np)(pthread_t,char*,size_t); 1.119 +bool init_pthread_getname() { 1.120 + *reinterpret_cast<void**>(&dynamic_pthread_getname_np) = 1.121 + dlsym(RTLD_DEFAULT, "pthread_getname_np"); 1.122 + return dynamic_pthread_getname_np; 1.123 +} 1.124 +static bool have_pthread_getname_np = init_pthread_getname(); 1.125 +#endif 1.126 + 1.127 +void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args) 1.128 +{ 1.129 +#ifdef STDOUT_LOGGING 1.130 + printf("%s\n:",tag); 1.131 + vprintf(format, args); 1.132 +#else 1.133 + 1.134 + PRLogModuleLevel level = static_cast<PRLogModuleLevel>(priority); 1.135 + 1.136 + GetSignalingLogInfo(); 1.137 + 1.138 + // Skip doing any of this work if we're not logging the indicated level... 1.139 + if (!PR_LOG_TEST(gLogModuleInfo,level)) { 1.140 + return; 1.141 + } 1.142 + 1.143 + // Trim the path component from the filename 1.144 + const char *lastSlash = sourceFile; 1.145 + while (*sourceFile) { 1.146 + if (*sourceFile == '/' || *sourceFile == '\\') { 1.147 + lastSlash = sourceFile; 1.148 + } 1.149 + sourceFile++; 1.150 + } 1.151 + sourceFile = lastSlash; 1.152 + if (*sourceFile == '/' || *sourceFile == '\\') { 1.153 + sourceFile++; 1.154 + } 1.155 + 1.156 +#define MAX_MESSAGE_LENGTH 1024 1.157 + char message[MAX_MESSAGE_LENGTH]; 1.158 + char buffer[64] = ""; 1.159 + 1.160 + const char *threadName = CSFCurrentThreadName(); 1.161 + 1.162 + // Check if we're the main thread... 1.163 + if (!threadName && NS_IsMainThread()) { 1.164 + threadName = "main"; 1.165 + } 1.166 + 1.167 + // If null, the name wasn't set up by CPR -- try NSPR 1.168 + if (!threadName) { 1.169 + threadName = PR_GetThreadName(PR_GetCurrentThread()); 1.170 + } 1.171 + 1.172 + // If not NSPR, it might be from some other imported library that uses 1.173 + // one of the variety of non-portable means of naming threads. 1.174 +#ifdef OS_LINUX 1.175 + if (!threadName && 1.176 + !prctl(PR_GET_NAME,reinterpret_cast<uintptr_t>(buffer),0,0,0)) { 1.177 + buffer[16]='\0'; 1.178 + if (buffer[0] != '\0') { 1.179 + threadName = buffer; 1.180 + } 1.181 + } 1.182 +#endif 1.183 +#ifdef OS_MACOSX 1.184 + if (!threadName && have_pthread_getname_np) { 1.185 + dynamic_pthread_getname_np(pthread_self(), buffer, sizeof(buffer)); 1.186 + if (buffer[0] != '\0') { 1.187 + threadName = buffer; 1.188 + } 1.189 + } 1.190 +#endif 1.191 + 1.192 + // If we can't find it anywhere, use a blank string 1.193 + if (!threadName) { 1.194 + threadName = ""; 1.195 + } 1.196 + 1.197 + vsnprintf(message, MAX_MESSAGE_LENGTH, format, args); 1.198 + PR_LOG(gLogModuleInfo, level, ("[%s|%s] %s:%d: %s", 1.199 + threadName, tag, sourceFile, sourceLine, 1.200 + message)); 1.201 +#endif 1.202 + 1.203 +} 1.204 + 1.205 +void CSFLog( CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, ...) 1.206 +{ 1.207 + va_list ap; 1.208 + va_start(ap, format); 1.209 + 1.210 + CSFLogV(priority, sourceFile, sourceLine, tag, format, ap); 1.211 + va_end(ap); 1.212 +} 1.213 +