| 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
|
|
|