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:
@@ -416,12 +416,23 @@ void cwdebug_backtrace(int n)
|
|||||||
#elif defined(DEBUG_CURLIO)
|
#elif defined(DEBUG_CURLIO)
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "aithreadid.h"
|
||||||
|
|
||||||
namespace debug
|
namespace debug
|
||||||
{
|
{
|
||||||
|
|
||||||
libcwd_do_type const libcw_do;
|
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)
|
std::ostream& operator<<(std::ostream& os, Indent::print_nt)
|
||||||
{
|
{
|
||||||
@@ -430,6 +441,19 @@ std::ostream& operator<<(std::ostream& os, Indent::print_nt)
|
|||||||
return os;
|
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)
|
std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s)
|
||||||
{
|
{
|
||||||
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };
|
static char const c2s_tab[7] = { 'a', 'b', 't', 'n', 'v', 'f', 'r' };
|
||||||
|
|||||||
@@ -29,14 +29,13 @@
|
|||||||
|
|
||||||
#ifdef DEBUG_CURLIO
|
#ifdef DEBUG_CURLIO
|
||||||
|
|
||||||
#include "aithreadid.h"
|
|
||||||
|
|
||||||
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
|
// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
|
||||||
// some of the cwd macro's with something that generates viewer
|
// some of the cwd macro's with something that generates viewer
|
||||||
// specific debug output. Note that this generates a LOT of
|
// specific debug output. Note that this generates a LOT of
|
||||||
// output and should not normally be defined.
|
// output and should not normally be defined.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "llpreprocessor.h"
|
||||||
|
|
||||||
namespace debug {
|
namespace debug {
|
||||||
namespace libcwd {
|
namespace libcwd {
|
||||||
@@ -49,6 +48,7 @@ struct buf2str {
|
|||||||
|
|
||||||
} // namespace libcwd
|
} // namespace libcwd
|
||||||
|
|
||||||
|
enum print_thread_id_t { print_thread_id };
|
||||||
inline void init() { }
|
inline void init() { }
|
||||||
struct libcwd_do_type {
|
struct libcwd_do_type {
|
||||||
void on() const { }
|
void on() const { }
|
||||||
@@ -56,14 +56,15 @@ struct libcwd_do_type {
|
|||||||
extern LL_COMMON_API libcwd_do_type const libcw_do;
|
extern LL_COMMON_API libcwd_do_type const libcw_do;
|
||||||
struct Indent {
|
struct Indent {
|
||||||
int M_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 };
|
enum LL_COMMON_API print_nt { print };
|
||||||
LL_COMMON_API Indent(int indent) : M_indent(indent) { S_indentation += M_indent; }
|
LL_COMMON_API Indent(int indent);
|
||||||
LL_COMMON_API ~Indent() { S_indentation -= M_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, 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, Indent::print_nt);
|
||||||
|
extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
|
||||||
|
|
||||||
namespace dc {
|
namespace dc {
|
||||||
|
|
||||||
@@ -87,13 +88,13 @@ extern LL_COMMON_API fake_channel const notice;
|
|||||||
} // namespace debug
|
} // namespace debug
|
||||||
|
|
||||||
#define Debug(x) do { using namespace debug; x; } while(0)
|
#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) \
|
#define DoutEntering(a, b) \
|
||||||
int __slviewer_debug_indentation = 2; \
|
int __slviewer_debug_indentation = 2; \
|
||||||
{ \
|
{ \
|
||||||
using namespace debug; \
|
using namespace debug; \
|
||||||
if ((a).mOn) \
|
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 \
|
else \
|
||||||
__slviewer_debug_indentation = 0; \
|
__slviewer_debug_indentation = 0; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
* - Initial version, written by Aleric Inglewood @ SL
|
* - Initial version, written by Aleric Inglewood @ SL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sys.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include "aithreadid.h"
|
#include "aithreadid.h"
|
||||||
@@ -36,7 +35,7 @@ AIThreadID const AIThreadID::sNone(AIThreadID::none);
|
|||||||
apr_os_thread_t AIThreadID::sMainThreadID;
|
apr_os_thread_t AIThreadID::sMainThreadID;
|
||||||
apr_os_thread_t const AIThreadID::undefinedID = (apr_os_thread_t)-1;
|
apr_os_thread_t const AIThreadID::undefinedID = (apr_os_thread_t)-1;
|
||||||
#ifndef LL_DARWIN
|
#ifndef LL_DARWIN
|
||||||
apr_os_thread_t CWD_TLS AIThreadID::lCurrentThread;
|
apr_os_thread_t ll_thread_local AIThreadID::lCurrentThread;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void AIThreadID::set_main_thread_id(void)
|
void AIThreadID::set_main_thread_id(void)
|
||||||
@@ -51,21 +50,27 @@ void AIThreadID::set_current_thread_id(void)
|
|||||||
#endif
|
#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)
|
std::ostream& operator<<(std::ostream& os, AIThreadID const& id)
|
||||||
{
|
{
|
||||||
return os << id.mID;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
#include <apr_portable.h> // apr_os_thread_t, apr_os_thread_current(), apr_os_thread_equal().
|
#include <apr_portable.h> // apr_os_thread_t, apr_os_thread_current(), apr_os_thread_equal().
|
||||||
#include <iosfwd> // std::ostream.
|
#include <iosfwd> // std::ostream.
|
||||||
#include "llpreprocessor.h" // LL_COMMON_API, LL_COMMON_API_TLS
|
#include "llpreprocessor.h" // LL_COMMON_API, LL_COMMON_API_TLS
|
||||||
#include "llerror.h"
|
|
||||||
|
|
||||||
// Lightweight wrapper around apr_os_thread_t.
|
// 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.
|
// 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 sMainThreadID;
|
||||||
static LL_COMMON_API apr_os_thread_t const undefinedID;
|
static LL_COMMON_API apr_os_thread_t const undefinedID;
|
||||||
#ifndef LL_DARWIN
|
#ifndef LL_DARWIN
|
||||||
static LL_COMMON_API_TLS apr_os_thread_t lCurrentThread;
|
static ll_thread_local apr_os_thread_t lCurrentThread;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
static LL_COMMON_API AIThreadID const sNone;
|
static LL_COMMON_API AIThreadID const sNone;
|
||||||
enum undefined_thread_t { none };
|
enum undefined_thread_t { none };
|
||||||
enum dout_print_t { DoutPrint };
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AIThreadID(void) : mID(apr_os_thread_current()) { }
|
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 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, 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_main_thread_id(void); // Called once to set sMainThreadID.
|
||||||
static void set_current_thread_id(void); // Called once for every thread to set lCurrentThread.
|
static void set_current_thread_id(void); // Called once for every thread to set lCurrentThread.
|
||||||
#ifdef LL_DARWIN
|
#ifdef LL_DARWIN
|
||||||
@@ -70,9 +67,15 @@ public:
|
|||||||
bool equals_current_thread(void) const { return apr_os_thread_equal(mID, apr_os_thread_current()); }
|
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); }
|
static bool in_main_thread(void) { return apr_os_thread_equal(apr_os_thread_current(), sMainThreadID); }
|
||||||
#else
|
#else
|
||||||
void reset(void) { mID = lCurrentThread; }
|
LL_COMMON_API void reset(void);
|
||||||
bool equals_current_thread(void) const { return apr_os_thread_equal(mID, lCurrentThread); }
|
LL_COMMON_API bool equals_current_thread(void) const;
|
||||||
static bool in_main_thread(void) { return apr_os_thread_equal(lCurrentThread, sMainThreadID); }
|
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
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
// In other words, it's safe for any thread to create a (sub)pool, independent of who
|
||||||
// owns the parent pool.
|
// owns the parent pool.
|
||||||
mOwner.reset();
|
mOwner.reset_inline();
|
||||||
#else
|
#else
|
||||||
mOwner = mParent->mOwner;
|
mOwner = mParent->mOwner;
|
||||||
llassert(mOwner.equals_current_thread());
|
llassert(mOwner.equals_current_thread_inline());
|
||||||
#endif
|
#endif
|
||||||
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
|
apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool);
|
||||||
llassert_always(apr_pool_create_status == APR_SUCCESS);
|
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
|
// 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,
|
// the parent may destruct us, since that is the pool that is still alive,
|
||||||
// possibly being used by others and being altered here.
|
// 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
|
#endif
|
||||||
apr_pool_t* pool = mPool;
|
apr_pool_t* pool = mPool;
|
||||||
mPool = NULL; // Mark that we are BEING destructed.
|
mPool = NULL; // Mark that we are BEING destructed.
|
||||||
|
|||||||
@@ -198,12 +198,9 @@
|
|||||||
// Darwin does not support thread-local data.
|
// Darwin does not support thread-local data.
|
||||||
#ifndef LL_DARWIN
|
#ifndef LL_DARWIN
|
||||||
#if LL_WINDOWS
|
#if LL_WINDOWS
|
||||||
// On windows, thread-local data is automatically exported.
|
#define ll_thread_local __declspec(thread)
|
||||||
#define LL_COMMON_API_TLS __declspec(thread)
|
|
||||||
#define CWD_TLS __declspec(thread)
|
|
||||||
#else // Linux
|
#else // Linux
|
||||||
#define LL_COMMON_API_TLS LL_COMMON_API __thread
|
#define ll_thread_local __thread
|
||||||
#define CWD_TLS __thread
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void LLRefCount::ref() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
mMutex.lock() ;
|
mMutex.lock() ;
|
||||||
mLockedThreadID.reset();
|
mLockedThreadID.reset_inline();
|
||||||
|
|
||||||
mRef++;
|
mRef++;
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ S32 LLRefCount::unref() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
mMutex.lock() ;
|
mMutex.lock() ;
|
||||||
mLockedThreadID.reset();
|
mLockedThreadID.reset_inline();
|
||||||
|
|
||||||
llassert(mRef >= 1);
|
llassert(mRef >= 1);
|
||||||
if (0 == --mRef)
|
if (0 == --mRef)
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ LLAtomicS32 LLThread::sRunning = 0;
|
|||||||
|
|
||||||
LL_COMMON_API void assert_main_thread()
|
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;
|
llerrs << "Illegal execution outside main thread." << llendl;
|
||||||
}
|
}
|
||||||
@@ -407,12 +407,12 @@ LLMutexBase::LLMutexBase() :
|
|||||||
|
|
||||||
bool LLMutexBase::isSelfLocked() const
|
bool LLMutexBase::isSelfLocked() const
|
||||||
{
|
{
|
||||||
return mLockingThread.equals_current_thread();
|
return mLockingThread.equals_current_thread_inline();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLMutexBase::lock()
|
void LLMutexBase::lock()
|
||||||
{
|
{
|
||||||
if (mLockingThread.equals_current_thread())
|
if (mLockingThread.equals_current_thread_inline())
|
||||||
{ //redundant lock
|
{ //redundant lock
|
||||||
mCount++;
|
mCount++;
|
||||||
return;
|
return;
|
||||||
@@ -420,12 +420,12 @@ void LLMutexBase::lock()
|
|||||||
|
|
||||||
apr_thread_mutex_lock(mAPRMutexp);
|
apr_thread_mutex_lock(mAPRMutexp);
|
||||||
|
|
||||||
mLockingThread.reset();
|
mLockingThread.reset_inline();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLMutexBase::tryLock()
|
bool LLMutexBase::tryLock()
|
||||||
{
|
{
|
||||||
if (mLockingThread.equals_current_thread())
|
if (mLockingThread.equals_current_thread_inline())
|
||||||
{ //redundant lock
|
{ //redundant lock
|
||||||
mCount++;
|
mCount++;
|
||||||
return true;
|
return true;
|
||||||
@@ -433,7 +433,7 @@ bool LLMutexBase::tryLock()
|
|||||||
bool success = !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp));
|
bool success = !APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp));
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
mLockingThread.reset();
|
mLockingThread.reset_inline();
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -441,7 +441,7 @@ bool LLMutexBase::tryLock()
|
|||||||
// non-blocking, but does do a lock/unlock so not free
|
// non-blocking, but does do a lock/unlock so not free
|
||||||
bool LLMutexBase::isLocked() const
|
bool LLMutexBase::isLocked() const
|
||||||
{
|
{
|
||||||
if (mLockingThread.equals_current_thread())
|
if (mLockingThread.equals_current_thread_inline())
|
||||||
return false; // A call to lock() won't block.
|
return false; // A call to lock() won't block.
|
||||||
if (APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)))
|
if (APR_STATUS_IS_EBUSY(apr_thread_mutex_trylock(mAPRMutexp)))
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user