1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "crazy_linker_thread.h" 6 7 #include <pthread.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 namespace { 12 13 static pthread_key_t s_thread_key; 14 static pthread_once_t s_once = PTHREAD_ONCE_INIT; 15 16 static void ThreadDataDestroy(void* data) { free(data); } 17 18 static void InitThreadKey() { 19 pthread_key_create(&s_thread_key, ThreadDataDestroy); 20 } 21 22 } // namespace 23 24 namespace crazy { 25 26 void ThreadData::Init() { 27 dlerror_ = dlerror_buffers_[0]; 28 dlerror_[0] = '\0'; 29 } 30 31 void ThreadData::SwapErrorBuffers() { 32 if (dlerror_ == dlerror_buffers_[0]) 33 dlerror_ = dlerror_buffers_[1]; 34 else 35 dlerror_ = dlerror_buffers_[0]; 36 dlerror_[0] = '\0'; 37 } 38 39 void ThreadData::SetErrorArgs(const char* fmt, va_list args) { 40 if (fmt == NULL) { 41 dlerror_[0] = '\0'; 42 return; 43 } 44 vsnprintf(dlerror_, kBufferSize, fmt, args); 45 } 46 47 void ThreadData::AppendErrorArgs(const char* fmt, va_list args) { 48 if (fmt == NULL) 49 return; 50 size_t len = strlen(dlerror_); 51 vsnprintf(dlerror_ + len, kBufferSize - len, fmt, args); 52 } 53 54 ThreadData* GetThreadDataFast() { 55 return reinterpret_cast<ThreadData*>(pthread_getspecific(s_thread_key)); 56 } 57 58 ThreadData* GetThreadData() { 59 pthread_once(&s_once, InitThreadKey); 60 ThreadData* data = GetThreadDataFast(); 61 if (!data) { 62 data = reinterpret_cast<ThreadData*>(calloc(sizeof(*data), 1)); 63 data->Init(); 64 pthread_setspecific(s_thread_key, data); 65 } 66 return data; 67 } 68 69 // Set the linker error string for the current thread. 70 void SetLinkerErrorString(const char* str) { GetThreadData()->SetError(str); } 71 72 // Set the formatted linker error for the current thread. 73 void SetLinkerError(const char* fmt, ...) { 74 va_list args; 75 va_start(args, fmt); 76 GetThreadData()->SetErrorArgs(fmt, args); 77 va_end(args); 78 } 79 80 } // namespace crazy 81