Windows compile and linker fixes.

* Do not include aithreadid.h from debug.h, because the latter is
  included everywhere (from linden_common.h) and aithreadid.h is
  heavy (includes among others windows.h).
* On windows, thread local members cannot be exported.
This commit is contained in:
Aleric Inglewood
2012-08-11 03:23:31 +02:00
parent 70717cb6c8
commit 3469d65f95
8 changed files with 78 additions and 48 deletions

View File

@@ -416,12 +416,23 @@ void cwdebug_backtrace(int n)
#elif defined(DEBUG_CURLIO)
#include "debug.h"
#include "aithreadid.h"
namespace debug
{
libcwd_do_type const libcw_do;
CWD_TLS int Indent::S_indentation;
ll_thread_local int Indent::S_indentation;
Indent::Indent(int indent) : M_indent(indent)
{
S_indentation += M_indent;
}
Indent::~Indent()
{
S_indentation -= M_indent;
}
std::ostream& operator<<(std::ostream& os, Indent::print_nt)
{
@@ -430,6 +441,19 @@ std::ostream& operator<<(std::ostream& os, Indent::print_nt)
return os;
}
std::ostream& operator<<(std::ostream& os, print_thread_id_t)
{
if (!AIThreadID::in_main_thread_inline())
{
#ifdef LL_DARWIN
os << std::hex << (size_t)apr_os_thread_current() << std::dec << ' ';
#else
os << std::hex << (size_t)AIThreadID::getCurrentThread_inline() << std::dec << ' ';
#endif
}
return os;
}
std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s)
{
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };

View File

