summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorMonty Brandenberg <monty@lindenlab.com>2013-05-06 13:01:56 -0400
committerMonty Brandenberg <monty@lindenlab.com>2013-05-06 13:01:56 -0400
commit2a59fef6beff7144085ea98ede4a3b4300248d7f (patch)
tree96ac7748d02e437de34639a51772af2040ce7170 /indra/llcommon
parentf5e8457e4e4fad1d823c51d86c01fdc2ae08401c (diff)
parent291b38717805f7de41af447c651c5b91352d0a51 (diff)
Merge. Pull from /lindenlab/viewer-cat prior to push.
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llfile.cpp21
-rw-r--r--indra/llcommon/llsingleton.h101
-rw-r--r--indra/llcommon/llthread.h90
3 files changed, 82 insertions, 130 deletions
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index bc615ed39e..864b6e6975 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -853,7 +853,8 @@ llifstream::llifstream(const std::string& _Filename,
#if LL_WINDOWS
std::istream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -872,7 +873,8 @@ llifstream::llifstream(const char* _Filename,
#if LL_WINDOWS
std::istream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open(wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -917,8 +919,10 @@ bool llifstream::is_open() const
void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
- if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+
#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::in) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -927,6 +931,7 @@ void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
_Myios::clear();
}
#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
{
this->setstate(ios_base::failbit);
}
@@ -969,7 +974,8 @@ llofstream::llofstream(const std::string& _Filename,
#if LL_WINDOWS
std::ostream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -988,7 +994,8 @@ llofstream::llofstream(const char* _Filename,
#if LL_WINDOWS
std::ostream(&_M_filebuf)
{
- if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -1032,8 +1039,9 @@ bool llofstream::is_open() const
void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
{ // open a C stream with specified mode
- if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
#if LL_WINDOWS
+ llutf16string wideName = utf8str_to_utf16str( _Filename );
+ if (_M_filebuf.open( wideName.c_str(), _Mode | ios_base::out) == 0)
{
_Myios::setstate(ios_base::failbit);
}
@@ -1042,6 +1050,7 @@ void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
_Myios::clear();
}
#else
+ if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
{
this->setstate(ios_base::failbit);
}
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 550e3c0d20..40002313f1 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -61,6 +61,7 @@ class LLSingleton : private boost::noncopyable
private:
typedef enum e_init_state
{
+ UNINITIALIZED,
CONSTRUCTING,
INITIALIZING,
INITIALIZED,
@@ -68,23 +69,23 @@ private:
} EInitState;
// stores pointer to singleton instance
- // and tracks initialization state of singleton
- struct SingletonInstanceData
+ struct SingletonLifetimeManager
{
- EInitState mInitState;
- DERIVED_TYPE* mSingletonInstance;
-
- SingletonInstanceData()
- : mSingletonInstance(NULL),
- mInitState(CONSTRUCTING)
+ SingletonLifetimeManager()
+ {
+ construct();
+ }
+
+ static void construct()
{
- mSingletonInstance = new DERIVED_TYPE();
- mInitState = INITIALIZING;
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = new DERIVED_TYPE();
+ sData.mInitState = INITIALIZING;
}
- ~SingletonInstanceData()
+ ~SingletonLifetimeManager()
{
- if (mInitState != DELETED)
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
@@ -94,9 +95,8 @@ private:
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -121,42 +121,46 @@ public:
*/
static void deleteSingleton()
{
- delete getData().mSingletonInstance;
- getData().mSingletonInstance = NULL;
- getData().mInitState = DELETED;
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
- static SingletonInstanceData& getData()
- {
- // this is static to cache the lookup results
- static SingletonInstanceData sData;
- return sData;
- }
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getData();
+ static SingletonLifetimeManager sLifeTimeMgr;
- if (data.mInitState == CONSTRUCTING)
+ switch (sData.mInitState)
{
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ return NULL;
+ case CONSTRUCTING:
llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
- }
-
- if (data.mInitState == DELETED)
- {
- llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
- data.mSingletonInstance = new DERIVED_TYPE();
- data.mInitState = INITIALIZING;
- } // Fall into INITIALIZING case below
-
- if (data.mInitState == INITIALIZING)
- {
+ return NULL;
+ case INITIALIZING:
// go ahead and flag ourselves as initialized so we can be reentrant during initialization
- data.mInitState = INITIALIZED;
- data.mSingletonInstance->initSingleton();
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ SingletonLifetimeManager::construct();
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
}
-
- return data.mSingletonInstance;
+
+ return NULL;
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -170,18 +174,29 @@ public:
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return getData().mInitState == INITIALIZED;
+ return sData.mInitState == INITIALIZED;
}
// Has this singleton already been deleted?
// Use this to avoid accessing singletons from a static object's destructor
static bool destroyed()
{
- return getData().mInitState == DELETED;
+ return sData.mInitState == DELETED;
}
private:
+
virtual void initSingleton() {}
+
+ struct SingletonData
+ {
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
+ static SingletonData sData;
};
+template<typename T>
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
+
#endif
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index a6eb14db9d..f51d985b5f 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -225,7 +225,6 @@ void LLThread::unlockData()
// see llmemory.h for LLPointer<> definition
-#if (1) // Old code - see comment below
class LL_COMMON_API LLThreadSafeRefCount
{
public:
@@ -243,99 +242,28 @@ public:
LLThreadSafeRefCount(const LLThreadSafeRefCount&);
LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
{
- if (sMutex)
- {
- sMutex->lock();
- }
mRef = 0;
- if (sMutex)
- {
- sMutex->unlock();
- }
return *this;
}
-
-
void ref()
{
- if (sMutex) sMutex->lock();
mRef++;
- if (sMutex) sMutex->unlock();
}
- S32 unref()
+ void unref()
{
llassert(mRef >= 1);
- if (sMutex) sMutex->lock();
- S32 res = --mRef;
- if (sMutex) sMutex->unlock();
- if (0 == res)
- {
- delete this;
- return 0;
+ if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value.
+ {
+ // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it.
+ // It is technically possible for a vanilla pointer to mess this up, or another thread to
+ // jump in, find this object, create another smart pointer and end up dangling, but if
+ // the code is that bad and not thread-safe, it's trouble already.
+ delete this;
}
- return res;
- }
- S32 getNumRefs() const
- {
- return mRef;
}
-private:
- S32 mRef;
-};
-
-#else
- // New code - This was from https://bitbucket.org/lindenlab/viewer-cat/commits/b03bb43e4ead57f904cb3c1e9745dc8460de6efc
- // and attempts
-
-class LL_COMMON_API LLThreadSafeRefCount
-{
-public:
- static void initThreadSafeRefCount(); // creates sMutex
- static void cleanupThreadSafeRefCount(); // destroys sMutex
-
-private:
- static LLMutex* sMutex;
-
-protected:
- virtual ~LLThreadSafeRefCount(); // use unref()
-
-public:
- LLThreadSafeRefCount();
- LLThreadSafeRefCount(const LLThreadSafeRefCount&);
- LLThreadSafeRefCount& operator=(const LLThreadSafeRefCount& ref)
- {
- mRef = 0;
- return *this;
- }
-
- void ref()
- {
- mRef++;
- }
-
- S32 unref()
- {
- llassert(mRef >= 1);
- bool time_to_die = (mRef == 1);
- if (time_to_die)
- {
- if (sMutex) sMutex->lock();
- // Looks redundant, but is very much not
- // We need to check again once we've acquired the lock
- // so that two threads who get into the if in parallel
- // don't both attempt to the delete.
- //
- mRef--; // Simon: why not if (mRef == 1) delete this; ? There still seems to be a window where mRef could be modified
- if (mRef == 0)
- delete this;
- if (sMutex) sMutex->unlock();
- return 0;
- }
- return --mRef;
- }
S32 getNumRefs() const
{
const S32 currentVal = mRef.CurrentValue();
@@ -345,7 +273,7 @@ public:
private:
LLAtomic32< S32 > mRef;
};
-#endif // new code
+
/**
* intrusive pointer support for LLThreadSafeRefCount