Index: third_party/crazy_linker/crazy_linker/src/crazy_linker_thread.cpp |
diff --git a/third_party/crazy_linker/crazy_linker/src/crazy_linker_thread.cpp b/third_party/crazy_linker/crazy_linker/src/crazy_linker_thread.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e49b9dff274363c140cbd56e06090af2bd5e35e5 |
--- /dev/null |
+++ b/third_party/crazy_linker/crazy_linker/src/crazy_linker_thread.cpp |
@@ -0,0 +1,84 @@ |
+// Copyright (c) 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "crazy_linker_thread.h" |
+ |
+#include <pthread.h> |
+#include <stdio.h> |
+#include <stdlib.h> |
+ |
+namespace { |
+ |
+static pthread_key_t s_thread_key; |
+static pthread_once_t s_once = PTHREAD_ONCE_INIT; |
+ |
+static void ThreadDataDestroy(void* data) { |
+ free(data); |
+} |
+ |
+static void InitThreadKey() { |
+ pthread_key_create(&s_thread_key, ThreadDataDestroy); |
+} |
+ |
+} // namespace |
+ |
+namespace crazy { |
+ |
+void ThreadData::Init() { |
+ dlerror_ = dlerror_buffers_[0]; |
+ dlerror_[0] = '\0'; |
+} |
+ |
+void ThreadData::SwapErrorBuffers() { |
+ if (dlerror_ == dlerror_buffers_[0]) |
+ dlerror_ = dlerror_buffers_[1]; |
+ else |
+ dlerror_ = dlerror_buffers_[0]; |
+ dlerror_[0] = '\0'; |
+} |
+ |
+void ThreadData::SetErrorArgs(const char* fmt, va_list args) { |
+ if (fmt == NULL) { |
+ dlerror_[0] = '\0'; |
+ return; |
+ } |
+ vsnprintf(dlerror_, kBufferSize, fmt, args); |
+} |
+ |
+void ThreadData::AppendErrorArgs(const char* fmt, va_list args) { |
+ if (fmt == NULL) |
+ return; |
+ size_t len = strlen(dlerror_); |
+ vsnprintf(dlerror_ + len, kBufferSize - len, fmt, args); |
+} |
+ |
+ThreadData* GetThreadDataFast() { |
+ return reinterpret_cast<ThreadData*>(pthread_getspecific(s_thread_key)); |
+} |
+ |
+ThreadData* GetThreadData() { |
+ pthread_once(&s_once, InitThreadKey); |
+ ThreadData* data = GetThreadDataFast(); |
+ if (!data) { |
+ data = reinterpret_cast<ThreadData*>(calloc(sizeof(*data), 1)); |
+ data->Init(); |
+ pthread_setspecific(s_thread_key, data); |
+ } |
+ return data; |
+} |
+ |
+// Set the linker error string for the current thread. |
+void SetLinkerErrorString(const char* str) { |
+ GetThreadData()->SetError(str); |
+} |
+ |
+// Set the formatted linker error for the current thread. |
+void SetLinkerError(const char* fmt, ...) { |
+ va_list args; |
+ va_start(args, fmt); |
+ GetThreadData()->SetErrorArgs(fmt, args); |
+ va_end(args); |
+} |
+ |
+} // namespace crazy |