@@ -29,14 +29,13 @@
#ifdef DEBUG_CURLIO
#include "aithreadid.h"
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
// some of the cwd macro's with something that generates viewer
// specific debug output. Note that this generates a LOT of
// output and should not normally be defined.
#include <string>
#include "llpreprocessor.h"
namespace debug {
namespace libcwd {
@@ -49,6 +48,7 @@ struct buf2str {
} // namespace libcwd
enum print_thread_id_t { print_thread_id };
inline void init() { }
struct libcwd_do_type {
void on() const { }
@@ -56,14 +56,15 @@ struct libcwd_do_type {
extern LL_COMMON_API libcwd_do_type const libcw_do;
struct Indent {
int M_indent;
static LL_COMMON_API_TLS int S_indentation;
static ll_thread_local int S_indentation;
enum LL_COMMON_API print_nt { print };
LL_COMMON_API Indent(int indent) : M_indent(indent) { S_indentation += M_indent; }
LL_COMMON_API ~Indent() { S_indentation -= M_indent; }
LL_COMMON_API Indent(int indent);
LL_COMMON_API ~Indent();
};
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
namespace dc {
@@ -87,13 +88,13 @@ extern LL_COMMON_API fake_channel const notice;
} // namespace debug
#define Debug(x) do { using namespace debug; x; } while(0)
#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << AIThreadID::DoutPrint << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
#define Dout(a, b) do { using namespace debug; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
#define DoutEntering(a, b) \
int __slviewer_debug_indentation = 2; \
{ \
using namespace debug; \
if ((a).mOn) \
llinfos_nf << AIThreadID::DoutPrint << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
else \
__slviewer_debug_indentation = 0; \
} \

View File

@@ -27,7 +27,6 @@
* - Initial version, written by Aleric Inglewood @ SL
*/
#include "sys.h"
#include <iostream>
#include <iomanip>
#include "aithreadid.h"
@@ -36,7 +35,7 @@ AIThreadID const AIThreadID::sNone(AIThreadID::none);
apr_os_thread_t AIThreadID::sMainThreadID;
apr_os_thread_t const AIThreadID::undefinedID = (apr_os_thread_t)-1;
#ifndef LL_DARWIN
apr_os_thread_t CWD_TLS AIThreadID::lCurrentThread;
apr_os_thread_t ll_thread_local AIThreadID::lCurrentThread;
#endif
void AIThreadID::set_main_thread_id(void)
@@ -51,21 +50,27 @@ void AIThreadID::set_current_thread_id(void)
#endif
}
void AIThreadID::reset(void)
{
mID = lCurrentThread;
}
bool AIThreadID::equals_current_thread(void) const
{
return apr_os_thread_equal(mID, lCurrentThread);
}
bool AIThreadID::in_main_thread(void)
{
return apr_os_thread_equal(lCurrentThread, sMainThreadID);
}
apr_os_thread_t AIThreadID::getCurrentThread(void)
{
return lCurrentThread;
}
std::ostream& operator<<(std::ostream& os, AIThreadID const& id)
{
return os << id.mID;
}
std::ostream& operator<<(std::ostream& os, AIThreadID::dout_print_t)
{
if (!AIThreadID::in_main_thread())
{
#ifdef LL_DARWIN
os << std::hex << (size_t)apr_os_thread_current() << std::dec << ' ';
#else
os << std::hex << (size_t)AIThreadID::lCurrentThread << std::dec << ' ';
#endif
}
return os;
}

View File

@@ -34,7 +34,6 @@
#include <apr_portable.h> // apr_os_thread_t, apr_os_thread_current(), apr_os_thread_equal().
#include <iosfwd> // std::ostream.
#include "llpreprocessor.h" // LL_COMMON_API, LL_COMMON_API_TLS
#include "llerror.h"
// Lightweight wrapper around apr_os_thread_t.
// This class introduces no extra assembly code after optimization; it's only intend is to provide type-safety.
@@ -45,12 +44,11 @@ private:
static LL_COMMON_API apr_os_thread_t sMainThreadID;
static LL_COMMON_API apr_os_thread_t const undefinedID;
#ifndef LL_DARWIN
static LL_COMMON_API_TLS apr_os_thread_t lCurrentThread;
static ll_thread_local apr_os_thread_t lCurrentThread;
#endif
public:
static LL_COMMON_API AIThreadID const sNone;
enum undefined_thread_t { none };
enum dout_print_t { DoutPrint };
public:
AIThreadID(void) : mID(apr_os_thread_current()) { }
@@ -62,7 +60,6 @@ public:
friend LL_COMMON_API bool operator==(AIThreadID const& id1, AIThreadID const& id2) { return apr_os_thread_equal(id1.mID, id2.mID); }
friend LL_COMMON_API bool operator!=(AIThreadID const& id1, AIThreadID const& id2) { return !apr_os_thread_equal(id1.mID, id2.mID); }
friend LL_COMMON_API std::ostream& operator<<(std::ostream& os, AIThreadID const& id);
friend LL_COMMON_API std::ostream& operator<<(std::ostream& os, dout_print_t);
static void set_main_thread_id(void); // Called once to set sMainThreadID.
static void set_current_thread_id(void); // Called once for every thread to set lCurrentThread.
#ifdef LL_DARWIN
@@ -70,9 +67,15 @@ public:
bool equals_current_thread(void) const { return apr_os_thread_equal(mID, apr_os_thread_current()); }
static bool in_main_thread(void) { return apr_os_thread_equal(apr_os_thread_current(), sMainThreadID); }
#else
void reset(void) { mID = lCurrentThread; }
bool equals_current_thread(void) const { return apr_os_thread_equal(mID, lCurrentThread); }
static bool in_main_thread(void) { return apr_os_thread_equal(lCurrentThread, sMainThreadID); }
LL_COMMON_API void reset(void);
LL_COMMON_API bool equals_current_thread(void) const;
LL_COMMON_API static bool in_main_thread(void);
LL_COMMON_API static apr_os_thread_t getCurrentThread(void);
// The *_inline variants cannot be exported because they access a thread-local member.
void reset_inline(void) { mID = lCurrentThread; }
bool equals_current_thread_inline(void) const { return apr_os_thread_equal(mID, lCurrentThread); }
static bool in_main_thread_inline(void) { return apr_os_thread_equal(lCurrentThread, sMainThreadID); }
static apr_os_thread_t getCurrentThread_inline(void) { return lCurrentThread; }
#endif
};

View File

@@ -60,10 +60,10 @@ void LLAPRPool::create(LLAPRPool& parent)
//
// In other words, it's safe for any thread to create a (sub)pool, independent of who
// owns the parent pool.
mOwner.reset();
mOwner.reset_inline();
#else
mOwner = mParent->mOwner;
llassert(mOwner.equals_current_thread());
llassert(mOwner.equals_current_thread_inline());
#endif
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
llassert_always(apr_pool_create_status == APR_SUCCESS);
@@ -83,7 +83,7 @@ void LLAPRPool::destroy(void)
// of course. Otherwise, if we are a subpool, only the thread that owns
// the parent may destruct us, since that is the pool that is still alive,
// possibly being used by others and being altered here.
llassert(!mParent || mParent->mOwner.equals_current_thread());
llassert(!mParent || mParent->mOwner.equals_current_thread_inline());
#endif
apr_pool_t* pool = mPool;
mPool = NULL; // Mark that we are BEING destructed.

View File

@@ -198,12 +198,9 @@
// Darwin does not support thread-local data.
#ifndef LL_DARWIN
#if LL_WINDOWS
// On windows, thread-local data is automatically exported.
#define LL_COMMON_API_TLS __declspec(thread)
#define CWD_TLS __declspec(thread)
#define ll_thread_local __declspec(thread)
#else // Linux
#define LL_COMMON_API_TLS LL_COMMON_API __thread
#define CWD_TLS __thread
#define ll_thread_local __thread
#endif
#endif

View File

@@ -75,7 +75,7 @@ void LLRefCount::ref() const
}
mMutex.lock() ;
mLockedThreadID.reset();
mLockedThreadID.reset_inline();
mRef++;
@@ -96,7 +96,7 @@ S32 LLRefCount::unref() const
}
mMutex.lock() ;
mLockedThreadID.reset();
mLockedThreadID.reset_inline();
llassert(mRef >= 1);
if (0 == --mRef)

