diff options
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llassettype.cpp | 5 | ||||
-rw-r--r-- | indra/llcommon/llassettype.h | 7 | ||||
-rw-r--r-- | indra/llcommon/lldarray.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llfoldertype.cpp | 3 | ||||
-rw-r--r-- | indra/llcommon/llfoldertype.h | 6 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize.cpp | 139 | ||||
-rw-r--r-- | indra/llcommon/llsdserialize.h | 4 | ||||
-rw-r--r-- | indra/llcommon/llstrider.h | 2 | ||||
-rw-r--r-- | indra/llcommon/llthread.cpp | 46 | ||||
-rw-r--r-- | indra/llcommon/llthread.h | 22 | ||||
-rw-r--r-- | indra/llcommon/stdenums.h | 3 |
11 files changed, 229 insertions, 10 deletions
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index 1c664e093b..9dab9d9582 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -100,7 +100,10 @@ LLAssetDictionary::LLAssetDictionary() addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true)); addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true)); - addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false)); + addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false)); + + addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); + }; // static diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 2c2dc27aaa..90cd03c433 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -114,8 +114,11 @@ public: AT_LINK_FOLDER = 25, // Inventory folder link - - AT_COUNT = 26, + + AT_MESH = 49, + // Mesh data in our proprietary SLM format + + AT_COUNT = 50, // +*********************************************************+ // | TO ADD AN ELEMENT TO THIS ENUM: | diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index 0e56a11d53..af647c7e7a 100644 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h @@ -202,7 +202,7 @@ public: { U32 n = mVector.size(); mIndexMap[k] = n; - mVector.resize(n+1); + mVector.push_back(Type()); llassert(mVector.size() == mIndexMap.size()); return mVector[n]; } diff --git a/indra/llcommon/llfoldertype.cpp b/indra/llcommon/llfoldertype.cpp index 2610fe9e6a..16ae4cddde 100644 --- a/indra/llcommon/llfoldertype.cpp +++ b/indra/llcommon/llfoldertype.cpp @@ -95,6 +95,9 @@ LLFolderDictionary::LLFolderDictionary() addEntry(LLFolderType::FT_CURRENT_OUTFIT, new FolderEntry("current", TRUE)); addEntry(LLFolderType::FT_OUTFIT, new FolderEntry("outfit", FALSE)); addEntry(LLFolderType::FT_MY_OUTFITS, new FolderEntry("my_otfts", TRUE)); + + addEntry(LLFolderType::FT_MESH, new FolderEntry("mesh", TRUE)); + addEntry(LLFolderType::FT_INBOX, new FolderEntry("inbox", TRUE)); addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE)); diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h index 7aa77f7f7e..409112a04e 100644 --- a/indra/llcommon/llfoldertype.h +++ b/indra/llcommon/llfoldertype.h @@ -86,9 +86,11 @@ public: FT_OUTFIT = 47, FT_MY_OUTFITS = 48, - FT_INBOX = 49, + FT_MESH = 49, - FT_COUNT = 50, + FT_INBOX = 50, + + FT_COUNT = 51, FT_NONE = -1 }; diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index cf337be161..fdeb93e27f 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -39,6 +39,7 @@ #include <iostream> #include "apr_base64.h" +#include "zlib/zlib.h" // for davep's dirty little zip functions #if !LL_WINDOWS #include <netinet/in.h> // htonl & ntohl @@ -1989,3 +1990,141 @@ std::ostream& operator<<(std::ostream& s, const LLSD& llsd) return s; } + +//dirty little zippers -- yell at davep if these are horrid + +//return a string containing gzipped bytes of binary serialized LLSD +// VERY inefficient -- creates several copies of LLSD block in memory +std::string zip_llsd(LLSD& data) +{ + std::stringstream llsd_strm; + + LLSDSerialize::serialize(data, llsd_strm, LLSDSerialize::LLSD_BINARY); + + z_stream strm; + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + + S32 ret = deflateInit(&strm, Z_BEST_COMPRESSION); + if (ret != Z_OK) + { + llwarns << "Failed to compress LLSD block." << llendl; + return std::string(); + } + + std::string source = llsd_strm.str(); + + strm.avail_in = source.size(); + strm.next_in = (U8*) source.data(); + U8* output = new U8[strm.avail_in]; + strm.avail_out = strm.avail_in; + strm.next_out = output; + ret = deflate(&strm, Z_FINISH); + if (ret != Z_STREAM_END) + { + delete [] output; + llwarns << "Failed to compress LLSD block." << llendl; + return std::string(); + } + + std::string::size_type size = source.size()-strm.avail_out; + + std::string result((char*) output, size); + deflateEnd(&strm); + delete [] output; + + return result; +} + +//decompress a block of LLSD from provided istream +// not very efficient -- creats a copy of decompressed LLSD block in memory +// and deserializes from that copy using LLSDSerialize +bool unzip_llsd(LLSD& data, std::istream& is, S32 size) +{ + U8* result = NULL; + U32 cur_size = 0; + z_stream strm; + + const U32 CHUNK = 65536; + + U8 *in = new U8[size]; + is.read((char*) in, size); + + U8 out[CHUNK]; + + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = size; + strm.next_in = in; + + S32 ret = inflateInit(&strm); + + if (ret != Z_OK) + { + llerrs << "WTF?" << llendl; + } + + do + { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR) + { + inflateEnd(&strm); + free(result); + delete [] in; + return false; + } + + switch (ret) + { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&strm); + free(result); + delete [] in; + return false; + break; + } + + U32 have = CHUNK-strm.avail_out; + + result = (U8*) realloc(result, cur_size + have); + memcpy(result+cur_size, out, have); + cur_size += have; + + } while (strm.avail_out == 0); + + inflateEnd(&strm); + delete [] in; + + if (ret != Z_STREAM_END) + { + free(result); + return false; + } + + //result now points to the decompressed LLSD block + { + std::string res_str((char*) result, cur_size); + std::istringstream istr(res_str); + + if (!LLSDSerialize::deserialize(data, istr, cur_size)) + { + llwarns << "Failed to unzip LLSD block" << llendl; + free(result); + return false; + } + } + + free(result); + return true; +} + + + diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index 2f2b292189..390eaca783 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -796,4 +796,8 @@ public: } }; +//dirty little zip functions -- yell at davep +LL_COMMON_API std::string zip_llsd(LLSD& data); +LL_COMMON_API bool unzip_llsd(LLSD& data, std::istream& is, S32 size); + #endif // LL_LLSDSERIALIZE_H diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 369b06b48a..44ea80a36b 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -51,7 +51,7 @@ public: void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));} void skip(const U32 index) { mBytep += mSkip*index;} - + U32 getSkip() const { return mSkip; } Object* get() { return mObjectp; } Object* operator->() { return mObjectp; } Object& operator *() { return *mObjectp; } diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index 37370e44e7..0385569a02 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -62,6 +62,12 @@ // //---------------------------------------------------------------------------- +#if !LL_DARWIN +U32 ll_thread_local sThreadID = 0; +#endif + +U32 LLThread::sIDIter = 0; + // // Handed to the APR thread creation function // @@ -72,10 +78,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap // Set thread state to running threadp->mStatus = RUNNING; +#if !LL_DARWIN + sThreadID = threadp->mID; +#endif + // Run the user supplied function threadp->run(); - llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl; + //llinfos << "LLThread::staticRun() Exiting: " << threadp->mName << llendl; // We're done with the run function, this thread is done executing now. threadp->mStatus = STOPPED; @@ -90,6 +100,8 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : mAPRThreadp(NULL), mStatus(STOPPED) { + mID = ++sIDIter; + // Thread creation probably CAN be paranoid about APR being initialized, if necessary if (poolp) { @@ -273,7 +285,7 @@ void LLThread::wakeLocked() //============================================================================ LLMutex::LLMutex(apr_pool_t *poolp) : - mAPRMutexp(NULL) + mAPRMutexp(NULL), mCount(0), mLockingThread(NO_THREAD) { //if (poolp) //{ @@ -305,7 +317,18 @@ LLMutex::~LLMutex() void LLMutex::lock() { +#if LL_DARWIN + if (mLockingThread == LLThread::currentID()) +#else + if (mLockingThread == sThreadID) +#endif + { //redundant lock + mCount++; + return; + } + apr_thread_mutex_lock(mAPRMutexp); + #if MUTEX_DEBUG // Have to have the lock before we can access the debug info U32 id = LLThread::currentID(); @@ -313,10 +336,22 @@ void LLMutex::lock() llerrs << "Already locked in Thread: " << id << llendl; mIsLocked[id] = TRUE; #endif + +#if LL_DARWIN + mLockingThread = LLThread::currentID(); +#else + mLockingThread = sThreadID; +#endif } void LLMutex::unlock() { + if (mCount > 0) + { //not the root unlock + mCount--; + return; + } + #if MUTEX_DEBUG // Access the debug info while we have the lock U32 id = LLThread::currentID(); @@ -324,6 +359,8 @@ void LLMutex::unlock() llerrs << "Not locked in Thread: " << id << llendl; mIsLocked[id] = FALSE; #endif + + mLockingThread = NO_THREAD; apr_thread_mutex_unlock(mAPRMutexp); } @@ -341,6 +378,11 @@ bool LLMutex::isLocked() } } +U32 LLMutex::lockingThread() const +{ + return mLockingThread; +} + //============================================================================ LLCondition::LLCondition(apr_pool_t *poolp) : diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index adef1a9192..4b6c3df105 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -41,8 +41,17 @@ class LLThread; class LLMutex; class LLCondition; +#if LL_WINDOWS +#define ll_thread_local __declspec(thread) +#else +#define ll_thread_local __thread +#endif + class LL_COMMON_API LLThread { +private: + static U32 sIDIter; + public: typedef enum e_thread_status { @@ -83,6 +92,8 @@ public: apr_pool_t *getAPRPool() { return mAPRPoolp; } LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; } + U32 getID() const { return mID; } + private: BOOL mPaused; @@ -97,6 +108,7 @@ protected: apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; EThreadStatus mStatus; + U32 mID; //a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used. //Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes. @@ -134,17 +146,27 @@ protected: class LL_COMMON_API LLMutex { public: + typedef enum + { + NO_THREAD = 0xFFFFFFFF + } e_locking_thread; + LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex ~LLMutex(); void lock(); // blocks void unlock(); bool isLocked(); // non-blocking, but does do a lock/unlock so not free + U32 lockingThread() const; //get ID of locking thread protected: apr_thread_mutex_t *mAPRMutexp; + mutable U32 mCount; + mutable U32 mLockingThread; + apr_pool_t *mAPRPoolp; BOOL mIsLocalPool; + #if MUTEX_DEBUG std::map<U32, BOOL> mIsLocked; #endif diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h index 1a5678dde1..6eead924da 100644 --- a/indra/llcommon/stdenums.h +++ b/indra/llcommon/stdenums.h @@ -55,7 +55,8 @@ enum EDragAndDropType DAD_ANIMATION = 12, DAD_GESTURE = 13, DAD_LINK = 14, - DAD_COUNT = 15, // number of types in this enum + DAD_MESH = 15, + DAD_COUNT = 16, // number of types in this enum }; // Reasons for drags to be denied. |