summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llassettype.cpp5
-rw-r--r--indra/llcommon/llassettype.h7
-rw-r--r--indra/llcommon/lldarray.h2
-rw-r--r--indra/llcommon/llfoldertype.cpp3
-rw-r--r--indra/llcommon/llfoldertype.h6
-rw-r--r--indra/llcommon/llsdserialize.cpp139
-rw-r--r--indra/llcommon/llsdserialize.h4
-rw-r--r--indra/llcommon/llstrider.h2
-rw-r--r--indra/llcommon/llthread.cpp46
-rw-r--r--indra/llcommon/llthread.h22
-rw-r--r--indra/llcommon/stdenums.h3
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.