View File

@@ -72,7 +72,7 @@ LLAtomicS32 LLThread::sRunning = 0;
LL_COMMON_API void assert_main_thread()
{
if (!AIThreadID::in_main_thread())
if (!AIThreadID::in_main_thread_inline())
{
llerrs << "Illegal execution outside main thread." << llendl;
}
@@ -407,12 +407,12 @@ LLMutexBase::LLMutexBase() :
bool LLMutexBase::isSelfLocked() const
{
return mLockingThread.equals_current_thread();
return mLockingThread.equals_current_thread_inline();
}
void LLMutexBase::lock()
{
if (mLockingThread.equals_current_thread())
if (mLockingThread.equals_current_thread_inline())
{ //redundant lock
mCount++;
return;
@@ -420,12 +420,12 @@ void LLMutexBase::lock()
apr_thread_mutex_lock(mAPRMutexp);
mLockingThread.reset();
mLockingThread.reset_inline();
}
bool LLMutexBase::tryLock()
{
if (mLockingThread.equals_current_thread())
if (mLockingThread.equals_current_thread_inline())
{ //redundant lock
mCount++;
return true;
@@ -433,7 +433,7 @@ bool LLMutexBase::tryLock()
bool success = !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp));
if (success)
{
mLockingThread.reset();
mLockingThread.reset_inline();
}
return success;
}
@@ -441,7 +441,7 @@ bool LLMutexBase::tryLock()
// non-blocking, but does do a lock/unlock so not free
bool LLMutexBase::isLocked() const
{
if (mLockingThread.equals_current_thread())
if (mLockingThread.equals_current_thread_inline())
return false; // A call to lock() won't block.
if (APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)))
return true;