diff options
author | Jacek Antonelli | 2011-05-08 15:13:37 -0500 |
---|---|---|
committer | Jacek Antonelli | 2011-05-08 15:50:49 -0500 |
commit | 7278f0254a3944bd2bcbf1e855fb0d90c3086a27 (patch) | |
tree | 5d7ecb81ebf1a07482f0a7d3d13acd7f18360c0b /linden/indra/llcommon | |
parent | Imprudence 1.3.1 released. (diff) | |
parent | Changed version to Experimental 2011.04.19 (diff) | |
download | meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.zip meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.gz meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.bz2 meta-impy-7278f0254a3944bd2bcbf1e855fb0d90c3086a27.tar.xz |
Merged Experimental branch (exp) back into main line (next).
Git thought many files (almost 100) had merge conflicts. But, after
resolving the conflicts (which were mostly trivial), almost all the
files turned out to be the same as in the exp branch. So, the
conflicts are not listed here. Check the diff between commit 244ffe8
and this commit to see what really changed.
Diffstat (limited to 'linden/indra/llcommon')
90 files changed, 2731 insertions, 769 deletions
diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 3f14be6..ed04ca6 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt | |||
@@ -4,6 +4,7 @@ project(llcommon) | |||
4 | 4 | ||
5 | include(00-Common) | 5 | include(00-Common) |
6 | include(LLCommon) | 6 | include(LLCommon) |
7 | include(Linking) | ||
7 | 8 | ||
8 | include_directories( | 9 | include_directories( |
9 | ${EXPAT_INCLUDE_DIRS} | 10 | ${EXPAT_INCLUDE_DIRS} |
@@ -12,9 +13,13 @@ include_directories( | |||
12 | ) | 13 | ) |
13 | 14 | ||
14 | set(llcommon_SOURCE_FILES | 15 | set(llcommon_SOURCE_FILES |
16 | aiaprpool.cpp | ||
17 | imageids.cpp | ||
18 | indra_constants.cpp | ||
15 | llapp.cpp | 19 | llapp.cpp |
16 | llapr.cpp | 20 | llapr.cpp |
17 | llassettype.cpp | 21 | llassettype.cpp |
22 | llavatarname.cpp | ||
18 | llbase32.cpp | 23 | llbase32.cpp |
19 | llbase64.cpp | 24 | llbase64.cpp |
20 | llcommon.cpp | 25 | llcommon.cpp |
@@ -42,6 +47,7 @@ set(llcommon_SOURCE_FILES | |||
42 | llmetrics.cpp | 47 | llmetrics.cpp |
43 | llmortician.cpp | 48 | llmortician.cpp |
44 | llprocessor.cpp | 49 | llprocessor.cpp |
50 | llprocesslauncher.cpp | ||
45 | llqueuedthread.cpp | 51 | llqueuedthread.cpp |
46 | llrand.cpp | 52 | llrand.cpp |
47 | llrun.cpp | 53 | llrun.cpp |
@@ -70,6 +76,8 @@ set(llcommon_SOURCE_FILES | |||
70 | set(llcommon_HEADER_FILES | 76 | set(llcommon_HEADER_FILES |
71 | CMakeLists.txt | 77 | CMakeLists.txt |
72 | 78 | ||
79 | aiaprpool.h | ||
80 | aithreadsafe.h | ||
73 | bitpack.h | 81 | bitpack.h |
74 | ctype_workaround.h | 82 | ctype_workaround.h |
75 | doublelinkedlist.h | 83 | doublelinkedlist.h |
@@ -83,6 +91,7 @@ set(llcommon_HEADER_FILES | |||
83 | llassettype.h | 91 | llassettype.h |
84 | llassoclist.h | 92 | llassoclist.h |
85 | llavatarconstants.h | 93 | llavatarconstants.h |
94 | llavatarname.h | ||
86 | llbase32.h | 95 | llbase32.h |
87 | llbase64.h | 96 | llbase64.h |
88 | llboost.h | 97 | llboost.h |
@@ -136,12 +145,14 @@ set(llcommon_HEADER_FILES | |||
136 | llnametable.h | 145 | llnametable.h |
137 | llpreprocessor.h | 146 | llpreprocessor.h |
138 | llpriqueuemap.h | 147 | llpriqueuemap.h |
148 | llprocesslauncher.h | ||
139 | llprocessor.h | 149 | llprocessor.h |
140 | llptrskiplist.h | 150 | llptrskiplist.h |
141 | llptrskipmap.h | 151 | llptrskipmap.h |
142 | llqueuedthread.h | 152 | llqueuedthread.h |
143 | llrand.h | 153 | llrand.h |
144 | llrun.h | 154 | llrun.h |
155 | llscopedvolatileaprpool.h | ||
145 | llsd.h | 156 | llsd.h |
146 | llsdserialize.h | 157 | llsdserialize.h |
147 | llsdserialize_xml.h | 158 | llsdserialize_xml.h |
@@ -188,11 +199,22 @@ set_source_files_properties(${llcommon_HEADER_FILES} | |||
188 | 199 | ||
189 | list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) | 200 | list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES}) |
190 | 201 | ||
191 | add_library (llcommon ${llcommon_SOURCE_FILES}) | 202 | add_library (llcommon SHARED ${llcommon_SOURCE_FILES}) |
192 | target_link_libraries( | 203 | target_link_libraries( |
193 | llcommon | 204 | llcommon |
194 | ${APRUTIL_LIBRARIES} | 205 | ${APRUTIL_LIBRARIES} |
195 | ${APR_LIBRARIES} | 206 | ${APR_LIBRARIES} |
196 | ${EXPAT_LIBRARIES} | 207 | ${EXPAT_LIBRARIES} |
197 | ${ZLIB_LIBRARIES} | 208 | ${ZLIB_LIBRARIES} |
209 | ${WINDOWS_LIBRARIES} | ||
198 | ) | 210 | ) |
211 | |||
212 | if (DARWIN) | ||
213 | # don't embed a full path in the library's install name | ||
214 | set_target_properties( | ||
215 | llcommon | ||
216 | PROPERTIES | ||
217 | BUILD_WITH_INSTALL_RPATH 1 | ||
218 | INSTALL_NAME_DIR "@executable_path/../Resources" | ||
219 | ) | ||
220 | endif (DARWIN) | ||
diff --git a/linden/indra/llcommon/aiaprpool.cpp b/linden/indra/llcommon/aiaprpool.cpp new file mode 100644 index 0000000..d3748e9 --- /dev/null +++ b/linden/indra/llcommon/aiaprpool.cpp | |||
@@ -0,0 +1,198 @@ | |||
1 | /** | ||
2 | * @file aiaprpool.cpp | ||
3 | * | ||
4 | * Copyright (c) 2010, Aleric Inglewood. | ||
5 | * | ||
6 | * This program is free software: you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation, either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
18 | * | ||
19 | * There are special exceptions to the terms and conditions of the GPL as | ||
20 | * it is applied to this Source Code. View the full text of the exception | ||
21 | * in the file doc/FLOSS-exception.txt in this software distribution. | ||
22 | * | ||
23 | * CHANGELOG | ||
24 | * and additional copyright holders. | ||
25 | * | ||
26 | * 04/04/2010 | ||
27 | * - Initial version, written by Aleric Inglewood @ SL | ||
28 | * | ||
29 | * 10/11/2010 | ||
30 | * - Changed filename, class names and license to a more | ||
31 | * company-neutral format. | ||
32 | * - Added APR_HAS_THREADS #if's to allow creation and destruction | ||
33 | * of subpools by threads other than the parent pool owner. | ||
34 | */ | ||
35 | |||
36 | #include "linden_common.h" | ||
37 | |||
38 | #include "llerror.h" | ||
39 | #include "aiaprpool.h" | ||
40 | #include "llthread.h" | ||
41 | |||
42 | // Create a subpool from parent. | ||
43 | void AIAPRPool::create(AIAPRPool& parent) | ||
44 | { | ||
45 | llassert(!mPool); // Must be non-initialized. | ||
46 | mParent = &parent; | ||
47 | if (!mParent) // Using the default parameter? | ||
48 | { | ||
49 | // By default use the root pool of the current thread. | ||
50 | mParent = &AIThreadLocalData::tldata().mRootPool; | ||
51 | } | ||
52 | llassert(mParent->mPool); // Parent must be initialized. | ||
53 | #if APR_HAS_THREADS | ||
54 | // As per the documentation of APR (ie http://apr.apache.org/docs/apr/1.4/apr__pools_8h.html): | ||
55 | // | ||
56 | // Note that most operations on pools are not thread-safe: a single pool should only be | ||
57 | // accessed by a single thread at any given time. The one exception to this rule is creating | ||
58 | // a subpool of a given pool: one or more threads can safely create subpools at the same | ||
59 | // time that another thread accesses the parent pool. | ||
60 | // | ||
61 | // In other words, it's safe for any thread to create a (sub)pool, independent of who | ||
62 | // owns the parent pool. | ||
63 | mOwner = apr_os_thread_current(); | ||
64 | #else | ||
65 | mOwner = mParent->mOwner; | ||
66 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
67 | #endif | ||
68 | apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, mParent->mPool); | ||
69 | llassert_always(apr_pool_create_status == APR_SUCCESS); | ||
70 | llassert(mPool); // Initialized. | ||
71 | apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); | ||
72 | } | ||
73 | |||
74 | // Destroy the (sub)pool, if any. | ||
75 | void AIAPRPool::destroy(void) | ||
76 | { | ||
77 | // Only do anything if we are not already (being) destroyed. | ||
78 | if (mPool) | ||
79 | { | ||
80 | #if !APR_HAS_THREADS | ||
81 | // If we are a root pool, then every thread may destruct us: in that case | ||
82 | // we have to assume that no other thread will use this pool concurrently, | ||
83 | // of course. Otherwise, if we are a subpool, only the thread that owns | ||
84 | // the parent may destruct us, since that is the pool that is still alive, | ||
85 | // possibly being used by others and being altered here. | ||
86 | llassert(!mParent || apr_os_thread_equal(mParent->mOwner, apr_os_thread_current())); | ||
87 | #endif | ||
88 | apr_pool_t* pool = mPool; | ||
89 | mPool = NULL; // Mark that we are BEING destructed. | ||
90 | apr_pool_cleanup_kill(pool, this, &s_plain_cleanup); | ||
91 | apr_pool_destroy(pool); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | bool AIAPRPool::parent_is_being_destructed(void) | ||
96 | { | ||
97 | return mParent && (!mParent->mPool || mParent->parent_is_being_destructed()); | ||
98 | } | ||
99 | |||
100 | AIAPRInitialization::AIAPRInitialization(void) | ||
101 | { | ||
102 | static bool apr_initialized = false; | ||
103 | |||
104 | if (!apr_initialized) | ||
105 | { | ||
106 | apr_initialize(); | ||
107 | } | ||
108 | |||
109 | apr_initialized = true; | ||
110 | } | ||
111 | |||
112 | bool AIAPRRootPool::sCountInitialized = false; | ||
113 | apr_uint32_t volatile AIAPRRootPool::sCount; | ||
114 | |||
115 | extern apr_thread_mutex_t* gLogMutexp; | ||
116 | extern apr_thread_mutex_t* gCallStacksLogMutexp; | ||
117 | |||
118 | AIAPRRootPool::AIAPRRootPool(void) : AIAPRInitialization(), AIAPRPool(0) | ||
119 | { | ||
120 | // sCountInitialized don't need locking because when we get here there is still only a single thread. | ||
121 | if (!sCountInitialized) | ||
122 | { | ||
123 | // Initialize the logging mutex | ||
124 | apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); | ||
125 | apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, mPool); | ||
126 | |||
127 | apr_status_t status = apr_atomic_init(mPool); | ||
128 | llassert_always(status == APR_SUCCESS); | ||
129 | apr_atomic_set32(&sCount, 1); // Set to 1 to account for the global root pool. | ||
130 | sCountInitialized = true; | ||
131 | |||
132 | // Initialize thread-local APR pool support. | ||
133 | // Because this recursively calls AIAPRRootPool::AIAPRRootPool(void) | ||
134 | // it must be done last, so that sCount is already initialized. | ||
135 | AIThreadLocalData::init(); | ||
136 | } | ||
137 | apr_atomic_inc32(&sCount); | ||
138 | } | ||
139 | |||
140 | AIAPRRootPool::~AIAPRRootPool() | ||
141 | { | ||
142 | if (!apr_atomic_dec32(&sCount)) | ||
143 | { | ||
144 | // The last pool was destructed. Cleanup remainder of APR. | ||
145 | LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; | ||
146 | |||
147 | if (gLogMutexp) | ||
148 | { | ||
149 | // Clean up the logging mutex | ||
150 | |||
151 | // All other threads NEED to be done before we clean up APR, so this is okay. | ||
152 | apr_thread_mutex_destroy(gLogMutexp); | ||
153 | gLogMutexp = NULL; | ||
154 | } | ||
155 | if (gCallStacksLogMutexp) | ||
156 | { | ||
157 | // Clean up the logging mutex | ||
158 | |||
159 | // All other threads NEED to be done before we clean up APR, so this is okay. | ||
160 | apr_thread_mutex_destroy(gCallStacksLogMutexp); | ||
161 | gCallStacksLogMutexp = NULL; | ||
162 | } | ||
163 | |||
164 | // Must destroy ALL, and therefore this last AIAPRRootPool, before terminating APR. | ||
165 | static_cast<AIAPRRootPool*>(this)->destroy(); | ||
166 | |||
167 | apr_terminate(); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | //static | ||
172 | AIAPRRootPool& AIAPRRootPool::get(void) | ||
173 | { | ||
174 | static AIAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp. | ||
175 | return global_APRpool; | ||
176 | } | ||
177 | |||
178 | void AIVolatileAPRPool::clearVolatileAPRPool() | ||
179 | { | ||
180 | llassert_always(mNumActiveRef > 0); | ||
181 | if (--mNumActiveRef == 0) | ||
182 | { | ||
183 | if (isOld()) | ||
184 | { | ||
185 | destroy(); | ||
186 | mNumTotalRef = 0 ; | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | // This does not actually free the memory, | ||
191 | // it just allows the pool to re-use this memory for the next allocation. | ||
192 | clear(); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | // Paranoia check if the pool is jammed. | ||
197 | llassert(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; | ||
198 | } | ||
diff --git a/linden/indra/llcommon/aiaprpool.h b/linden/indra/llcommon/aiaprpool.h new file mode 100644 index 0000000..ac523a9 --- /dev/null +++ b/linden/indra/llcommon/aiaprpool.h | |||
@@ -0,0 +1,240 @@ | |||
1 | /** | ||
2 | * @file aiaprpool.h | ||
3 | * @brief Implementation of AIAPRPool. | ||
4 | * | ||
5 | * Copyright (c) 2010, Aleric Inglewood. | ||
6 | * | ||
7 | * This program is free software: you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation, either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | * | ||
20 | * There are special exceptions to the terms and conditions of the GPL as | ||
21 | * it is applied to this Source Code. View the full text of the exception | ||
22 | * in the file doc/FLOSS-exception.txt in this software distribution. | ||
23 | * | ||
24 | * CHANGELOG | ||
25 | * and additional copyright holders. | ||
26 | * | ||
27 | * 04/04/2010 | ||
28 | * - Initial version, written by Aleric Inglewood @ SL | ||
29 | * | ||
30 | * 10/11/2010 | ||
31 | * - Changed filename, class names and license to a more | ||
32 | * company-neutral format. | ||
33 | * - Added APR_HAS_THREADS #if's to allow creation and destruction | ||
34 | * of subpools by threads other than the parent pool owner. | ||
35 | */ | ||
36 | |||
37 | #ifndef AIAPRPOOL_H | ||
38 | #define AIAPRPOOL_H | ||
39 | |||
40 | #ifdef LL_WINDOWS | ||
41 | //#include <ws2tcpip.h> | ||
42 | # define WIN32_LEAN_AND_MEAN | ||
43 | # include <winsock2.h> // Needed before including apr_portable.h | ||
44 | #endif | ||
45 | |||
46 | #include "apr_portable.h" | ||
47 | #include "apr_pools.h" | ||
48 | #include "llerror.h" | ||
49 | |||
50 | extern void ll_init_apr(); | ||
51 | |||
52 | /** | ||
53 | * @brief A wrapper around the APR memory pool API. | ||
54 | * | ||
55 | * Usage of this class should be restricted to passing it to libapr-1 function calls that need it. | ||
56 | * | ||
57 | */ | ||
58 | class LL_COMMON_API AIAPRPool | ||
59 | { | ||
60 | protected: | ||
61 | apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized. | ||
62 | AIAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero. | ||
63 | apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero. | ||
64 | |||
65 | public: | ||
66 | //! Construct an uninitialized (destructed) pool. | ||
67 | AIAPRPool(void) : mPool(NULL) { } | ||
68 | |||
69 | //! Construct a subpool from an existing pool. | ||
70 | // This is not a copy-constructor, this class doesn't have one! | ||
71 | AIAPRPool(AIAPRPool& parent) : mPool(NULL) { create(parent); } | ||
72 | |||
73 | //! Destruct the memory pool (free all of it's subpools and allocated memory). | ||
74 | ~AIAPRPool() { destroy(); } | ||
75 | |||
76 | protected: | ||
77 | // Create a pool that is allocated from the Operating System. Only used by AIAPRRootPool. | ||
78 | AIAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current()) | ||
79 | { | ||
80 | apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL); | ||
81 | llassert_always(apr_pool_create_status == APR_SUCCESS); | ||
82 | llassert(mPool); | ||
83 | apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); | ||
84 | } | ||
85 | |||
86 | public: | ||
87 | //! Create a subpool from parent. May only be called for an uninitialized/destroyed pool. | ||
88 | // The default parameter causes the root pool of the current thread to be used. | ||
89 | void create(AIAPRPool& parent = *static_cast<AIAPRPool*>(NULL)); | ||
90 | |||
91 | //! Destroy the (sub)pool, if any. | ||
92 | void destroy(void); | ||
93 | |||
94 | // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool. | ||
95 | typedef apr_pool_t* const AIAPRPool::* const bool_type; | ||
96 | //! Return true if the pool is initialized. | ||
97 | operator bool_type() const { return mPool ? &AIAPRPool::mPool : 0; } | ||
98 | |||
99 | // Painful, but we have to either provide access to this, or wrap | ||
100 | // every APR function call that needs a apr_pool_t* to be passed. | ||
101 | // NEVER destroy a pool that is returned by this function! | ||
102 | apr_pool_t* operator()(void) const | ||
103 | { | ||
104 | llassert(mPool); | ||
105 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
106 | return mPool; | ||
107 | } | ||
108 | |||
109 | // Free all memory without destructing the pool. | ||
110 | void clear(void) | ||
111 | { | ||
112 | llassert(mPool); | ||
113 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
114 | apr_pool_clear(mPool); | ||
115 | } | ||
116 | |||
117 | // These methods would make this class 'complete' (as wrapper around the libapr | ||
118 | // pool functions), but we don't use memory pools in the viewer (only when | ||
119 | // we are forced to pass one to a libapr call), so don't define them in order | ||
120 | // not to encourage people to use them. | ||
121 | #if 0 | ||
122 | void* palloc(size_t size) | ||
123 | { | ||
124 | llassert(mPool); | ||
125 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
126 | return apr_palloc(mPool, size); | ||
127 | } | ||
128 | void* pcalloc(size_t size) | ||
129 | { | ||
130 | llassert(mPool); | ||
131 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
132 | return apr_pcalloc(mPool, size); | ||
133 | } | ||
134 | #endif | ||
135 | |||
136 | private: | ||
137 | bool parent_is_being_destructed(void); | ||
138 | static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<AIAPRPool*>(userdata)->plain_cleanup(); } | ||
139 | |||
140 | apr_status_t plain_cleanup(void) | ||
141 | { | ||
142 | if (mPool && // We are not being destructed, | ||
143 | parent_is_being_destructed()) // but our parent is. | ||
144 | // This means the pool is being destructed recursively by libapr | ||
145 | // because one of it's parents is being destructed. | ||
146 | { | ||
147 | mPool = NULL; // Stop destroy() from destructing the pool again. | ||
148 | } | ||
149 | return APR_SUCCESS; | ||
150 | } | ||
151 | }; | ||
152 | |||
153 | class AIAPRInitialization | ||
154 | { | ||
155 | public: | ||
156 | AIAPRInitialization(void); | ||
157 | }; | ||
158 | |||
159 | /** | ||
160 | * @brief Root memory pool (allocates memory from the operating system). | ||
161 | * | ||
162 | * This class should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase | ||
163 | * (and LLMutexRootPool when APR_HAS_THREADS isn't defined). | ||
164 | */ | ||
165 | class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool | ||
166 | { | ||
167 | private: | ||
168 | friend class AIThreadLocalData; | ||
169 | friend class AIThreadSafeSimpleDCRootPool_pbase; | ||
170 | #if !APR_HAS_THREADS | ||
171 | friend class LLMutexRootPool; | ||
172 | #endif | ||
173 | //! Construct a root memory pool. | ||
174 | // Should only be used by AIThreadLocalData and AIThreadSafeSimpleDCRootPool_pbase. | ||
175 | AIAPRRootPool(void); | ||
176 | ~AIAPRRootPool(); | ||
177 | |||
178 | private: | ||
179 | // Keep track of how many root pools exist and when the last one is destructed. | ||
180 | static bool sCountInitialized; | ||
181 | static apr_uint32_t volatile sCount; | ||
182 | |||
183 | public: | ||
184 | // Return a global root pool that is independent of AIThreadLocalData. | ||
185 | // Normally you should not use this. Only use for early initialization | ||
186 | // (before main) and deinitialization (after main). | ||
187 | static AIAPRRootPool& get(void); | ||
188 | |||
189 | #if APR_POOL_DEBUG | ||
190 | void grab_ownership(void) | ||
191 | { | ||
192 | // You need a patched libapr to use this. | ||
193 | // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI | ||
194 | apr_pool_owner_set(mPool); | ||
195 | } | ||
196 | #endif | ||
197 | |||
198 | private: | ||
199 | // Used for constructing the Special Global Root Pool (returned by AIAPRRootPool::get). | ||
200 | // It is the same as the default constructor but omits to increment sCount. As a result, | ||
201 | // we must be sure that at least one other AIAPRRootPool is created before termination | ||
202 | // of the application (which is the case: we create one AIAPRRootPool per thread). | ||
203 | AIAPRRootPool(int) : AIAPRInitialization(), AIAPRPool(0) { } | ||
204 | }; | ||
205 | |||
206 | //! Volatile memory pool | ||
207 | // | ||
208 | // 'Volatile' APR memory pool which normally only clears memory, | ||
209 | // and does not destroy the pool (the same pool is reused) for | ||
210 | // greater efficiency. However, as a safe guard the apr pool | ||
211 | // is destructed every FULL_VOLATILE_APR_POOL uses to allow | ||
212 | // the system memory to be allocated more efficiently and not | ||
213 | // get scattered through RAM. | ||
214 | // | ||
215 | class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool | ||
216 | { | ||
217 | public: | ||
218 | AIVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { } | ||
219 | |||
220 | apr_pool_t* getVolatileAPRPool(void) | ||
221 | { | ||
222 | if (!mPool) create(); | ||
223 | ++mNumActiveRef; | ||
224 | ++mNumTotalRef; | ||
225 | return AIAPRPool::operator()(); | ||
226 | } | ||
227 | void clearVolatileAPRPool(void); | ||
228 | |||
229 | bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; } | ||
230 | bool isUnused() const { return mNumActiveRef == 0; } | ||
231 | |||
232 | private: | ||
233 | S32 mNumActiveRef; // Number of active uses of the pool. | ||
234 | S32 mNumTotalRef; // Number of total uses of the pool since last creation. | ||
235 | |||
236 | // Maximum number of references to AIVolatileAPRPool until the pool is recreated. | ||
237 | static S32 const FULL_VOLATILE_APR_POOL = 1024; | ||
238 | }; | ||
239 | |||
240 | #endif // AIAPRPOOL_H | ||
diff --git a/linden/indra/llcommon/aithreadsafe.h b/linden/indra/llcommon/aithreadsafe.h new file mode 100644 index 0000000..e1b93ba --- /dev/null +++ b/linden/indra/llcommon/aithreadsafe.h | |||
@@ -0,0 +1,463 @@ | |||
1 | /** | ||
2 | * @file aithreadsafe.h | ||
3 | * @brief Implementation of AIThreadSafe, AIReadAccessConst, AIReadAccess and AIWriteAccess. | ||
4 | * | ||
5 | * CHANGELOG | ||
6 | * and additional copyright holders. | ||
7 | * | ||
8 | * 31/03/2010 | ||
9 | * Initial version, written by Aleric Inglewood @ SL | ||
10 | */ | ||
11 | |||
12 | #ifndef AITHREADSAFE_H | ||
13 | #define AITHREADSAFE_H | ||
14 | |||
15 | #include <new> | ||
16 | |||
17 | #include "llthread.h" | ||
18 | #include "llerror.h" | ||
19 | |||
20 | template<typename T> struct AIReadAccessConst; | ||
21 | template<typename T> struct AIReadAccess; | ||
22 | template<typename T> struct AIWriteAccess; | ||
23 | template<typename T> struct AIAccess; | ||
24 | |||
25 | template<typename T> | ||
26 | class AIThreadSafeBits | ||
27 | { | ||
28 | private: | ||
29 | // AIThreadSafe is a wrapper around an instance of T. | ||
30 | // Because T might not have a default constructor, it is constructed | ||
31 | // 'in place', with placement new, in the memory reserved here. | ||
32 | // | ||
33 | // Make sure that the memory that T will be placed in is properly | ||
34 | // aligned by using an array of long's. | ||
35 | long mMemory[(sizeof(T) + sizeof(long) - 1) / sizeof(long)]; | ||
36 | |||
37 | public: | ||
38 | // The wrapped objects are constructed in-place with placement new *outside* | ||
39 | // of this object (by AITHREADSAFE macro(s) or derived classes). | ||
40 | // However, we are responsible for the destruction of the wrapped object. | ||
41 | ~AIThreadSafeBits() { ptr()->~T(); } | ||
42 | |||
43 | // Only for use by AITHREADSAFE, see below. | ||
44 | void* memory() const { return const_cast<long*>(&mMemory[0]); } | ||
45 | |||
46 | protected: | ||
47 | // Accessors. | ||
48 | T const* ptr() const { return reinterpret_cast<T const*>(mMemory); } | ||
49 | T* ptr() { return reinterpret_cast<T*>(mMemory); } | ||
50 | }; | ||
51 | |||
52 | /** | ||
53 | * @brief A wrapper class for objects that need to be accessed by more than one thread, allowing concurrent readers. | ||
54 | * | ||
55 | * Use AITHREADSAFE to define instances of any type, and use AIReadAccessConst, | ||
56 | * AIReadAccess and AIWriteAccess to get access to the instance. | ||
57 | * | ||
58 | * For example, | ||
59 | * | ||
60 | * <code> | ||
61 | * class Foo { public: Foo(int, int); }; | ||
62 | * | ||
63 | * AITHREADSAFE(Foo, foo, (2, 3)); | ||
64 | * | ||
65 | * AIReadAccess<Foo> foo_r(foo); | ||
66 | * // Use foo_r-> for read access. | ||
67 | * | ||
68 | * AIWriteAccess<Foo> foo_w(foo); | ||
69 | * // Use foo_w-> for write access. | ||
70 | * </code> | ||
71 | * | ||
72 | * If <code>foo</code> is constant, you have to use <code>AIReadAccessConst<Foo></code>. | ||
73 | * | ||
74 | * It is possible to pass access objects to a function that | ||
75 | * downgrades the access, for example: | ||
76 | * | ||
77 | * <code> | ||
78 | * void readfunc(AIReadAccess const& access); | ||
79 | * | ||
80 | * AIWriteAccess<Foo> foo_w(foo); | ||
81 | * readfunc(foo_w); // readfunc will perform read access to foo_w. | ||
82 | * </code> | ||
83 | * | ||
84 | * If <code>AIReadAccess</code> is non-const, you can upgrade the access by creating | ||
85 | * an <code>AIWriteAccess</code> object from it. For example: | ||
86 | * | ||
87 | * <code> | ||
88 | * AIWriteAccess<Foo> foo_w(foo_r); | ||
89 | * </code> | ||
90 | * | ||
91 | * This API is Robust(tm). If you try anything that could result in problems, | ||
92 | * it simply won't compile. The only mistake you can still easily make is | ||
93 | * to obtain write access to an object when it is not needed, or to unlock | ||
94 | * an object in between accesses while the state of the object should be | ||
95 | * preserved. For example: | ||
96 | * | ||
97 | * <code> | ||
98 | * // This resets foo to point to the first file and then returns that. | ||
99 | * std::string filename = AIWriteAccess<Foo>(foo)->get_first_filename(); | ||
100 | * | ||
101 | * // WRONG! The state between calling get_first_filename and get_next_filename should be preserved! | ||
102 | * | ||
103 | * AIWriteAccess<Foo> foo_w(foo); // Wrong. The code below only needs read-access. | ||
104 | * while (!filename.empty()) | ||
105 | * { | ||
106 | * something(filename); | ||
107 | * filename = foo_w->next_filename(); | ||
108 | * } | ||
109 | * </code> | ||
110 | * | ||
111 | * Correct would be | ||
112 | * | ||
113 | * <code> | ||
114 | * AIReadAccess<Foo> foo_r(foo); | ||
115 | * std::string filename = AIWriteAccess<Foo>(foo_r)->get_first_filename(); | ||
116 | * while (!filename.empty()) | ||
117 | * { | ||
118 | * something(filename); | ||
119 | * filename = foo_r->next_filename(); | ||
120 | * } | ||
121 | * </code> | ||
122 | * | ||
123 | */ | ||
124 | template<typename T> | ||
125 | class AIThreadSafe : public AIThreadSafeBits<T> | ||
126 | { | ||
127 | protected: | ||
128 | // Only these may access the object (through ptr()). | ||
129 | friend struct AIReadAccessConst<T>; | ||
130 | friend struct AIReadAccess<T>; | ||
131 | friend struct AIWriteAccess<T>; | ||
132 | |||
133 | // Locking control. | ||
134 | AIRWLock mRWLock; | ||
135 | |||
136 | // For use by AIThreadSafeDC | ||
137 | AIThreadSafe(void) { } | ||
138 | AIThreadSafe(AIAPRPool& parent) : mRWLock(parent) { } | ||
139 | |||
140 | public: | ||
141 | // Only for use by AITHREADSAFE, see below. | ||
142 | AIThreadSafe(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); } | ||
143 | }; | ||
144 | |||
145 | /** | ||
146 | * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafe, using an arbitrary constructor. | ||
147 | * | ||
148 | * For example, instead of doing | ||
149 | * | ||
150 | * <code> | ||
151 | * Foo foo(x, y); | ||
152 | * static Bar bar; | ||
153 | * </code> | ||
154 | * | ||
155 | * One can instantiate a thread-safe instance with | ||
156 | * | ||
157 | * <code> | ||
158 | * AITHREADSAFE(Foo, foo, (x, y)); | ||
159 | * static AITHREADSAFE(Bar, bar, ); | ||
160 | * </code> | ||
161 | * | ||
162 | * Note: This macro does not allow to allocate such object on the heap. | ||
163 | * If that is needed, have a look at AIThreadSafeDC. | ||
164 | */ | ||
165 | #define AITHREADSAFE(type, var, paramlist) AIThreadSafe<type> var(new (var.memory()) type paramlist) | ||
166 | |||
167 | /** | ||
168 | * @brief A wrapper class for objects that need to be accessed by more than one thread. | ||
169 | * | ||
170 | * This class is the same as an AIThreadSafe wrapper, except that it can only | ||
171 | * be used for default constructed objects. | ||
172 | * | ||
173 | * For example, instead of | ||
174 | * | ||
175 | * <code> | ||
176 | * Foo foo; | ||
177 | * </code> | ||
178 | * | ||
179 | * One would use | ||
180 | * | ||
181 | * <code> | ||
182 | * AIThreadSafeDC<Foo> foo; | ||
183 | * </code> | ||
184 | * | ||
185 | * The advantage over AITHREADSAFE is that this object can be allocated with | ||
186 | * new on the heap. For example: | ||
187 | * | ||
188 | * <code> | ||
189 | * AIThreadSafeDC<Foo>* ptr = new AIThreadSafeDC<Foo>; | ||
190 | * </code> | ||
191 | * | ||
192 | * which is not possible with AITHREADSAFE. | ||
193 | */ | ||
194 | template<typename T> | ||
195 | class AIThreadSafeDC : public AIThreadSafe<T> | ||
196 | { | ||
197 | public: | ||
198 | // Construct a wrapper around a default constructed object. | ||
199 | AIThreadSafeDC(void) { new (AIThreadSafe<T>::ptr()) T; } | ||
200 | }; | ||
201 | |||
202 | /** | ||
203 | * @brief Read lock object and provide read access. | ||
204 | */ | ||
205 | template<typename T> | ||
206 | struct AIReadAccessConst | ||
207 | { | ||
208 | //! Internal enum for the lock-type of the AI*Access object. | ||
209 | enum state_type | ||
210 | { | ||
211 | readlocked, //!< A AIReadAccessConst or AIReadAccess. | ||
212 | read2writelocked, //!< A AIWriteAccess constructed from a AIReadAccess. | ||
213 | writelocked, //!< A AIWriteAccess constructed from a AIThreadSafe. | ||
214 | write2writelocked //!< A AIWriteAccess constructed from (the AIReadAccess base class of) a AIWriteAccess. | ||
215 | }; | ||
216 | |||
217 | //! Construct a AIReadAccessConst from a constant AIThreadSafe. | ||
218 | AIReadAccessConst(AIThreadSafe<T> const& wrapper) | ||
219 | : mWrapper(const_cast<AIThreadSafe<T>&>(wrapper)), | ||
220 | mState(readlocked) | ||
221 | { | ||
222 | mWrapper.mRWLock.rdlock(); | ||
223 | } | ||
224 | |||
225 | //! Destruct the AI*Access object. | ||
226 | // These should never be dynamically allocated, so there is no need to make this virtual. | ||
227 | ~AIReadAccessConst() | ||
228 | { | ||
229 | if (mState == readlocked) | ||
230 | mWrapper.mRWLock.rdunlock(); | ||
231 | else if (mState == writelocked) | ||
232 | mWrapper.mRWLock.wrunlock(); | ||
233 | else if (mState == read2writelocked) | ||
234 | mWrapper.mRWLock.wr2rdlock(); | ||
235 | } | ||
236 | |||
237 | //! Access the underlaying object for read access. | ||
238 | T const* operator->() const { return mWrapper.ptr(); } | ||
239 | |||
240 | //! Access the underlaying object for read access. | ||
241 | T const& operator*() const { return *mWrapper.ptr(); } | ||
242 | |||
243 | protected: | ||
244 | //! Constructor used by AIReadAccess. | ||
245 | AIReadAccessConst(AIThreadSafe<T>& wrapper, state_type state) | ||
246 | : mWrapper(wrapper), mState(state) { } | ||
247 | |||
248 | AIThreadSafe<T>& mWrapper; //!< Reference to the object that we provide access to. | ||
249 | state_type const mState; //!< The lock state that mWrapper is in. | ||
250 | |||
251 | private: | ||
252 | // Disallow copy constructing directly. | ||
253 | AIReadAccessConst(AIReadAccessConst const&); | ||
254 | }; | ||
255 | |||
256 | /** | ||
257 | * @brief Read lock object and provide read access, with possible promotion to write access. | ||
258 | */ | ||
259 | template<typename T> | ||
260 | struct AIReadAccess : public AIReadAccessConst<T> | ||
261 | { | ||
262 | typedef typename AIReadAccessConst<T>::state_type state_type; | ||
263 | using AIReadAccessConst<T>::readlocked; | ||
264 | |||
265 | //! Construct a AIReadAccess from a non-constant AIThreadSafe. | ||
266 | AIReadAccess(AIThreadSafe<T>& wrapper) : AIReadAccessConst<T>(wrapper, readlocked) { this->mWrapper.mRWLock.rdlock(); } | ||
267 | |||
268 | protected: | ||
269 | //! Constructor used by AIWriteAccess. | ||
270 | AIReadAccess(AIThreadSafe<T>& wrapper, state_type state) : AIReadAccessConst<T>(wrapper, state) { } | ||
271 | |||
272 | friend class AIWriteAccess<T>; | ||
273 | }; | ||
274 | |||
275 | /** | ||
276 | * @brief Write lock object and provide read/write access. | ||
277 | */ | ||
278 | template<typename T> | ||
279 | struct AIWriteAccess : public AIReadAccess<T> | ||
280 | { | ||
281 | using AIReadAccessConst<T>::readlocked; | ||
282 | using AIReadAccessConst<T>::read2writelocked; | ||
283 | using AIReadAccessConst<T>::writelocked; | ||
284 | using AIReadAccessConst<T>::write2writelocked; | ||
285 | |||
286 | //! Construct a AIWriteAccess from a non-constant AIThreadSafe. | ||
287 | AIWriteAccess(AIThreadSafe<T>& wrapper) : AIReadAccess<T>(wrapper, writelocked) { this->mWrapper.mRWLock.wrlock();} | ||
288 | |||
289 | //! Promote read access to write access. | ||
290 | explicit AIWriteAccess(AIReadAccess<T>& access) | ||
291 | : AIReadAccess<T>(access.mWrapper, (access.mState == readlocked) ? read2writelocked : write2writelocked) | ||
292 | { | ||
293 | if (this->mState == read2writelocked) | ||
294 | { | ||
295 | this->mWrapper.mRWLock.rd2wrlock(); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | //! Access the underlaying object for (read and) write access. | ||
300 | T* operator->() const { return this->mWrapper.ptr(); } | ||
301 | |||
302 | //! Access the underlaying object for (read and) write access. | ||
303 | T& operator*() const { return *this->mWrapper.ptr(); } | ||
304 | }; | ||
305 | |||
306 | /** | ||
307 | * @brief A wrapper class for objects that need to be accessed by more than one thread. | ||
308 | * | ||
309 | * Use AITHREADSAFESIMPLE to define instances of any type, and use AIAccess | ||
310 | * to get access to the instance. | ||
311 | * | ||
312 | * For example, | ||
313 | * | ||
314 | * <code> | ||
315 | * class Foo { public: Foo(int, int); }; | ||
316 | * | ||
317 | * AITHREADSAFESIMPLE(Foo, foo, (2, 3)); | ||
318 | * | ||
319 | * AIAccess<Foo> foo_w(foo); | ||
320 | * // Use foo_w-> for read and write access. | ||
321 | * | ||
322 | * See also AIThreadSafe | ||
323 | */ | ||
324 | template<typename T> | ||
325 | class AIThreadSafeSimple : public AIThreadSafeBits<T> | ||
326 | { | ||
327 | protected: | ||
328 | // Only this one may access the object (through ptr()). | ||
329 | friend struct AIAccess<T>; | ||
330 | |||
331 | // Locking control. | ||
332 | LLMutex mMutex; | ||
333 | |||
334 | // For use by AIThreadSafeSimpleDC | ||
335 | AIThreadSafeSimple(void) { } | ||
336 | AIThreadSafeSimple(AIAPRPool& parent) : mMutex(parent) { } | ||
337 | |||
338 | public: | ||
339 | // Only for use by AITHREADSAFESIMPLE, see below. | ||
340 | AIThreadSafeSimple(T* object) { llassert(object == AIThreadSafeBits<T>::ptr()); } | ||
341 | }; | ||
342 | |||
343 | /** | ||
344 | * @brief Instantiate an static, global or local object of a given type wrapped in AIThreadSafeSimple, using an arbitrary constructor. | ||
345 | * | ||
346 | * For example, instead of doing | ||
347 | * | ||
348 | * <code> | ||
349 | * Foo foo(x, y); | ||
350 | * static Bar bar; | ||
351 | * </code> | ||
352 | * | ||
353 | * One can instantiate a thread-safe instance with | ||
354 | * | ||
355 | * <code> | ||
356 | * AITHREADSAFESIMPLE(Foo, foo, (x, y)); | ||
357 | * static AITHREADSAFESIMPLE(Bar, bar, ); | ||
358 | * </code> | ||
359 | * | ||
360 | * Note: This macro does not allow to allocate such object on the heap. | ||
361 | * If that is needed, have a look at AIThreadSafeSimpleDC. | ||
362 | */ | ||
363 | #define AITHREADSAFESIMPLE(type, var, paramlist) AIThreadSafeSimple<type> var(new (var.memory()) type paramlist) | ||
364 | |||
365 | /** | ||
366 | * @brief A wrapper class for objects that need to be accessed by more than one thread. | ||
367 | * | ||
368 | * This class is the same as an AIThreadSafeSimple wrapper, except that it can only | ||
369 | * be used for default constructed objects. | ||
370 | * | ||
371 | * For example, instead of | ||
372 | * | ||
373 | * <code> | ||
374 | * Foo foo; | ||
375 | * </code> | ||
376 | * | ||
377 | * One would use | ||
378 | * | ||
379 | * <code> | ||
380 | * AIThreadSafeSimpleDC<Foo> foo; | ||
381 | * </code> | ||
382 | * | ||
383 | * The advantage over AITHREADSAFESIMPLE is that this object can be allocated with | ||
384 | * new on the heap. For example: | ||
385 | * | ||
386 | * <code> | ||
387 | * AIThreadSafeSimpleDC<Foo>* ptr = new AIThreadSafeSimpleDC<Foo>; | ||
388 | * </code> | ||
389 | * | ||
390 | * which is not possible with AITHREADSAFESIMPLE. | ||
391 | */ | ||
392 | template<typename T> | ||
393 | class AIThreadSafeSimpleDC : public AIThreadSafeSimple<T> | ||
394 | { | ||
395 | public: | ||
396 | // Construct a wrapper around a default constructed object. | ||
397 | AIThreadSafeSimpleDC(void) { new (AIThreadSafeSimple<T>::ptr()) T; } | ||
398 | |||
399 | protected: | ||
400 | // For use by AIThreadSafeSimpleDCRootPool | ||
401 | AIThreadSafeSimpleDC(AIAPRPool& parent) : AIThreadSafeSimple<T>(parent) { new (AIThreadSafeSimple<T>::ptr()) T; } | ||
402 | }; | ||
403 | |||
404 | // Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of | ||
405 | // the root pool before constructing AIThreadSafeSimpleDC. | ||
406 | class AIThreadSafeSimpleDCRootPool_pbase | ||
407 | { | ||
408 | protected: | ||
409 | AIAPRRootPool mRootPool; | ||
410 | |||
411 | private: | ||
412 | template<typename T> friend class AIThreadSafeSimpleDCRootPool; | ||
413 | AIThreadSafeSimpleDCRootPool_pbase(void) { } | ||
414 | }; | ||
415 | |||
416 | /** | ||
417 | * @brief A wrapper class for objects that need to be accessed by more than one thread. | ||
418 | * | ||
419 | * The same as AIThreadSafeSimpleDC except that this class creates its own AIAPRRootPool | ||
420 | * for the internally used mutexes and condition, instead of using the current threads | ||
421 | * root pool. The advantage of this is that it can be used for objects that need to | ||
422 | * be accessed from the destructors of global objects (after main). The disadvantage | ||
423 | * is that it's less efficient to use your own root pool, therefore it's use should be | ||
424 | * restricted to those cases where it is absolutely necessary. | ||
425 | */ | ||
426 | template<typename T> | ||
427 | class AIThreadSafeSimpleDCRootPool : private AIThreadSafeSimpleDCRootPool_pbase, public AIThreadSafeSimpleDC<T> | ||
428 | { | ||
429 | public: | ||
430 | // Construct a wrapper around a default constructed object, using memory allocated | ||
431 | // from the operating system for the internal APR objects (mutexes and conditional), | ||
432 | // as opposed to allocated from the current threads root pool. | ||
433 | AIThreadSafeSimpleDCRootPool(void) : | ||
434 | AIThreadSafeSimpleDCRootPool_pbase(), | ||
435 | AIThreadSafeSimpleDC<T>(mRootPool) { } | ||
436 | }; | ||
437 | |||
438 | /** | ||
439 | * @brief Write lock object and provide read/write access. | ||
440 | */ | ||
441 | template<typename T> | ||
442 | struct AIAccess | ||
443 | { | ||
444 | //! Construct a AIAccess from a non-constant AIThreadSafeSimple. | ||
445 | AIAccess(AIThreadSafeSimple<T>& wrapper) : mWrapper(wrapper) { this->mWrapper.mMutex.lock(); } | ||
446 | |||
447 | //! Access the underlaying object for (read and) write access. | ||
448 | T* operator->() const { return this->mWrapper.ptr(); } | ||
449 | |||
450 | //! Access the underlaying object for (read and) write access. | ||
451 | T& operator*() const { return *this->mWrapper.ptr(); } | ||
452 | |||
453 | ~AIAccess() { this->mWrapper.mMutex.unlock(); } | ||
454 | |||
455 | protected: | ||
456 | AIThreadSafeSimple<T>& mWrapper; //!< Reference to the object that we provide access to. | ||
457 | |||
458 | private: | ||
459 | // Disallow copy constructing directly. | ||
460 | AIAccess(AIAccess const&); | ||
461 | }; | ||
462 | |||
463 | #endif | ||
diff --git a/linden/indra/llcommon/imageids.cpp b/linden/indra/llcommon/imageids.cpp new file mode 100644 index 0000000..e5343fe --- /dev/null +++ b/linden/indra/llcommon/imageids.cpp | |||
@@ -0,0 +1,79 @@ | |||
1 | /** | ||
2 | * @file imageids.cpp | ||
3 | * | ||
4 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
5 | * | ||
6 | * Copyright (c) 2001-2010, Linden Research, Inc. | ||
7 | * | ||
8 | * Second Life Viewer Source Code | ||
9 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
10 | * to you under the terms of the GNU General Public License, version 2.0 | ||
11 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
12 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
13 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
14 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
15 | * | ||
16 | * There are special exceptions to the terms and conditions of the GPL as | ||
17 | * it is applied to this Source Code. View the full text of the exception | ||
18 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
19 | * online at | ||
20 | * http://secondlife.com/developers/opensource/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #include "imageids.h" | ||
36 | |||
37 | #include "lluuid.h" | ||
38 | |||
39 | // | ||
40 | // USE OF THIS FILE IS DEPRECATED | ||
41 | // | ||
42 | // Please use viewerart.ini and the standard | ||
43 | // art import path. // indicates if file is only | ||
44 | // on dataserver, or also | ||
45 | // pre-cached on viewer | ||
46 | |||
47 | // Grass Images | ||
48 | const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER | ||
49 | |||
50 | const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER | ||
51 | |||
52 | const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver | ||
53 | const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver | ||
54 | const LLUUID IMG_CLOUD_POOF ("fc4b9f0b-d008-45c6-96a4-01dd947ac621"); // dataserver | ||
55 | const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver | ||
56 | const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver | ||
57 | const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver | ||
58 | const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector | ||
59 | const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver | ||
60 | const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver | ||
61 | |||
62 | const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver | ||
63 | const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver | ||
64 | const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver | ||
65 | const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver | ||
66 | const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver | ||
67 | |||
68 | const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver | ||
69 | const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver | ||
70 | |||
71 | const LLUUID IMG_BLOOM1 ("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); // VIEWER | ||
72 | const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER | ||
73 | const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER | ||
74 | const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER | ||
75 | const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER | ||
76 | |||
77 | const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER | ||
78 | |||
79 | const LLUUID DEFAULT_UNREZZED_AVATAR_PARTICLE ("c6e07fda-aea5-4149-acb6-6f09980e0db5"); // VIEWER only | ||
diff --git a/linden/indra/llcommon/imageids.h b/linden/indra/llcommon/imageids.h index 832708c..516fda1 100644 --- a/linden/indra/llcommon/imageids.h +++ b/linden/indra/llcommon/imageids.h | |||
@@ -33,46 +33,44 @@ | |||
33 | #ifndef LL_IMAGEIDS_H | 33 | #ifndef LL_IMAGEIDS_H |
34 | #define LL_IMAGEIDS_H | 34 | #define LL_IMAGEIDS_H |
35 | 35 | ||
36 | #include "lluuid.h" | ||
37 | |||
38 | // | 36 | // |
39 | // USE OF THIS FILE IS DEPRECATED | 37 | // USE OF THIS FILE IS DEPRECATED |
40 | // | 38 | // |
41 | // Please use viewerart.ini and the standard | 39 | // Please use viewerart.ini and the standard |
42 | // art import path. // indicates if file is only | 40 | // art import path. |
43 | // on dataserver, or also | 41 | |
44 | // pre-cached on viewer | 42 | class LLUUID; |
45 | 43 | ||
46 | // Grass Images | 44 | LL_COMMON_API extern const LLUUID IMG_SMOKE; |
47 | const LLUUID IMG_SMOKE ("b4ba225c-373f-446d-9f7e-6cb7b5cf9b3d"); // VIEWER | ||
48 | 45 | ||
49 | const LLUUID IMG_DEFAULT ("d2114404-dd59-4a4d-8e6c-49359e91bbf0"); // VIEWER | 46 | LL_COMMON_API extern const LLUUID IMG_DEFAULT; |
50 | 47 | ||
51 | const LLUUID IMG_SUN ("cce0f112-878f-4586-a2e2-a8f104bba271"); // dataserver | 48 | LL_COMMON_API extern const LLUUID IMG_SUN; |
52 | const LLUUID IMG_MOON ("d07f6eed-b96a-47cd-b51d-400ad4a1c428"); // dataserver | 49 | LL_COMMON_API extern const LLUUID IMG_MOON; |
53 | const LLUUID IMG_CLOUD_POOF ("fc4b9f0b-d008-45c6-96a4-01dd947ac621"); // dataserver | 50 | LL_COMMON_API extern const LLUUID IMG_CLOUD_POOF; |
54 | const LLUUID IMG_SHOT ("35f217a3-f618-49cf-bbca-c86d486551a9"); // dataserver | 51 | LL_COMMON_API extern const LLUUID IMG_SHOT; |
55 | const LLUUID IMG_SPARK ("d2e75ac1-d0fb-4532-820e-a20034ac814d"); // dataserver | 52 | LL_COMMON_API extern const LLUUID IMG_SPARK; |
56 | const LLUUID IMG_FIRE ("aca40aa8-44cf-44ca-a0fa-93e1a2986f82"); // dataserver | 53 | LL_COMMON_API extern const LLUUID IMG_FIRE; |
57 | const LLUUID IMG_FACE_SELECT ("a85ac674-cb75-4af6-9499-df7c5aaf7a28"); // face selector | 54 | LL_COMMON_API extern const LLUUID IMG_FACE_SELECT; |
58 | const LLUUID IMG_DEFAULT_AVATAR ("c228d1cf-4b5d-4ba8-84f4-899a0796aa97"); // dataserver | 55 | LL_COMMON_API extern const LLUUID IMG_DEFAULT_AVATAR; |
59 | const LLUUID IMG_INVISIBLE ("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // dataserver | 56 | LL_COMMON_API extern const LLUUID IMG_INVISIBLE; |
60 | 57 | ||
61 | const LLUUID IMG_EXPLOSION ("68edcf47-ccd7-45b8-9f90-1649d7f12806"); // On dataserver | 58 | LL_COMMON_API extern const LLUUID IMG_EXPLOSION; |
62 | const LLUUID IMG_EXPLOSION_2 ("21ce046c-83fe-430a-b629-c7660ac78d7c"); // On dataserver | 59 | LL_COMMON_API extern const LLUUID IMG_EXPLOSION_2; |
63 | const LLUUID IMG_EXPLOSION_3 ("fedea30a-1be8-47a6-bc06-337a04a39c4b"); // On dataserver | 60 | LL_COMMON_API extern const LLUUID IMG_EXPLOSION_3; |
64 | const LLUUID IMG_EXPLOSION_4 ("abf0d56b-82e5-47a2-a8ad-74741bb2c29e"); // On dataserver | 61 | LL_COMMON_API extern const LLUUID IMG_EXPLOSION_4; |
65 | const LLUUID IMG_SMOKE_POOF ("1e63e323-5fe0-452e-92f8-b98bd0f764e3"); // On dataserver | 62 | LL_COMMON_API extern const LLUUID IMG_SMOKE_POOF; |
66 | 63 | ||
67 | const LLUUID IMG_BIG_EXPLOSION_1 ("5e47a0dc-97bf-44e0-8b40-de06718cee9d"); // On dataserver | 64 | LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_1; |
68 | const LLUUID IMG_BIG_EXPLOSION_2 ("9c8eca51-53d5-42a7-bb58-cef070395db8"); // On dataserver | 65 | LL_COMMON_API extern const LLUUID IMG_BIG_EXPLOSION_2; |
69 | 66 | ||
70 | const LLUUID IMG_BLOOM1 ("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); // VIEWER | 67 | LL_COMMON_API extern const LLUUID IMG_BLOOM1; |
71 | const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER | 68 | LL_COMMON_API extern const LLUUID TERRAIN_DIRT_DETAIL; |
72 | const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER | 69 | LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL; |
73 | const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER | 70 | LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL; |
74 | const LLUUID TERRAIN_ROCK_DETAIL ("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER | 71 | LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL; |
75 | 72 | ||
76 | const LLUUID DEFAULT_WATER_NORMAL ("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER | 73 | LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL; |
77 | 74 | ||
75 | LL_COMMON_API extern const LLUUID DEFAULT_UNREZZED_AVATAR_PARTICLE; | ||
78 | #endif | 76 | #endif |
diff --git a/linden/indra/llcommon/indra_constants.cpp b/linden/indra/llcommon/indra_constants.cpp new file mode 100644 index 0000000..64cbb11 --- /dev/null +++ b/linden/indra/llcommon/indra_constants.cpp | |||
@@ -0,0 +1,47 @@ | |||
1 | /** | ||
2 | * @file indra_constants.cpp | ||
3 | * @brief some useful short term constants for Indra | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2010, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlife.com/developers/opensource/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #include "indra_constants.h" | ||
36 | |||
37 | #include "lluuid.h" | ||
38 | |||
39 | // "agent id" for things that should be done to ALL agents | ||
40 | const LLUUID LL_UUID_ALL_AGENTS("44e87126-e794-4ded-05b3-7c42da3d5cdb"); | ||
41 | |||
42 | // Governor Linden's agent id. | ||
43 | const LLUUID ALEXANDRIA_LINDEN_ID("ba2a564a-f0f1-4b82-9c61-b7520bfcd09f"); | ||
44 | const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); | ||
45 | const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); | ||
46 | // Maintenance's group id. | ||
47 | const LLUUID MAINTENANCE_GROUP_ID("dc7b21cd-3c89-fcaa-31c8-25f9ffd224cd"); | ||
diff --git a/linden/indra/llcommon/indra_constants.h b/linden/indra/llcommon/indra_constants.h index 96c0a1f..b765d4d 100644 --- a/linden/indra/llcommon/indra_constants.h +++ b/linden/indra/llcommon/indra_constants.h | |||
@@ -34,7 +34,9 @@ | |||
34 | #define LL_INDRA_CONSTANTS_H | 34 | #define LL_INDRA_CONSTANTS_H |
35 | 35 | ||
36 | #include "stdtypes.h" | 36 | #include "stdtypes.h" |
37 | #include "lluuid.h" | 37 | #include "llpreprocessor.h" |
38 | |||
39 | class LLUUID; | ||
38 | 40 | ||
39 | // At 45 Hz collisions seem stable and objects seem | 41 | // At 45 Hz collisions seem stable and objects seem |
40 | // to settle down at a reasonable rate. | 42 | // to settle down at a reasonable rate. |
@@ -151,6 +153,11 @@ const char WATER_LAYER_CODE = 'W'; | |||
151 | const char WIND_LAYER_CODE = '7'; | 153 | const char WIND_LAYER_CODE = '7'; |
152 | const char CLOUD_LAYER_CODE = '8'; | 154 | const char CLOUD_LAYER_CODE = '8'; |
153 | 155 | ||
156 | // Extended land layer for Aurora Sim | ||
157 | const char AURORA_LAND_LAYER_CODE = 'M'; | ||
158 | const char AURORA_WIND_LAYER_CODE = '9'; | ||
159 | const char AURORA_CLOUD_LAYER_CODE = ':'; | ||
160 | |||
154 | // keys | 161 | // keys |
155 | // Bit masks for various keyboard modifier keys. | 162 | // Bit masks for various keyboard modifier keys. |
156 | const MASK MASK_NONE = 0x0000; | 163 | const MASK MASK_NONE = 0x0000; |
@@ -261,14 +268,15 @@ const U8 GOD_LIKE = 1; | |||
261 | const U8 GOD_NOT = 0; | 268 | const U8 GOD_NOT = 0; |
262 | 269 | ||
263 | // "agent id" for things that should be done to ALL agents | 270 | // "agent id" for things that should be done to ALL agents |
264 | const LLUUID LL_UUID_ALL_AGENTS("44e87126-e794-4ded-05b3-7c42da3d5cdb"); | 271 | LL_COMMON_API extern const LLUUID LL_UUID_ALL_AGENTS; |
272 | |||
273 | // inventory library owner | ||
274 | LL_COMMON_API extern const LLUUID ALEXANDRIA_LINDEN_ID; | ||
265 | 275 | ||
266 | // Governor Linden's agent id. | 276 | LL_COMMON_API extern const LLUUID GOVERNOR_LINDEN_ID; |
267 | const LLUUID ALEXANDRIA_LINDEN_ID("ba2a564a-f0f1-4b82-9c61-b7520bfcd09f"); | 277 | LL_COMMON_API extern const LLUUID REALESTATE_LINDEN_ID; |
268 | const LLUUID GOVERNOR_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); | ||
269 | const LLUUID REALESTATE_LINDEN_ID("3d6181b0-6a4b-97ef-18d8-722652995cf1"); | ||
270 | // Maintenance's group id. | 278 | // Maintenance's group id. |
271 | const LLUUID MAINTENANCE_GROUP_ID("dc7b21cd-3c89-fcaa-31c8-25f9ffd224cd"); | 279 | LL_COMMON_API extern const LLUUID MAINTENANCE_GROUP_ID; |
272 | 280 | ||
273 | // Flags for kick message | 281 | // Flags for kick message |
274 | const U32 KICK_FLAGS_DEFAULT = 0x0; | 282 | const U32 KICK_FLAGS_DEFAULT = 0x0; |
diff --git a/linden/indra/llcommon/linden_common.h b/linden/indra/llcommon/linden_common.h index 25dd629..bf844b9 100644 --- a/linden/indra/llcommon/linden_common.h +++ b/linden/indra/llcommon/linden_common.h | |||
@@ -51,16 +51,16 @@ | |||
51 | #include <cstdio> | 51 | #include <cstdio> |
52 | #include <cstdlib> | 52 | #include <cstdlib> |
53 | #include <ctime> | 53 | #include <ctime> |
54 | #include <iostream> | 54 | #include <iosfwd> |
55 | #include <fstream> | ||
56 | 55 | ||
57 | // Work Microsoft compiler warnings | 56 | // Work around Microsoft compiler warnings in STL headers |
58 | #ifdef LL_WINDOWS | 57 | #ifdef LL_WINDOWS |
59 | #pragma warning (disable : 4702) // unreachable code | 58 | #pragma warning (disable : 4702) // unreachable code |
60 | #pragma warning (disable : 4244) // conversion from time_t to S32 | 59 | #pragma warning (disable : 4244) // conversion from time_t to S32 |
61 | #endif // LL_WINDOWS | 60 | #endif // LL_WINDOWS |
62 | 61 | ||
63 | #include <algorithm> | 62 | // *TODO: Eliminate these, most library .cpp files don't need them. |
63 | // Add them to llviewerprecompiledheaders.h if necessary. | ||
64 | #include <list> | 64 | #include <list> |
65 | #include <map> | 65 | #include <map> |
66 | #include <vector> | 66 | #include <vector> |
@@ -76,18 +76,21 @@ | |||
76 | #pragma warning (disable : 4512) // assignment operator could not be generated | 76 | #pragma warning (disable : 4512) // assignment operator could not be generated |
77 | #pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) | 77 | #pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) |
78 | #pragma warning (disable : 4265) // boost 1.36.0, non-virtual destructor in boost::exception_detail::* | 78 | #pragma warning (disable : 4265) // boost 1.36.0, non-virtual destructor in boost::exception_detail::* |
79 | |||
80 | // Reenable warnings we disabled above | ||
81 | #pragma warning (3 : 4702) // unreachable code, we like level 3, not 4 | ||
82 | // moved msvc warnings to llpreprocessor.h *TODO - delete this comment after merge conflicts are unlikely -brad | ||
79 | #endif // LL_WINDOWS | 83 | #endif // LL_WINDOWS |
80 | 84 | ||
81 | // Linden only libs in alpha-order other than stdtypes.h | 85 | // Linden only libs in alpha-order other than stdtypes.h |
86 | // *NOTE: Please keep includes here to a minimum, see above. | ||
82 | #include "stdtypes.h" | 87 | #include "stdtypes.h" |
83 | #include "lldefs.h" | 88 | #include "lldefs.h" |
84 | #include "llerror.h" | 89 | #include "llerror.h" |
85 | #include "llextendedstatus.h" | 90 | #include "llextendedstatus.h" |
86 | #include "llfasttimer.h" | 91 | // Don't do this, adds 15K lines of header code to every library file. |
92 | //#include "llfasttimer.h" | ||
87 | #include "llfile.h" | 93 | #include "llfile.h" |
88 | #include "llformat.h" | 94 | #include "llformat.h" |
89 | #include "llstring.h" | ||
90 | #include "llsys.h" | ||
91 | #include "lltimer.h" | ||
92 | 95 | ||
93 | #endif | 96 | #endif |
diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index 199315f..eedc503 100644 --- a/linden/indra/llcommon/llapp.cpp +++ b/linden/indra/llcommon/llapp.cpp | |||
@@ -119,13 +119,8 @@ void LLApp::commonCtor() | |||
119 | mOptions.append(sd); | 119 | mOptions.append(sd); |
120 | } | 120 | } |
121 | 121 | ||
122 | // Make sure we clean up APR when we exit | ||
123 | // Don't need to do this if we're cleaning up APR in the destructor | ||
124 | //atexit(ll_cleanup_apr); | ||
125 | |||
126 | // Set the application to this instance. | 122 | // Set the application to this instance. |
127 | sApplication = this; | 123 | sApplication = this; |
128 | |||
129 | } | 124 | } |
130 | 125 | ||
131 | LLApp::LLApp(LLErrorThread *error_thread) : | 126 | LLApp::LLApp(LLErrorThread *error_thread) : |
@@ -420,7 +415,7 @@ void LLApp::incSigChildCount() | |||
420 | int LLApp::getPid() | 415 | int LLApp::getPid() |
421 | { | 416 | { |
422 | #if LL_WINDOWS | 417 | #if LL_WINDOWS |
423 | return 0; | 418 | return GetCurrentProcessId(); |
424 | #else | 419 | #else |
425 | return getpid(); | 420 | return getpid(); |
426 | #endif | 421 | #endif |
diff --git a/linden/indra/llcommon/llapp.h b/linden/indra/llcommon/llapp.h index f8a593c..96112c9 100644 --- a/linden/indra/llcommon/llapp.h +++ b/linden/indra/llcommon/llapp.h | |||
@@ -34,14 +34,17 @@ | |||
34 | #define LL_LLAPP_H | 34 | #define LL_LLAPP_H |
35 | 35 | ||
36 | #include <map> | 36 | #include <map> |
37 | #include "llapr.h" | ||
38 | #include "llrun.h" | 37 | #include "llrun.h" |
39 | #include "llsd.h" | 38 | #include "llsd.h" |
40 | 39 | ||
41 | // Forward declarations | 40 | // Forward declarations |
41 | template <typename Type> class LLAtomic32; | ||
42 | typedef LLAtomic32<U32> LLAtomicU32; | ||
42 | class LLErrorThread; | 43 | class LLErrorThread; |
43 | class LLApp; | 44 | class LLLiveFile; |
44 | 45 | #if LL_LINUX | |
46 | typedef struct siginfo siginfo_t; | ||
47 | #endif | ||
45 | 48 | ||
46 | typedef void (*LLAppErrorHandler)(); | 49 | typedef void (*LLAppErrorHandler)(); |
47 | typedef void (*LLAppChildCallback)(int pid, bool exited, int status); | 50 | typedef void (*LLAppChildCallback)(int pid, bool exited, int status); |
@@ -62,7 +65,7 @@ public: | |||
62 | }; | 65 | }; |
63 | #endif | 66 | #endif |
64 | 67 | ||
65 | class LLApp | 68 | class LL_COMMON_API LLApp |
66 | { | 69 | { |
67 | friend class LLErrorThread; | 70 | friend class LLErrorThread; |
68 | public: | 71 | public: |
@@ -189,8 +192,6 @@ public: | |||
189 | #if !LL_WINDOWS | 192 | #if !LL_WINDOWS |
190 | static U32 getSigChildCount(); | 193 | static U32 getSigChildCount(); |
191 | static void incSigChildCount(); | 194 | static void incSigChildCount(); |
192 | #else | ||
193 | #define getpid GetCurrentProcessId | ||
194 | #endif | 195 | #endif |
195 | static int getPid(); | 196 | static int getPid(); |
196 | 197 | ||
diff --git a/linden/indra/llcommon/llapr.cpp b/linden/indra/llcommon/llapr.cpp index 7e3a26c..a013d9c 100644 --- a/linden/indra/llcommon/llapr.cpp +++ b/linden/indra/llcommon/llapr.cpp | |||
@@ -34,220 +34,7 @@ | |||
34 | 34 | ||
35 | #include "linden_common.h" | 35 | #include "linden_common.h" |
36 | #include "llapr.h" | 36 | #include "llapr.h" |
37 | 37 | #include "llscopedvolatileaprpool.h" | |
38 | apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool | ||
39 | apr_thread_mutex_t *gLogMutexp = NULL; | ||
40 | apr_thread_mutex_t *gCallStacksLogMutexp = NULL; | ||
41 | |||
42 | const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool | ||
43 | |||
44 | void ll_init_apr() | ||
45 | { | ||
46 | if (!gAPRPoolp) | ||
47 | { | ||
48 | // Initialize APR and create the global pool | ||
49 | apr_initialize(); | ||
50 | apr_pool_create(&gAPRPoolp, NULL); | ||
51 | |||
52 | // Initialize the logging mutex | ||
53 | apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); | ||
54 | apr_thread_mutex_create(&gCallStacksLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp); | ||
55 | |||
56 | // Initialize thread-local APR pool support. | ||
57 | LLVolatileAPRPool::initLocalAPRFilePool(); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | |||
62 | void ll_cleanup_apr() | ||
63 | { | ||
64 | LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; | ||
65 | |||
66 | if (gLogMutexp) | ||
67 | { | ||
68 | // Clean up the logging mutex | ||
69 | |||
70 | // All other threads NEED to be done before we clean up APR, so this is okay. | ||
71 | apr_thread_mutex_destroy(gLogMutexp); | ||
72 | gLogMutexp = NULL; | ||
73 | } | ||
74 | if (gCallStacksLogMutexp) | ||
75 | { | ||
76 | // Clean up the logging mutex | ||
77 | |||
78 | // All other threads NEED to be done before we clean up APR, so this is okay. | ||
79 | apr_thread_mutex_destroy(gCallStacksLogMutexp); | ||
80 | gCallStacksLogMutexp = NULL; | ||
81 | } | ||
82 | if (gAPRPoolp) | ||
83 | { | ||
84 | apr_pool_destroy(gAPRPoolp); | ||
85 | gAPRPoolp = NULL; | ||
86 | } | ||
87 | apr_terminate(); | ||
88 | } | ||
89 | |||
90 | // | ||
91 | // | ||
92 | //LLAPRPool | ||
93 | // | ||
94 | LLAPRPool::LLAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) | ||
95 | { | ||
96 | mParent = parent ; | ||
97 | mReleasePoolFlag = releasePoolFlag ; | ||
98 | mMaxSize = size ; | ||
99 | mPool = NULL ; | ||
100 | |||
101 | createAPRPool() ; | ||
102 | } | ||
103 | |||
104 | LLAPRPool::~LLAPRPool() | ||
105 | { | ||
106 | releaseAPRPool() ; | ||
107 | } | ||
108 | |||
109 | void LLAPRPool::createAPRPool() | ||
110 | { | ||
111 | if(mPool) | ||
112 | { | ||
113 | return ; | ||
114 | } | ||
115 | |||
116 | mStatus = apr_pool_create(&mPool, mParent); | ||
117 | ll_apr_warn_status(mStatus) ; | ||
118 | |||
119 | if(mMaxSize > 0) //size is the number of blocks (which is usually 4K), NOT bytes. | ||
120 | { | ||
121 | apr_allocator_t *allocator = apr_pool_allocator_get(mPool); | ||
122 | if (allocator) | ||
123 | { | ||
124 | apr_allocator_max_free_set(allocator, mMaxSize) ; | ||
125 | } | ||
126 | } | ||
127 | } | ||
128 | |||
129 | void LLAPRPool::releaseAPRPool() | ||
130 | { | ||
131 | if(!mPool) | ||
132 | { | ||
133 | return ; | ||
134 | } | ||
135 | |||
136 | if(!mParent || mReleasePoolFlag) | ||
137 | { | ||
138 | apr_pool_destroy(mPool) ; | ||
139 | mPool = NULL ; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | apr_pool_t* LLAPRPool::getAPRPool() | ||
144 | { | ||
145 | if(!mPool) | ||
146 | { | ||
147 | createAPRPool() ; | ||
148 | } | ||
149 | |||
150 | return mPool ; | ||
151 | } | ||
152 | LLVolatileAPRPool::LLVolatileAPRPool(apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) | ||
153 | : LLAPRPool(parent, size, releasePoolFlag) | ||
154 | { | ||
155 | mNumActiveRef = 0 ; | ||
156 | mNumTotalRef = 0 ; | ||
157 | } | ||
158 | |||
159 | apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() | ||
160 | { | ||
161 | mNumTotalRef++ ; | ||
162 | mNumActiveRef++ ; | ||
163 | return getAPRPool() ; | ||
164 | } | ||
165 | |||
166 | void LLVolatileAPRPool::clearVolatileAPRPool() | ||
167 | { | ||
168 | if(mNumActiveRef > 0) | ||
169 | { | ||
170 | mNumActiveRef--; | ||
171 | if(mNumActiveRef < 1) | ||
172 | { | ||
173 | if(isFull()) | ||
174 | { | ||
175 | mNumTotalRef = 0 ; | ||
176 | |||
177 | //destroy the apr_pool. | ||
178 | releaseAPRPool() ; | ||
179 | } | ||
180 | else | ||
181 | { | ||
182 | //This does not actually free the memory, | ||
183 | //it just allows the pool to re-use this memory for the next allocation. | ||
184 | apr_pool_clear(mPool) ; | ||
185 | } | ||
186 | } | ||
187 | } | ||
188 | else | ||
189 | { | ||
190 | llassert_always(mNumActiveRef > 0) ; | ||
191 | } | ||
192 | |||
193 | //paranoia check if the pool is jammed. | ||
194 | //will remove the check before going to release. | ||
195 | llassert_always(mNumTotalRef < (FULL_VOLATILE_APR_POOL << 2)) ; | ||
196 | } | ||
197 | |||
198 | BOOL LLVolatileAPRPool::isFull() | ||
199 | { | ||
200 | return mNumTotalRef > FULL_VOLATILE_APR_POOL ; | ||
201 | } | ||
202 | |||
203 | #ifdef SHOW_ASSERT | ||
204 | // This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. | ||
205 | static void* gIsMainThread; | ||
206 | bool is_main_thread() { return gIsMainThread == LLVolatileAPRPool::getLocalAPRFilePool(); } | ||
207 | #endif | ||
208 | |||
209 | // The thread private handle to access the LocalAPRFilePool. | ||
210 | apr_threadkey_t* LLVolatileAPRPool::sLocalAPRFilePoolKey; | ||
211 | |||
212 | // This should be called exactly once, before the first call to createLocalAPRFilePool. | ||
213 | // static | ||
214 | void LLVolatileAPRPool::initLocalAPRFilePool() | ||
215 | { | ||
216 | apr_status_t status = apr_threadkey_private_create(&sLocalAPRFilePoolKey, &destroyLocalAPRFilePool, gAPRPoolp); | ||
217 | ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the | ||
218 | // total number of keys per process {PTHREAD_KEYS_MAX} | ||
219 | // has been exceeded. | ||
220 | // Create the thread-local pool for the main thread (this function is called by the main thread). | ||
221 | createLocalAPRFilePool(); | ||
222 | #ifdef SHOW_ASSERT | ||
223 | gIsMainThread = getLocalAPRFilePool(); | ||
224 | #endif | ||
225 | } | ||
226 | |||
227 | // This should be called once for every thread, before it uses getLocalAPRFilePool. | ||
228 | // static | ||
229 | void LLVolatileAPRPool::createLocalAPRFilePool() | ||
230 | { | ||
231 | void* thread_local_data = new LLVolatileAPRPool; | ||
232 | apr_status_t status = apr_threadkey_private_set(thread_local_data, sLocalAPRFilePoolKey); | ||
233 | llassert_always(status == APR_SUCCESS); | ||
234 | } | ||
235 | |||
236 | // This is called once for every thread when the thread is destructed. | ||
237 | // static | ||
238 | void LLVolatileAPRPool::destroyLocalAPRFilePool(void* thread_local_data) | ||
239 | { | ||
240 | delete reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); | ||
241 | } | ||
242 | |||
243 | // static | ||
244 | LLVolatileAPRPool* LLVolatileAPRPool::getLocalAPRFilePool() | ||
245 | { | ||
246 | void* thread_local_data; | ||
247 | apr_status_t status = apr_threadkey_private_get(&thread_local_data, sLocalAPRFilePoolKey); | ||
248 | llassert_always(status == APR_SUCCESS); | ||
249 | return reinterpret_cast<LLVolatileAPRPool*>(thread_local_data); | ||
250 | } | ||
251 | 38 | ||
252 | //--------------------------------------------------------------------- | 39 | //--------------------------------------------------------------------- |
253 | // | 40 | // |
@@ -310,13 +97,15 @@ void ll_apr_assert_status(apr_status_t status) | |||
310 | // | 97 | // |
311 | LLAPRFile::LLAPRFile() | 98 | LLAPRFile::LLAPRFile() |
312 | : mFile(NULL), | 99 | : mFile(NULL), |
313 | mCurrentFilePoolp(NULL) | 100 | mVolatileFilePoolp(NULL), |
101 | mRegularFilePoolp(NULL) | ||
314 | { | 102 | { |
315 | } | 103 | } |
316 | 104 | ||
317 | LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) | 105 | LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) |
318 | : mFile(NULL), | 106 | : mFile(NULL), |
319 | mCurrentFilePoolp(NULL) | 107 | mVolatileFilePoolp(NULL), |
108 | mRegularFilePoolp(NULL) | ||
320 | { | 109 | { |
321 | open(filename, flags, access_type); | 110 | open(filename, flags, access_type); |
322 | } | 111 | } |
@@ -335,10 +124,16 @@ apr_status_t LLAPRFile::close() | |||
335 | mFile = NULL ; | 124 | mFile = NULL ; |
336 | } | 125 | } |
337 | 126 | ||
338 | if(mCurrentFilePoolp) | 127 | if (mVolatileFilePoolp) |
339 | { | 128 | { |
340 | mCurrentFilePoolp->clearVolatileAPRPool() ; | 129 | mVolatileFilePoolp->clearVolatileAPRPool() ; |
341 | mCurrentFilePoolp = NULL ; | 130 | mVolatileFilePoolp = NULL ; |
131 | } | ||
132 | |||
133 | if (mRegularFilePoolp) | ||
134 | { | ||
135 | delete mRegularFilePoolp; | ||
136 | mRegularFilePoolp = NULL; | ||
342 | } | 137 | } |
343 | 138 | ||
344 | return ret ; | 139 | return ret ; |
@@ -347,25 +142,28 @@ apr_status_t LLAPRFile::close() | |||
347 | apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) | 142 | apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) |
348 | { | 143 | { |
349 | llassert_always(!mFile); | 144 | llassert_always(!mFile); |
350 | llassert_always(!mCurrentFilePoolp); | 145 | llassert_always(!mVolatileFilePoolp && !mRegularFilePoolp); |
351 | 146 | ||
352 | // Access the pool and increment it's reference count. | 147 | apr_status_t status; |
353 | // The reference count of LLVolatileAPRPool objects will be decremented | ||
354 | // again in LLAPRFile::close by calling mCurrentFilePoolp->clearVolatileAPRPool(). | ||
355 | apr_pool_t* pool; | ||
356 | if (access_type == local) | ||
357 | { | ||
358 | // Use a "volatile" thread-local pool. | ||
359 | mCurrentFilePoolp = LLVolatileAPRPool::getLocalAPRFilePool(); | ||
360 | pool = mCurrentFilePoolp->getVolatileAPRPool(); | ||
361 | } | ||
362 | else | ||
363 | { | 148 | { |
364 | llassert(is_main_thread()); | 149 | apr_pool_t* apr_file_open_pool; |
365 | pool = gAPRPoolp; | 150 | if (access_type == local) |
151 | { | ||
152 | // Use a "volatile" thread-local pool. | ||
153 | mVolatileFilePoolp = &AIThreadLocalData::tldata().mVolatileAPRPool; | ||
154 | // Access the pool and increment it's reference count. | ||
155 | // The reference count of AIVolatileAPRPool objects will be decremented | ||
156 | // again in LLAPRFile::close by calling mVolatileFilePoolp->clearVolatileAPRPool(). | ||
157 | apr_file_open_pool = mVolatileFilePoolp->getVolatileAPRPool(); | ||
158 | } | ||
159 | else | ||
160 | { | ||
161 | mRegularFilePoolp = new AIAPRPool(AIThreadLocalData::tldata().mRootPool); | ||
162 | apr_file_open_pool = (*mRegularFilePoolp)(); | ||
163 | } | ||
164 | status = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, apr_file_open_pool); | ||
366 | } | 165 | } |
367 | apr_status_t s = apr_file_open(&mFile, filename.c_str(), flags, APR_OS_DEFAULT, pool); | 166 | if (status != APR_SUCCESS || !mFile) |
368 | if (s != APR_SUCCESS || !mFile) | ||
369 | { | 167 | { |
370 | mFile = NULL ; | 168 | mFile = NULL ; |
371 | close() ; | 169 | close() ; |
@@ -373,7 +171,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc | |||
373 | { | 171 | { |
374 | *sizep = 0; | 172 | *sizep = 0; |
375 | } | 173 | } |
376 | return s; | 174 | return status; |
377 | } | 175 | } |
378 | 176 | ||
379 | if (sizep) | 177 | if (sizep) |
@@ -390,7 +188,7 @@ apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, acc | |||
390 | *sizep = file_size; | 188 | *sizep = file_size; |
391 | } | 189 | } |
392 | 190 | ||
393 | return s; | 191 | return status; |
394 | } | 192 | } |
395 | 193 | ||
396 | // File I/O | 194 | // File I/O |
@@ -440,17 +238,6 @@ S32 LLAPRFile::seek(apr_seek_where_t where, S32 offset) | |||
440 | //static components of LLAPRFile | 238 | //static components of LLAPRFile |
441 | // | 239 | // |
442 | 240 | ||
443 | // Used in the static functions below. | ||
444 | class LLScopedVolatileAPRFilePool { | ||
445 | private: | ||
446 | LLVolatileAPRPool* mPool; | ||
447 | apr_pool_t* apr_pool; | ||
448 | public: | ||
449 | LLScopedVolatileAPRFilePool() : mPool(LLVolatileAPRPool::getLocalAPRFilePool()), apr_pool(mPool->getVolatileAPRPool()) { } | ||
450 | ~LLScopedVolatileAPRFilePool() { mPool->clearVolatileAPRPool(); } | ||
451 | operator apr_pool_t*() const { return apr_pool; } | ||
452 | }; | ||
453 | |||
454 | //static | 241 | //static |
455 | S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) | 242 | S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) |
456 | { | 243 | { |
@@ -487,7 +274,7 @@ S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) | |||
487 | S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) | 274 | S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) |
488 | { | 275 | { |
489 | apr_file_t* file_handle; | 276 | apr_file_t* file_handle; |
490 | LLScopedVolatileAPRFilePool pool; | 277 | LLScopedVolatileAPRPool pool; |
491 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); | 278 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), APR_READ|APR_BINARY, APR_OS_DEFAULT, pool); |
492 | if (s != APR_SUCCESS || !file_handle) | 279 | if (s != APR_SUCCESS || !file_handle) |
493 | { | 280 | { |
@@ -539,7 +326,7 @@ S32 LLAPRFile::writeEx(const std::string& filename, void *buf, S32 offset, S32 n | |||
539 | } | 326 | } |
540 | 327 | ||
541 | apr_file_t* file_handle; | 328 | apr_file_t* file_handle; |
542 | LLScopedVolatileAPRFilePool pool; | 329 | LLScopedVolatileAPRPool pool; |
543 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); | 330 | apr_status_t s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); |
544 | if (s != APR_SUCCESS || !file_handle) | 331 | if (s != APR_SUCCESS || !file_handle) |
545 | { | 332 | { |
@@ -584,7 +371,7 @@ bool LLAPRFile::remove(const std::string& filename) | |||
584 | { | 371 | { |
585 | apr_status_t s; | 372 | apr_status_t s; |
586 | 373 | ||
587 | LLScopedVolatileAPRFilePool pool; | 374 | LLScopedVolatileAPRPool pool; |
588 | s = apr_file_remove(filename.c_str(), pool); | 375 | s = apr_file_remove(filename.c_str(), pool); |
589 | 376 | ||
590 | if (s != APR_SUCCESS) | 377 | if (s != APR_SUCCESS) |
@@ -601,7 +388,7 @@ bool LLAPRFile::rename(const std::string& filename, const std::string& newname) | |||
601 | { | 388 | { |
602 | apr_status_t s; | 389 | apr_status_t s; |
603 | 390 | ||
604 | LLScopedVolatileAPRFilePool pool; | 391 | LLScopedVolatileAPRPool pool; |
605 | s = apr_file_rename(filename.c_str(), newname.c_str(), pool); | 392 | s = apr_file_rename(filename.c_str(), newname.c_str(), pool); |
606 | 393 | ||
607 | if (s != APR_SUCCESS) | 394 | if (s != APR_SUCCESS) |
@@ -619,7 +406,7 @@ bool LLAPRFile::isExist(const std::string& filename, apr_int32_t flags) | |||
619 | apr_file_t* file_handle; | 406 | apr_file_t* file_handle; |
620 | apr_status_t s; | 407 | apr_status_t s; |
621 | 408 | ||
622 | LLScopedVolatileAPRFilePool pool; | 409 | LLScopedVolatileAPRPool pool; |
623 | s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); | 410 | s = apr_file_open(&file_handle, filename.c_str(), flags, APR_OS_DEFAULT, pool); |
624 | 411 | ||
625 | if (s != APR_SUCCESS || !file_handle) | 412 | if (s != APR_SUCCESS || !file_handle) |
@@ -640,7 +427,7 @@ S32 LLAPRFile::size(const std::string& filename) | |||
640 | apr_finfo_t info; | 427 | apr_finfo_t info; |
641 | apr_status_t s; | 428 | apr_status_t s; |
642 | 429 | ||
643 | LLScopedVolatileAPRFilePool pool; | 430 | LLScopedVolatileAPRPool pool; |
644 | s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); | 431 | s = apr_file_open(&file_handle, filename.c_str(), APR_READ, APR_OS_DEFAULT, pool); |
645 | 432 | ||
646 | if (s != APR_SUCCESS || !file_handle) | 433 | if (s != APR_SUCCESS || !file_handle) |
@@ -669,7 +456,7 @@ bool LLAPRFile::makeDir(const std::string& dirname) | |||
669 | { | 456 | { |
670 | apr_status_t s; | 457 | apr_status_t s; |
671 | 458 | ||
672 | LLScopedVolatileAPRFilePool pool; | 459 | LLScopedVolatileAPRPool pool; |
673 | s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); | 460 | s = apr_dir_make(dirname.c_str(), APR_FPROT_OS_DEFAULT, pool); |
674 | 461 | ||
675 | if (s != APR_SUCCESS) | 462 | if (s != APR_SUCCESS) |
@@ -686,7 +473,7 @@ bool LLAPRFile::removeDir(const std::string& dirname) | |||
686 | { | 473 | { |
687 | apr_status_t s; | 474 | apr_status_t s; |
688 | 475 | ||
689 | LLScopedVolatileAPRFilePool pool; | 476 | LLScopedVolatileAPRPool pool; |
690 | s = apr_file_remove(dirname.c_str(), pool); | 477 | s = apr_file_remove(dirname.c_str(), pool); |
691 | 478 | ||
692 | if (s != APR_SUCCESS) | 479 | if (s != APR_SUCCESS) |
diff --git a/linden/indra/llcommon/llapr.h b/linden/indra/llcommon/llapr.h index 7f770b0..ded15f5 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h | |||
@@ -48,74 +48,8 @@ | |||
48 | #include "apr_atomic.h" | 48 | #include "apr_atomic.h" |
49 | #include "llstring.h" | 49 | #include "llstring.h" |
50 | 50 | ||
51 | extern apr_thread_mutex_t* gLogMutexp; | 51 | class AIAPRPool; |
52 | extern apr_thread_mutex_t* gCallStacksLogMutexp; | 52 | class AIVolatileAPRPool; |
53 | |||
54 | /** | ||
55 | * @brief initialize the common apr constructs -- apr itself, the | ||
56 | * global pool, and a mutex. | ||
57 | */ | ||
58 | void ll_init_apr(); | ||
59 | |||
60 | /** | ||
61 | * @brief Cleanup those common apr constructs. | ||
62 | */ | ||
63 | void ll_cleanup_apr(); | ||
64 | |||
65 | // | ||
66 | //LL apr_pool | ||
67 | //manage apr_pool_t, destroy allocated apr_pool in the destruction function. | ||
68 | // | ||
69 | class LLAPRPool | ||
70 | { | ||
71 | public: | ||
72 | LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; | ||
73 | ~LLAPRPool() ; | ||
74 | |||
75 | apr_pool_t* getAPRPool() ; | ||
76 | apr_status_t getStatus() {return mStatus ; } | ||
77 | |||
78 | protected: | ||
79 | void releaseAPRPool() ; | ||
80 | void createAPRPool() ; | ||
81 | |||
82 | protected: | ||
83 | apr_pool_t* mPool ; //pointing to an apr_pool | ||
84 | apr_pool_t* mParent ; //parent pool | ||
85 | apr_size_t mMaxSize ; //max size of mPool, mPool should return memory to system if allocated memory beyond this limit. However it seems not to work. | ||
86 | apr_status_t mStatus ; //status when creating the pool | ||
87 | BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true. | ||
88 | }; | ||
89 | |||
90 | // | ||
91 | //volatile LL apr_pool | ||
92 | //which clears memory automatically. | ||
93 | //so it can not hold static data or data after memory is cleared | ||
94 | // | ||
95 | class LLVolatileAPRPool : protected LLAPRPool | ||
96 | { | ||
97 | public: | ||
98 | LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); | ||
99 | ~LLVolatileAPRPool(){} | ||
100 | |||
101 | apr_pool_t* getVolatileAPRPool() ; | ||
102 | |||
103 | void clearVolatileAPRPool() ; | ||
104 | |||
105 | BOOL isFull() ; | ||
106 | BOOL isEmpty() {return !mNumActiveRef ;} | ||
107 | |||
108 | static void initLocalAPRFilePool(); | ||
109 | static void createLocalAPRFilePool(); | ||
110 | static void destroyLocalAPRFilePool(void* thread_local_data); | ||
111 | static LLVolatileAPRPool* getLocalAPRFilePool(); | ||
112 | |||
113 | private: | ||
114 | S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. | ||
115 | S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. | ||
116 | |||
117 | static apr_threadkey_t* sLocalAPRFilePoolKey; | ||
118 | } ; | ||
119 | 53 | ||
120 | /** | 54 | /** |
121 | * @class LLScopedLock | 55 | * @class LLScopedLock |
@@ -126,7 +60,7 @@ private: | |||
126 | * destructor handles the unlock. Instances of this class are | 60 | * destructor handles the unlock. Instances of this class are |
127 | * <b>not</b> thread safe. | 61 | * <b>not</b> thread safe. |
128 | */ | 62 | */ |
129 | class LLScopedLock : private boost::noncopyable | 63 | class LL_COMMON_API LLScopedLock : private boost::noncopyable |
130 | { | 64 | { |
131 | public: | 65 | public: |
132 | /** | 66 | /** |
@@ -201,12 +135,13 @@ typedef LLAtomic32<S32> LLAtomicS32; | |||
201 | // 2, a global pool. | 135 | // 2, a global pool. |
202 | // | 136 | // |
203 | 137 | ||
204 | class LLAPRFile : boost::noncopyable | 138 | class LL_COMMON_API LLAPRFile : boost::noncopyable |
205 | { | 139 | { |
206 | // make this non copyable since a copy closes the file | 140 | // make this non copyable since a copy closes the file |
207 | private: | 141 | private: |
208 | apr_file_t* mFile ; | 142 | apr_file_t* mFile ; |
209 | LLVolatileAPRPool *mCurrentFilePoolp ; //currently in use apr_pool, could be one of them: sAPRFilePoolp, or a temp pool. | 143 | AIVolatileAPRPool* mVolatileFilePoolp; // (Thread local) APR pool currently in use. |
144 | AIAPRPool* mRegularFilePoolp; // ...or a regular pool. | ||
210 | 145 | ||
211 | public: | 146 | public: |
212 | enum access_t { | 147 | enum access_t { |
@@ -257,10 +192,8 @@ public: | |||
257 | * APR_SUCCESS. | 192 | * APR_SUCCESS. |
258 | * @return Returns <code>true</code> if status is an error condition. | 193 | * @return Returns <code>true</code> if status is an error condition. |
259 | */ | 194 | */ |
260 | bool ll_apr_warn_status(apr_status_t status); | 195 | bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); |
261 | |||
262 | void ll_apr_assert_status(apr_status_t status); | ||
263 | 196 | ||
264 | extern "C" apr_pool_t* gAPRPoolp; // Global APR memory pool | 197 | void LL_COMMON_API ll_apr_assert_status(apr_status_t status); |
265 | 198 | ||
266 | #endif // LL_LLAPR_H | 199 | #endif // LL_LLAPR_H |
diff --git a/linden/indra/llcommon/llassettype.h b/linden/indra/llcommon/llassettype.h index 4077b8d..9f611ae 100644 --- a/linden/indra/llcommon/llassettype.h +++ b/linden/indra/llcommon/llassettype.h | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #include "stdenums.h" // for EDragAndDropType | 38 | #include "stdenums.h" // for EDragAndDropType |
39 | 39 | ||
40 | class LLAssetType | 40 | class LL_COMMON_API LLAssetType |
41 | { | 41 | { |
42 | public: | 42 | public: |
43 | enum EType | 43 | enum EType |
diff --git a/linden/indra/llcommon/llavatarname.cpp b/linden/indra/llcommon/llavatarname.cpp new file mode 100644 index 0000000..ebe8c88 --- /dev/null +++ b/linden/indra/llcommon/llavatarname.cpp | |||
@@ -0,0 +1,150 @@ | |||
1 | /** | ||
2 | * @file llavatarname.cpp | ||
3 | * @brief Represents name-related data for an avatar, such as the | ||
4 | * username/SLID ("bobsmith123" or "james.linden") and the display | ||
5 | * name ("James Cook") | ||
6 | * | ||
7 | * $LicenseInfo:firstyear=2010&license=viewerlgpl$ | ||
8 | * Second Life Viewer Source Code | ||
9 | * Copyright (C) 2010, Linden Research, Inc. | ||
10 | * | ||
11 | * This library is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU Lesser General Public | ||
13 | * License as published by the Free Software Foundation; | ||
14 | * version 2.1 of the License only. | ||
15 | * | ||
16 | * This library is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * Lesser General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Lesser General Public | ||
22 | * License along with this library; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA | ||
26 | * $/LicenseInfo$ | ||
27 | */ | ||
28 | #include "linden_common.h" | ||
29 | |||
30 | #include "llavatarname.h" | ||
31 | |||
32 | #include "lldate.h" | ||
33 | #include "llsd.h" | ||
34 | |||
35 | bool LLAvatarName::sOmitResidentAsLastName = false; | ||
36 | |||
37 | // Store these in pre-built std::strings to avoid memory allocations in | ||
38 | // LLSD map lookups | ||
39 | static const std::string USERNAME("username"); | ||
40 | static const std::string DISPLAY_NAME("display_name"); | ||
41 | static const std::string LEGACY_FIRST_NAME("legacy_first_name"); | ||
42 | static const std::string LEGACY_LAST_NAME("legacy_last_name"); | ||
43 | static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default"); | ||
44 | static const std::string DISPLAY_NAME_EXPIRES("display_name_expires"); | ||
45 | static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update"); | ||
46 | |||
47 | LLAvatarName::LLAvatarName() | ||
48 | : mUsername(), | ||
49 | mDisplayName(), | ||
50 | mLegacyFirstName(), | ||
51 | mLegacyLastName(), | ||
52 | mIsDisplayNameDefault(false), | ||
53 | mIsDummy(false), | ||
54 | mExpires(F64_MAX), | ||
55 | mNextUpdate(0.0) | ||
56 | { } | ||
57 | |||
58 | bool LLAvatarName::operator<(const LLAvatarName& rhs) const | ||
59 | { | ||
60 | if (mUsername == rhs.mUsername) | ||
61 | return mDisplayName < rhs.mDisplayName; | ||
62 | else | ||
63 | return mUsername < rhs.mUsername; | ||
64 | } | ||
65 | |||
66 | LLSD LLAvatarName::asLLSD() const | ||
67 | { | ||
68 | LLSD sd; | ||
69 | sd[USERNAME] = mUsername; | ||
70 | sd[DISPLAY_NAME] = mDisplayName; | ||
71 | sd[LEGACY_FIRST_NAME] = mLegacyFirstName; | ||
72 | sd[LEGACY_LAST_NAME] = mLegacyLastName; | ||
73 | sd[IS_DISPLAY_NAME_DEFAULT] = mIsDisplayNameDefault; | ||
74 | sd[DISPLAY_NAME_EXPIRES] = LLDate(mExpires); | ||
75 | sd[DISPLAY_NAME_NEXT_UPDATE] = LLDate(mNextUpdate); | ||
76 | return sd; | ||
77 | } | ||
78 | |||
79 | void LLAvatarName::fromLLSD(const LLSD& sd) | ||
80 | { | ||
81 | mUsername = sd[USERNAME].asString(); | ||
82 | mDisplayName = sd[DISPLAY_NAME].asString(); | ||
83 | mLegacyFirstName = sd[LEGACY_FIRST_NAME].asString(); | ||
84 | mLegacyLastName = sd[LEGACY_LAST_NAME].asString(); | ||
85 | mIsDisplayNameDefault = sd[IS_DISPLAY_NAME_DEFAULT].asBoolean(); | ||
86 | LLDate expires = sd[DISPLAY_NAME_EXPIRES]; | ||
87 | mExpires = expires.secondsSinceEpoch(); | ||
88 | LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE]; | ||
89 | mNextUpdate = next_update.secondsSinceEpoch(); | ||
90 | } | ||
91 | |||
92 | std::string LLAvatarName::getCompleteName() const | ||
93 | { | ||
94 | std::string name; | ||
95 | if (!mUsername.empty()) | ||
96 | { | ||
97 | name = mDisplayName + " (" + mUsername + ")"; | ||
98 | } | ||
99 | else | ||
100 | { | ||
101 | // ...display names are off, legacy name is in mDisplayName | ||
102 | name = mDisplayName; | ||
103 | } | ||
104 | return name; | ||
105 | } | ||
106 | |||
107 | std::string LLAvatarName::getLegacyName() const | ||
108 | { | ||
109 | std::string name; | ||
110 | name.reserve(mLegacyFirstName.size() + 1 + mLegacyLastName.size()); | ||
111 | name = mLegacyFirstName; | ||
112 | if (!sOmitResidentAsLastName || mLegacyLastName != "Resident") | ||
113 | { | ||
114 | name += " "; | ||
115 | name += mLegacyLastName; | ||
116 | } | ||
117 | return name; | ||
118 | } | ||
119 | |||
120 | std::string LLAvatarName::getNames(bool linefeed) const | ||
121 | { | ||
122 | std::string name; | ||
123 | |||
124 | if (mUsername.empty()) | ||
125 | { | ||
126 | // ...display names are off, legacy name is in mDisplayName | ||
127 | name = mDisplayName; | ||
128 | if (sOmitResidentAsLastName) | ||
129 | { | ||
130 | LLStringUtil::replaceString(name, " Resident", ""); | ||
131 | } | ||
132 | } | ||
133 | else | ||
134 | { | ||
135 | name = getLegacyName(); | ||
136 | if (name != mDisplayName) | ||
137 | { | ||
138 | if (linefeed) | ||
139 | { | ||
140 | name = mDisplayName + "\n[" + name + "]"; | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | name = mDisplayName + " [" + name + "]"; | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | return name; | ||
150 | } | ||
diff --git a/linden/indra/llcommon/llavatarname.h b/linden/indra/llcommon/llavatarname.h new file mode 100644 index 0000000..3b6c6ea --- /dev/null +++ b/linden/indra/llcommon/llavatarname.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /** | ||
2 | * @file llavatarname.h | ||
3 | * @brief Represents name-related data for an avatar, such as the | ||
4 | * username/SLID ("bobsmith123" or "james.linden") and the display | ||
5 | * name ("James Cook") | ||
6 | * | ||
7 | * $LicenseInfo:firstyear=2010&license=viewerlgpl$ | ||
8 | * Second Life Viewer Source Code | ||
9 | * Copyright (C) 2010, Linden Research, Inc. | ||
10 | * | ||
11 | * This library is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU Lesser General Public | ||
13 | * License as published by the Free Software Foundation; | ||
14 | * version 2.1 of the License only. | ||
15 | * | ||
16 | * This library is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
19 | * Lesser General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU Lesser General Public | ||
22 | * License along with this library; if not, write to the Free Software | ||
23 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
24 | * | ||
25 | * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA | ||
26 | * $/LicenseInfo$ | ||
27 | */ | ||
28 | #ifndef LLAVATARNAME_H | ||
29 | #define LLAVATARNAME_H | ||
30 | |||
31 | #include <string> | ||
32 | |||
33 | class LLSD; | ||
34 | |||
35 | class LL_COMMON_API LLAvatarName | ||
36 | { | ||
37 | public: | ||
38 | LLAvatarName(); | ||
39 | |||
40 | bool operator<(const LLAvatarName& rhs) const; | ||
41 | |||
42 | LLSD asLLSD() const; | ||
43 | |||
44 | void fromLLSD(const LLSD& sd); | ||
45 | |||
46 | // For normal names, returns "James Linden (james.linden)" | ||
47 | // When display names are disabled returns just "James Linden" | ||
48 | std::string getCompleteName() const; | ||
49 | |||
50 | // For normal names, returns "Whatever Display Name (John Doe)" when | ||
51 | // display name and legacy name are different, or just "John Doe" | ||
52 | // when they are equal or when display names are disabled. | ||
53 | // When linefeed == true, the space between the display name and | ||
54 | // the opening parenthesis for the legacy name is replaced with a | ||
55 | // line feed. | ||
56 | std::string getNames(bool linefeed = false) const; | ||
57 | |||
58 | // Returns "James Linden" or "bobsmith123 Resident" for backwards | ||
59 | // compatibility with systems like voice and muting | ||
60 | std::string getLegacyName() const; | ||
61 | |||
62 | // "bobsmith123" or "james.linden", US-ASCII only | ||
63 | std::string mUsername; | ||
64 | |||
65 | // "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode | ||
66 | // Contains data whether or not user has explicitly set | ||
67 | // a display name; may duplicate their username. | ||
68 | std::string mDisplayName; | ||
69 | |||
70 | // For "James Linden", "James" | ||
71 | // For "bobsmith123", "bobsmith123" | ||
72 | // Used to communicate with legacy systems like voice and muting which | ||
73 | // rely on old-style names. | ||
74 | std::string mLegacyFirstName; | ||
75 | |||
76 | // For "James Linden", "Linden" | ||
77 | // For "bobsmith123", "Resident" | ||
78 | // see above for rationale | ||
79 | std::string mLegacyLastName; | ||
80 | |||
81 | // If true, both display name and SLID were generated from | ||
82 | // a legacy first and last name, like "James Linden (james.linden)" | ||
83 | bool mIsDisplayNameDefault; | ||
84 | |||
85 | // Under error conditions, we may insert "dummy" records with | ||
86 | // names equal to legacy name into caches as placeholders. | ||
87 | // These can be shown in UI, but are not serialized. | ||
88 | bool mIsDummy; | ||
89 | |||
90 | // Names can change, so need to keep track of when name was | ||
91 | // last checked. | ||
92 | // Unix time-from-epoch seconds for efficiency | ||
93 | F64 mExpires; | ||
94 | |||
95 | // You can only change your name every N hours, so record | ||
96 | // when the next update is allowed | ||
97 | // Unix time-from-epoch seconds | ||
98 | F64 mNextUpdate; | ||
99 | |||
100 | // true to prevent the displaying of "Resident" as a last name | ||
101 | // in legacy names | ||
102 | static bool sOmitResidentAsLastName; | ||
103 | }; | ||
104 | |||
105 | #endif | ||
diff --git a/linden/indra/llcommon/llbase32.h b/linden/indra/llcommon/llbase32.h index 63a93e1..47cd893 100644 --- a/linden/indra/llcommon/llbase32.h +++ b/linden/indra/llcommon/llbase32.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #ifndef LLBASE32_H | 34 | #ifndef LLBASE32_H |
35 | #define LLBASE32_h | 35 | #define LLBASE32_h |
36 | 36 | ||
37 | class LLBase32 | 37 | class LL_COMMON_API LLBase32 |
38 | { | 38 | { |
39 | public: | 39 | public: |
40 | static std::string encode(const U8* input, size_t input_size); | 40 | static std::string encode(const U8* input, size_t input_size); |
diff --git a/linden/indra/llcommon/llbase64.h b/linden/indra/llcommon/llbase64.h index 58414bb..15b27a6 100644 --- a/linden/indra/llcommon/llbase64.h +++ b/linden/indra/llcommon/llbase64.h | |||
@@ -34,7 +34,7 @@ | |||
34 | #ifndef LLBASE64_H | 34 | #ifndef LLBASE64_H |
35 | #define LLBASE64_h | 35 | #define LLBASE64_h |
36 | 36 | ||
37 | class LLBase64 | 37 | class LL_COMMON_API LLBase64 |
38 | { | 38 | { |
39 | public: | 39 | public: |
40 | static std::string encode(const U8* input, size_t input_size); | 40 | static std::string encode(const U8* input, size_t input_size); |
diff --git a/linden/indra/llcommon/llcommon.cpp b/linden/indra/llcommon/llcommon.cpp index 2cbb718..298dd46 100644 --- a/linden/indra/llcommon/llcommon.cpp +++ b/linden/indra/llcommon/llcommon.cpp | |||
@@ -35,17 +35,9 @@ | |||
35 | #include "llthread.h" | 35 | #include "llthread.h" |
36 | 36 | ||
37 | //static | 37 | //static |
38 | BOOL LLCommon::sAprInitialized = FALSE; | ||
39 | |||
40 | //static | ||
41 | void LLCommon::initClass() | 38 | void LLCommon::initClass() |
42 | { | 39 | { |
43 | LLMemory::initClass(); | 40 | LLMemory::initClass(); |
44 | if (!sAprInitialized) | ||
45 | { | ||
46 | ll_init_apr(); | ||
47 | sAprInitialized = TRUE; | ||
48 | } | ||
49 | LLTimer::initClass(); | 41 | LLTimer::initClass(); |
50 | LLThreadSafeRefCount::initThreadSafeRefCount(); | 42 | LLThreadSafeRefCount::initThreadSafeRefCount(); |
51 | // LLWorkerThread::initClass(); | 43 | // LLWorkerThread::initClass(); |
@@ -59,10 +51,5 @@ void LLCommon::cleanupClass() | |||
59 | // LLWorkerThread::cleanupClass(); | 51 | // LLWorkerThread::cleanupClass(); |
60 | LLThreadSafeRefCount::cleanupThreadSafeRefCount(); | 52 | LLThreadSafeRefCount::cleanupThreadSafeRefCount(); |
61 | LLTimer::cleanupClass(); | 53 | LLTimer::cleanupClass(); |
62 | if (sAprInitialized) | ||
63 | { | ||
64 | ll_cleanup_apr(); | ||
65 | sAprInitialized = FALSE; | ||
66 | } | ||
67 | LLMemory::cleanupClass(); | 54 | LLMemory::cleanupClass(); |
68 | } | 55 | } |
diff --git a/linden/indra/llcommon/llcommon.h b/linden/indra/llcommon/llcommon.h index 5f77988..300ebe2 100644 --- a/linden/indra/llcommon/llcommon.h +++ b/linden/indra/llcommon/llcommon.h | |||
@@ -38,13 +38,11 @@ | |||
38 | #include "lltimer.h" | 38 | #include "lltimer.h" |
39 | #include "llfile.h" | 39 | #include "llfile.h" |
40 | 40 | ||
41 | class LLCommon | 41 | class LL_COMMON_API LLCommon |
42 | { | 42 | { |
43 | public: | 43 | public: |
44 | static void initClass(); | 44 | static void initClass(); |
45 | static void cleanupClass(); | 45 | static void cleanupClass(); |
46 | private: | ||
47 | static BOOL sAprInitialized; | ||
48 | }; | 46 | }; |
49 | 47 | ||
50 | #endif | 48 | #endif |
diff --git a/linden/indra/llcommon/llcrc.h b/linden/indra/llcommon/llcrc.h index 27fae7d..7436906 100644 --- a/linden/indra/llcommon/llcrc.h +++ b/linden/indra/llcommon/llcrc.h | |||
@@ -50,7 +50,7 @@ | |||
50 | // llinfos << "File crc: " << crc.getCRC() << llendl; | 50 | // llinfos << "File crc: " << crc.getCRC() << llendl; |
51 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 51 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
52 | 52 | ||
53 | class LLCRC | 53 | class LL_COMMON_API LLCRC |
54 | { | 54 | { |
55 | protected: | 55 | protected: |
56 | U32 mCurrent; | 56 | U32 mCurrent; |
diff --git a/linden/indra/llcommon/llcriticaldamp.h b/linden/indra/llcommon/llcriticaldamp.h index ad98284..13e37d8 100644 --- a/linden/indra/llcommon/llcriticaldamp.h +++ b/linden/indra/llcommon/llcriticaldamp.h | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #include "llframetimer.h" | 39 | #include "llframetimer.h" |
40 | 40 | ||
41 | class LLCriticalDamp | 41 | class LL_COMMON_API LLCriticalDamp |
42 | { | 42 | { |
43 | public: | 43 | public: |
44 | LLCriticalDamp(); | 44 | LLCriticalDamp(); |
diff --git a/linden/indra/llcommon/llcursortypes.h b/linden/indra/llcommon/llcursortypes.h index bea7035..836ecc3 100644 --- a/linden/indra/llcommon/llcursortypes.h +++ b/linden/indra/llcommon/llcursortypes.h | |||
@@ -77,6 +77,6 @@ enum ECursorType { | |||
77 | UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) | 77 | UI_CURSOR_COUNT // Number of elements in this enum (NOT a cursor) |
78 | }; | 78 | }; |
79 | 79 | ||
80 | ECursorType getCursorFromString(const std::string& cursor_string); | 80 | LL_COMMON_API ECursorType getCursorFromString(const std::string& cursor_string); |
81 | 81 | ||
82 | #endif // LL_LLCURSORTYPES_H | 82 | #endif // LL_LLCURSORTYPES_H |
diff --git a/linden/indra/llcommon/lldate.cpp b/linden/indra/llcommon/lldate.cpp index 41a3af3..be29448 100644 --- a/linden/indra/llcommon/lldate.cpp +++ b/linden/indra/llcommon/lldate.cpp | |||
@@ -113,6 +113,8 @@ void LLDate::toHTTPDateStream(std::ostream& s) const | |||
113 | #else | 113 | #else |
114 | s.setf(ios::right); | 114 | s.setf(ios::right); |
115 | #endif | 115 | #endif |
116 | static char const* const weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; | ||
117 | static char const* const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; | ||
116 | std::string day = weekdays[exp_time.tm_wday]; | 118 | std::string day = weekdays[exp_time.tm_wday]; |
117 | std::string month = months[exp_time.tm_mon]; | 119 | std::string month = months[exp_time.tm_mon]; |
118 | 120 | ||
diff --git a/linden/indra/llcommon/lldate.h b/linden/indra/llcommon/lldate.h index 7cc9c8a..d27da79 100644 --- a/linden/indra/llcommon/lldate.h +++ b/linden/indra/llcommon/lldate.h | |||
@@ -46,7 +46,7 @@ | |||
46 | * | 46 | * |
47 | * The date class represents a point in time after epoch - 1970-01-01. | 47 | * The date class represents a point in time after epoch - 1970-01-01. |
48 | */ | 48 | */ |
49 | class LLDate | 49 | class LL_COMMON_API LLDate |
50 | { | 50 | { |
51 | public: | 51 | public: |
52 | /** | 52 | /** |
@@ -153,14 +153,9 @@ private: | |||
153 | }; | 153 | }; |
154 | 154 | ||
155 | // Helper function to stream out a date | 155 | // Helper function to stream out a date |
156 | std::ostream& operator<<(std::ostream& s, const LLDate& date); | 156 | LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLDate& date); |
157 | 157 | ||
158 | // Helper function to stream in a date | 158 | // Helper function to stream in a date |
159 | std::istream& operator>>(std::istream& s, LLDate& date); | 159 | LL_COMMON_API std::istream& operator>>(std::istream& s, LLDate& date); |
160 | |||
161 | |||
162 | const static std::string weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}; | ||
163 | |||
164 | const static std::string months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; | ||
165 | 160 | ||
166 | #endif // LL_LLDATE_H | 161 | #endif // LL_LLDATE_H |
diff --git a/linden/indra/llcommon/llerror.cpp b/linden/indra/llcommon/llerror.cpp index 30b61a9..aeba629 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp | |||
@@ -46,6 +46,8 @@ | |||
46 | # include <unistd.h> | 46 | # include <unistd.h> |
47 | #endif // !LL_WINDOWS | 47 | #endif // !LL_WINDOWS |
48 | #if LL_WINDOWS | 48 | #if LL_WINDOWS |
49 | # define WIN32_LEAN_AND_MEAN | ||
50 | # include <winsock2.h> | ||
49 | # include <windows.h> | 51 | # include <windows.h> |
50 | #endif // LL_WINDOWS | 52 | #endif // LL_WINDOWS |
51 | #include <vector> | 53 | #include <vector> |
@@ -58,7 +60,9 @@ | |||
58 | #include "llsd.h" | 60 | #include "llsd.h" |
59 | #include "llsdserialize.h" | 61 | #include "llsdserialize.h" |
60 | #include "llstl.h" | 62 | #include "llstl.h" |
63 | #include "lltimer.h" | ||
61 | 64 | ||
65 | extern apr_thread_mutex_t* gCallStacksLogMutexp; | ||
62 | 66 | ||
63 | namespace { | 67 | namespace { |
64 | #if !LL_WINDOWS | 68 | #if !LL_WINDOWS |
@@ -164,6 +168,9 @@ namespace { | |||
164 | } | 168 | } |
165 | } | 169 | } |
166 | fprintf(stderr, "%s\n", message.c_str()); | 170 | fprintf(stderr, "%s\n", message.c_str()); |
171 | #if LL_WINDOWS | ||
172 | fflush(stderr); //Now using a buffer. flush is required. | ||
173 | #endif | ||
167 | if (ANSI_YES == mUseANSI) colorANSI("0"); // reset | 174 | if (ANSI_YES == mUseANSI) colorANSI("0"); // reset |
168 | } | 175 | } |
169 | 176 | ||
@@ -559,7 +566,7 @@ namespace | |||
559 | #if LL_WINDOWS | 566 | #if LL_WINDOWS |
560 | LLError::addRecorder(new RecordToWinDebug); | 567 | LLError::addRecorder(new RecordToWinDebug); |
561 | #endif | 568 | #endif |
562 | 569 | llwarns << "Load LogControlFile from Directory:"<< dir << llendl; | |
563 | LogControlFile& e = LogControlFile::fromDirectory(dir); | 570 | LogControlFile& e = LogControlFile::fromDirectory(dir); |
564 | 571 | ||
565 | // NOTE: We want to explicitly load the file before we add it to the event timer | 572 | // NOTE: We want to explicitly load the file before we add it to the event timer |
@@ -869,6 +876,9 @@ You get: | |||
869 | 876 | ||
870 | */ | 877 | */ |
871 | 878 | ||
879 | apr_thread_mutex_t* gLogMutexp; | ||
880 | apr_thread_mutex_t* gCallStacksLogMutexp; | ||
881 | |||
872 | namespace { | 882 | namespace { |
873 | bool checkLevelMap(const LevelMap& map, const std::string& key, | 883 | bool checkLevelMap(const LevelMap& map, const std::string& key, |
874 | LLError::ELevel& level) | 884 | LLError::ELevel& level) |
diff --git a/linden/indra/llcommon/llerror.h b/linden/indra/llcommon/llerror.h index 6794be4..5a4c644 100644 --- a/linden/indra/llcommon/llerror.h +++ b/linden/indra/llcommon/llerror.h | |||
@@ -131,7 +131,7 @@ namespace LLError | |||
131 | 131 | ||
132 | class CallSite; | 132 | class CallSite; |
133 | 133 | ||
134 | class Log | 134 | class LL_COMMON_API Log |
135 | { | 135 | { |
136 | public: | 136 | public: |
137 | static bool shouldLog(CallSite&); | 137 | static bool shouldLog(CallSite&); |
@@ -140,7 +140,7 @@ namespace LLError | |||
140 | static void flush(std::ostringstream*, const CallSite&); | 140 | static void flush(std::ostringstream*, const CallSite&); |
141 | }; | 141 | }; |
142 | 142 | ||
143 | class CallSite | 143 | class LL_COMMON_API CallSite |
144 | { | 144 | { |
145 | // Represents a specific place in the code where a message is logged | 145 | // Represents a specific place in the code where a message is logged |
146 | // This is public because it is used by the macros below. It is not | 146 | // This is public because it is used by the macros below. It is not |
@@ -189,7 +189,7 @@ namespace LLError | |||
189 | //LLCallStacks is designed not to be thread-safe. | 189 | //LLCallStacks is designed not to be thread-safe. |
190 | //so try not to use it in multiple parallel threads at same time. | 190 | //so try not to use it in multiple parallel threads at same time. |
191 | //Used in a single thread at a time is fine. | 191 | //Used in a single thread at a time is fine. |
192 | class LLCallStacks | 192 | class LL_COMMON_API LLCallStacks |
193 | { | 193 | { |
194 | private: | 194 | private: |
195 | static char** sBuffer ; | 195 | static char** sBuffer ; |
@@ -239,7 +239,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; | |||
239 | */ | 239 | */ |
240 | 240 | ||
241 | #define lllog(level, broadTag, narrowTag, once) \ | 241 | #define lllog(level, broadTag, narrowTag, once) \ |
242 | { \ | 242 | do { \ |
243 | static LLError::CallSite _site( \ | 243 | static LLError::CallSite _site( \ |
244 | level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\ | 244 | level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\ |
245 | if (_site.shouldLog()) \ | 245 | if (_site.shouldLog()) \ |
@@ -252,7 +252,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG; | |||
252 | LLError::End(); \ | 252 | LLError::End(); \ |
253 | LLError::Log::flush(_out, _site); \ | 253 | LLError::Log::flush(_out, _site); \ |
254 | } \ | 254 | } \ |
255 | } | 255 | } while(0) |
256 | 256 | ||
257 | // DEPRECATED: Use the new macros that allow tags and *look* like macros. | 257 | // DEPRECATED: Use the new macros that allow tags and *look* like macros. |
258 | #define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false) | 258 | #define lldebugs lllog(LLError::LEVEL_DEBUG, NULL, NULL, false) |
diff --git a/linden/indra/llcommon/llerrorcontrol.h b/linden/indra/llcommon/llerrorcontrol.h index a55d706..54138b2 100644 --- a/linden/indra/llcommon/llerrorcontrol.h +++ b/linden/indra/llcommon/llerrorcontrol.h | |||
@@ -52,12 +52,12 @@ class LLSD; | |||
52 | 52 | ||
53 | namespace LLError | 53 | namespace LLError |
54 | { | 54 | { |
55 | void initForServer(const std::string& identity); | 55 | LL_COMMON_API void initForServer(const std::string& identity); |
56 | // resets all logging settings to defaults needed by server processes | 56 | // resets all logging settings to defaults needed by server processes |
57 | // logs to stderr, syslog, and windows debug log | 57 | // logs to stderr, syslog, and windows debug log |
58 | // the identity string is used for in the syslog | 58 | // the identity string is used for in the syslog |
59 | 59 | ||
60 | void initForApplication(const std::string& dir); | 60 | LL_COMMON_API void initForApplication(const std::string& dir); |
61 | // resets all logging settings to defaults needed by applicaitons | 61 | // resets all logging settings to defaults needed by applicaitons |
62 | // logs to stderr and windows debug log | 62 | // logs to stderr and windows debug log |
63 | // sets up log configuration from the file logcontrol.xml in dir | 63 | // sets up log configuration from the file logcontrol.xml in dir |
@@ -68,13 +68,14 @@ namespace LLError | |||
68 | Setting a level means log messages at that level or above. | 68 | Setting a level means log messages at that level or above. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | void setPrintLocation(bool); | 71 | LL_COMMON_API void setPrintLocation(bool); |
72 | void setDefaultLevel(LLError::ELevel); | 72 | LL_COMMON_API void setDefaultLevel(LLError::ELevel); |
73 | void setFunctionLevel(const std::string& function_name, LLError::ELevel); | 73 | LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel); |
74 | void setClassLevel(const std::string& class_name, LLError::ELevel); | 74 | LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel); |
75 | void setFileLevel(const std::string& file_name, LLError::ELevel); | 75 | LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel); |
76 | LL_COMMON_API void setTagLevel(const std::string& file_name, LLError::ELevel); | ||
76 | 77 | ||
77 | void configure(const LLSD&); | 78 | LL_COMMON_API void configure(const LLSD&); |
78 | // the LLSD can configure all of the settings | 79 | // the LLSD can configure all of the settings |
79 | // usually read automatically from the live errorlog.xml file | 80 | // usually read automatically from the live errorlog.xml file |
80 | 81 | ||
@@ -84,25 +85,25 @@ namespace LLError | |||
84 | */ | 85 | */ |
85 | 86 | ||
86 | typedef void(*FatalFunction)(const std::string& message); | 87 | typedef void(*FatalFunction)(const std::string& message); |
87 | void crashAndLoop(const std::string& message); | 88 | LL_COMMON_API void crashAndLoop(const std::string& message); |
88 | // Default fatal funtion: access null pointer and loops forever | 89 | // Default fatal funtion: access null pointer and loops forever |
89 | 90 | ||
90 | void setFatalFunction(FatalFunction); | 91 | LL_COMMON_API void setFatalFunction(FatalFunction); |
91 | // The fatal function will be called when an message of LEVEL_ERROR | 92 | // The fatal function will be called when an message of LEVEL_ERROR |
92 | // is logged. Note: supressing a LEVEL_ERROR message from being logged | 93 | // is logged. Note: supressing a LEVEL_ERROR message from being logged |
93 | // (by, for example, setting a class level to LEVEL_NONE), will keep | 94 | // (by, for example, setting a class level to LEVEL_NONE), will keep |
94 | // the that message from causing the fatal funciton to be invoked. | 95 | // the that message from causing the fatal funciton to be invoked. |
95 | 96 | ||
96 | typedef std::string (*TimeFunction)(); | 97 | typedef std::string (*TimeFunction)(); |
97 | std::string utcTime(); | 98 | LL_COMMON_API std::string utcTime(); |
98 | 99 | ||
99 | void setTimeFunction(TimeFunction); | 100 | LL_COMMON_API void setTimeFunction(TimeFunction); |
100 | // The function is use to return the current time, formatted for | 101 | // The function is use to return the current time, formatted for |
101 | // display by those error recorders that want the time included. | 102 | // display by those error recorders that want the time included. |
102 | 103 | ||
103 | 104 | ||
104 | 105 | ||
105 | class Recorder | 106 | class LL_COMMON_API Recorder |
106 | { | 107 | { |
107 | // An object that handles the actual output or error messages. | 108 | // An object that handles the actual output or error messages. |
108 | public: | 109 | public: |
@@ -116,17 +117,17 @@ namespace LLError | |||
116 | // included in the text of the message | 117 | // included in the text of the message |
117 | }; | 118 | }; |
118 | 119 | ||
119 | void addRecorder(Recorder*); | 120 | LL_COMMON_API void addRecorder(Recorder*); |
120 | void removeRecorder(Recorder*); | 121 | LL_COMMON_API void removeRecorder(Recorder*); |
121 | // each error message is passed to each recorder via recordMessage() | 122 | // each error message is passed to each recorder via recordMessage() |
122 | 123 | ||
123 | void logToFile(const std::string& filename); | 124 | LL_COMMON_API void logToFile(const std::string& filename); |
124 | void logToFixedBuffer(LLFixedBuffer*); | 125 | LL_COMMON_API void logToFixedBuffer(LLFixedBuffer*); |
125 | // Utilities to add recorders for logging to a file or a fixed buffer | 126 | // Utilities to add recorders for logging to a file or a fixed buffer |
126 | // A second call to the same function will remove the logger added | 127 | // A second call to the same function will remove the logger added |
127 | // with the first. | 128 | // with the first. |
128 | // Passing the empty string or NULL to just removes any prior. | 129 | // Passing the empty string or NULL to just removes any prior. |
129 | std::string logFileName(); | 130 | LL_COMMON_API std::string logFileName(); |
130 | // returns name of current logging file, empty string if none | 131 | // returns name of current logging file, empty string if none |
131 | 132 | ||
132 | 133 | ||
@@ -135,11 +136,11 @@ namespace LLError | |||
135 | */ | 136 | */ |
136 | 137 | ||
137 | class Settings; | 138 | class Settings; |
138 | Settings* saveAndResetSettings(); | 139 | LL_COMMON_API Settings* saveAndResetSettings(); |
139 | void restoreSettings(Settings *); | 140 | LL_COMMON_API void restoreSettings(Settings *); |
140 | 141 | ||
141 | std::string abbreviateFile(const std::string& filePath); | 142 | LL_COMMON_API std::string abbreviateFile(const std::string& filePath); |
142 | int shouldLogCallCount(); | 143 | LL_COMMON_API int shouldLogCallCount(); |
143 | 144 | ||
144 | }; | 145 | }; |
145 | 146 | ||
diff --git a/linden/indra/llcommon/llerrorthread.cpp b/linden/indra/llcommon/llerrorthread.cpp index 4c779c5..e2b106a 100644 --- a/linden/indra/llcommon/llerrorthread.cpp +++ b/linden/indra/llcommon/llerrorthread.cpp | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "linden_common.h" | 32 | #include "linden_common.h" |
33 | #include "llerrorthread.h" | 33 | #include "llerrorthread.h" |
34 | #include "llapp.h" | 34 | #include "llapp.h" |
35 | #include "lltimer.h" | ||
35 | 36 | ||
36 | LLErrorThread::LLErrorThread() | 37 | LLErrorThread::LLErrorThread() |
37 | : LLThread("Error"), | 38 | : LLThread("Error"), |
diff --git a/linden/indra/llcommon/llerrorthread.h b/linden/indra/llcommon/llerrorthread.h index f1d6ffc..3121d29 100644 --- a/linden/indra/llcommon/llerrorthread.h +++ b/linden/indra/llcommon/llerrorthread.h | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include "llthread.h" | 36 | #include "llthread.h" |
37 | 37 | ||
38 | class LLErrorThread : public LLThread | 38 | class LL_COMMON_API LLErrorThread : public LLThread |
39 | { | 39 | { |
40 | public: | 40 | public: |
41 | LLErrorThread(); | 41 | LLErrorThread(); |
diff --git a/linden/indra/llcommon/llevent.h b/linden/indra/llcommon/llevent.h index 60887a0..6b223a8 100644 --- a/linden/indra/llcommon/llevent.h +++ b/linden/indra/llcommon/llevent.h | |||
@@ -44,7 +44,7 @@ class LLEventDispatcher; | |||
44 | class LLObservable; | 44 | class LLObservable; |
45 | 45 | ||
46 | // Abstract event. All events derive from LLEvent | 46 | // Abstract event. All events derive from LLEvent |
47 | class LLEvent : public LLThreadSafeRefCount | 47 | class LL_COMMON_API LLEvent : public LLThreadSafeRefCount |
48 | { | 48 | { |
49 | protected: | 49 | protected: |
50 | virtual ~LLEvent(); | 50 | virtual ~LLEvent(); |
@@ -72,7 +72,7 @@ private: | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | // Abstract listener. All listeners derive from LLEventListener | 74 | // Abstract listener. All listeners derive from LLEventListener |
75 | class LLEventListener : public LLThreadSafeRefCount | 75 | class LL_COMMON_API LLEventListener : public LLThreadSafeRefCount |
76 | { | 76 | { |
77 | protected: | 77 | protected: |
78 | virtual ~LLEventListener(); | 78 | virtual ~LLEventListener(); |
@@ -89,7 +89,7 @@ public: | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | // A listener which tracks references to it and cleans up when it's deallocated | 91 | // A listener which tracks references to it and cleans up when it's deallocated |
92 | class LLSimpleListener : public LLEventListener | 92 | class LL_COMMON_API LLSimpleListener : public LLEventListener |
93 | { | 93 | { |
94 | public: | 94 | public: |
95 | void clearDispatchers(); | 95 | void clearDispatchers(); |
@@ -114,7 +114,7 @@ struct LLListenerEntry | |||
114 | // Base class for a dispatcher - an object which listens | 114 | // Base class for a dispatcher - an object which listens |
115 | // to events being fired and relays them to their | 115 | // to events being fired and relays them to their |
116 | // appropriate destinations. | 116 | // appropriate destinations. |
117 | class LLEventDispatcher : public LLThreadSafeRefCount | 117 | class LL_COMMON_API LLEventDispatcher : public LLThreadSafeRefCount |
118 | { | 118 | { |
119 | protected: | 119 | protected: |
120 | virtual ~LLEventDispatcher(); | 120 | virtual ~LLEventDispatcher(); |
@@ -157,7 +157,7 @@ private: | |||
157 | // In order for this class to work properly, it needs | 157 | // In order for this class to work properly, it needs |
158 | // an instance of an LLEventDispatcher to route events to their | 158 | // an instance of an LLEventDispatcher to route events to their |
159 | // listeners. | 159 | // listeners. |
160 | class LLObservable | 160 | class LL_COMMON_API LLObservable |
161 | { | 161 | { |
162 | public: | 162 | public: |
163 | // Initialize with the default Dispatcher | 163 | // Initialize with the default Dispatcher |
diff --git a/linden/indra/llcommon/llfasttimer.cpp b/linden/indra/llcommon/llfasttimer.cpp index 4aa23bb..5f091d5 100644 --- a/linden/indra/llcommon/llfasttimer.cpp +++ b/linden/indra/llcommon/llfasttimer.cpp | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <sched.h> | 42 | #include <sched.h> |
43 | #elif LL_DARWIN | 43 | #elif LL_DARWIN |
44 | #include <sys/time.h> | 44 | #include <sys/time.h> |
45 | #include "lltimer.h" // get_clock_count() | ||
45 | #else | 46 | #else |
46 | #error "architecture not supported" | 47 | #error "architecture not supported" |
47 | #endif | 48 | #endif |
diff --git a/linden/indra/llcommon/llfasttimer.h b/linden/indra/llcommon/llfasttimer.h index 8c1cf47..602a2f7 100644 --- a/linden/indra/llcommon/llfasttimer.h +++ b/linden/indra/llcommon/llfasttimer.h | |||
@@ -35,9 +35,9 @@ | |||
35 | 35 | ||
36 | #define FAST_TIMER_ON 1 | 36 | #define FAST_TIMER_ON 1 |
37 | 37 | ||
38 | U64 get_cpu_clock_count(); | 38 | LL_COMMON_API U64 get_cpu_clock_count(); |
39 | 39 | ||
40 | class LLFastTimer | 40 | class LL_COMMON_API LLFastTimer |
41 | { | 41 | { |
42 | public: | 42 | public: |
43 | enum EFastTimerType | 43 | enum EFastTimerType |
diff --git a/linden/indra/llcommon/llfile.cpp b/linden/indra/llcommon/llfile.cpp index 2a76f7f..6b68630 100644 --- a/linden/indra/llcommon/llfile.cpp +++ b/linden/indra/llcommon/llfile.cpp | |||
@@ -34,6 +34,8 @@ | |||
34 | */ | 34 | */ |
35 | 35 | ||
36 | #if LL_WINDOWS | 36 | #if LL_WINDOWS |
37 | # define WIN32_LEAN_AND_MEAN | ||
38 | # include <winsock2.h> | ||
37 | #include <windows.h> | 39 | #include <windows.h> |
38 | #endif | 40 | #endif |
39 | 41 | ||
diff --git a/linden/indra/llcommon/llfile.h b/linden/indra/llcommon/llfile.h index c6092f7..ee37605 100644 --- a/linden/indra/llcommon/llfile.h +++ b/linden/indra/llcommon/llfile.h | |||
@@ -70,7 +70,7 @@ typedef struct stat llstat; | |||
70 | 70 | ||
71 | #include "llstring.h" // safe char* -> std::string conversion | 71 | #include "llstring.h" // safe char* -> std::string conversion |
72 | 72 | ||
73 | class LLFile | 73 | class LL_COMMON_API LLFile |
74 | { | 74 | { |
75 | public: | 75 | public: |
76 | // All these functions take UTF8 path/filenames. | 76 | // All these functions take UTF8 path/filenames. |
@@ -95,7 +95,7 @@ public: | |||
95 | 95 | ||
96 | #if USE_LLFILESTREAMS | 96 | #if USE_LLFILESTREAMS |
97 | 97 | ||
98 | class llifstream : public std::basic_istream < char , std::char_traits < char > > | 98 | class LL_COMMON_API llifstream : public std::basic_istream < char , std::char_traits < char > > |
99 | { | 99 | { |
100 | // input stream associated with a C stream | 100 | // input stream associated with a C stream |
101 | public: | 101 | public: |
@@ -136,7 +136,7 @@ private: | |||
136 | }; | 136 | }; |
137 | 137 | ||
138 | 138 | ||
139 | class llofstream : public std::basic_ostream< char , std::char_traits < char > > | 139 | class LL_COMMON_API llofstream : public std::basic_ostream< char , std::char_traits < char > > |
140 | { | 140 | { |
141 | public: | 141 | public: |
142 | typedef std::basic_ostream< char , std::char_traits < char > > _Myt; | 142 | typedef std::basic_ostream< char , std::char_traits < char > > _Myt; |
@@ -185,7 +185,7 @@ private: | |||
185 | //#define llifstream std::ifstream | 185 | //#define llifstream std::ifstream |
186 | //#define llofstream std::ofstream | 186 | //#define llofstream std::ofstream |
187 | 187 | ||
188 | class llifstream : public std::ifstream | 188 | class LL_COMMON_API llifstream : public std::ifstream |
189 | { | 189 | { |
190 | public: | 190 | public: |
191 | llifstream() : std::ifstream() | 191 | llifstream() : std::ifstream() |
@@ -203,7 +203,7 @@ public: | |||
203 | }; | 203 | }; |
204 | 204 | ||
205 | 205 | ||
206 | class llofstream : public std::ofstream | 206 | class LL_COMMON_API llofstream : public std::ofstream |
207 | { | 207 | { |
208 | public: | 208 | public: |
209 | llofstream() : std::ofstream() | 209 | llofstream() : std::ofstream() |
diff --git a/linden/indra/llcommon/llfindlocale.cpp b/linden/indra/llcommon/llfindlocale.cpp index 505f5c5..71675af 100644 --- a/linden/indra/llcommon/llfindlocale.cpp +++ b/linden/indra/llcommon/llfindlocale.cpp | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <ctype.h> | 39 | #include <ctype.h> |
40 | 40 | ||
41 | #ifdef WIN32 | 41 | #ifdef WIN32 |
42 | # define WIN32_LEAN_AND_MEAN | ||
43 | # include <winsock2.h> | ||
42 | #include <windows.h> | 44 | #include <windows.h> |
43 | #include <winnt.h> | 45 | #include <winnt.h> |
44 | #endif | 46 | #endif |
diff --git a/linden/indra/llcommon/llfindlocale.h b/linden/indra/llcommon/llfindlocale.h index f17c774..b812a06 100644 --- a/linden/indra/llcommon/llfindlocale.h +++ b/linden/indra/llcommon/llfindlocale.h | |||
@@ -59,8 +59,8 @@ typedef enum { | |||
59 | /* This allocates/fills in a FL_Locale structure with pointers to | 59 | /* This allocates/fills in a FL_Locale structure with pointers to |
60 | strings (which should be treated as static), or NULL for inappropriate / | 60 | strings (which should be treated as static), or NULL for inappropriate / |
61 | undetected fields. */ | 61 | undetected fields. */ |
62 | FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain); | 62 | LL_COMMON_API FL_Success FL_FindLocale(FL_Locale **locale, FL_Domain domain); |
63 | /* This should be used to free the struct written by FL_FindLocale */ | 63 | /* This should be used to free the struct written by FL_FindLocale */ |
64 | void FL_FreeLocale(FL_Locale **locale); | 64 | LL_COMMON_API void FL_FreeLocale(FL_Locale **locale); |
65 | 65 | ||
66 | #endif /*__findlocale_h_*/ | 66 | #endif /*__findlocale_h_*/ |
diff --git a/linden/indra/llcommon/llfixedbuffer.cpp b/linden/indra/llcommon/llfixedbuffer.cpp index e9d6029..37a12ad 100644 --- a/linden/indra/llcommon/llfixedbuffer.cpp +++ b/linden/indra/llcommon/llfixedbuffer.cpp | |||
@@ -33,9 +33,8 @@ | |||
33 | #include "llfixedbuffer.h" | 33 | #include "llfixedbuffer.h" |
34 | 34 | ||
35 | LLFixedBuffer::LLFixedBuffer(const U32 max_lines) | 35 | LLFixedBuffer::LLFixedBuffer(const U32 max_lines) |
36 | : mMutex(NULL) | 36 | : mMaxLines(max_lines) |
37 | { | 37 | { |
38 | mMaxLines = max_lines; | ||
39 | mTimer.reset(); | 38 | mTimer.reset(); |
40 | } | 39 | } |
41 | 40 | ||
diff --git a/linden/indra/llcommon/llfixedbuffer.h b/linden/indra/llcommon/llfixedbuffer.h index 992a024..51d0701 100644 --- a/linden/indra/llcommon/llfixedbuffer.h +++ b/linden/indra/llcommon/llfixedbuffer.h | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | // Fixed size buffer for console output and other things. | 42 | // Fixed size buffer for console output and other things. |
43 | 43 | ||
44 | class LLFixedBuffer | 44 | class LL_COMMON_API LLFixedBuffer |
45 | { | 45 | { |
46 | public: | 46 | public: |
47 | LLFixedBuffer(const U32 max_lines = 20); | 47 | LLFixedBuffer(const U32 max_lines = 20); |
diff --git a/linden/indra/llcommon/llformat.h b/linden/indra/llcommon/llformat.h index 44c62d9..ad30d4f 100644 --- a/linden/indra/llcommon/llformat.h +++ b/linden/indra/llcommon/llformat.h | |||
@@ -40,6 +40,6 @@ | |||
40 | // *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun) | 40 | // *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun) |
41 | // should perhaps be replaced with boost::format. | 41 | // should perhaps be replaced with boost::format. |
42 | 42 | ||
43 | std::string llformat(const char *fmt, ...); | 43 | LL_COMMON_API std::string llformat(const char *fmt, ...); |
44 | 44 | ||
45 | #endif // LL_LLFORMAT_H | 45 | #endif // LL_LLFORMAT_H |
diff --git a/linden/indra/llcommon/llframetimer.h b/linden/indra/llcommon/llframetimer.h index 8f51272..f4775a9 100644 --- a/linden/indra/llcommon/llframetimer.h +++ b/linden/indra/llcommon/llframetimer.h | |||
@@ -43,7 +43,7 @@ | |||
43 | #include "lltimer.h" | 43 | #include "lltimer.h" |
44 | #include "timing.h" | 44 | #include "timing.h" |
45 | 45 | ||
46 | class LLFrameTimer | 46 | class LL_COMMON_API LLFrameTimer |
47 | { | 47 | { |
48 | public: | 48 | public: |
49 | LLFrameTimer() : mStartTime( sFrameTime ), mExpiry(0), mStarted(TRUE) {} | 49 | LLFrameTimer() : mStartTime( sFrameTime ), mExpiry(0), mStarted(TRUE) {} |
diff --git a/linden/indra/llcommon/llheartbeat.h b/linden/indra/llcommon/llheartbeat.h index fecb5b1..6f70269 100644 --- a/linden/indra/llcommon/llheartbeat.h +++ b/linden/indra/llcommon/llheartbeat.h | |||
@@ -40,7 +40,7 @@ | |||
40 | // Note: Win32 does not support the heartbeat/smackdown system; | 40 | // Note: Win32 does not support the heartbeat/smackdown system; |
41 | // heartbeat-delivery turns into a no-op there. | 41 | // heartbeat-delivery turns into a no-op there. |
42 | 42 | ||
43 | class LLHeartbeat | 43 | class LL_COMMON_API LLHeartbeat |
44 | { | 44 | { |
45 | public: | 45 | public: |
46 | // secs_between_heartbeat: after a heartbeat is successfully delivered, | 46 | // secs_between_heartbeat: after a heartbeat is successfully delivered, |
diff --git a/linden/indra/llcommon/llliveappconfig.h b/linden/indra/llcommon/llliveappconfig.h index 55d84a4..3251a7c 100644 --- a/linden/indra/llcommon/llliveappconfig.h +++ b/linden/indra/llcommon/llliveappconfig.h | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | class LLApp; | 38 | class LLApp; |
39 | 39 | ||
40 | class LLLiveAppConfig : public LLLiveFile | 40 | class LL_COMMON_API LLLiveAppConfig : public LLLiveFile |
41 | { | 41 | { |
42 | public: | 42 | public: |
43 | // To use this, instantiate a LLLiveAppConfig object inside your main loop. | 43 | // To use this, instantiate a LLLiveAppConfig object inside your main loop. |
diff --git a/linden/indra/llcommon/lllivefile.h b/linden/indra/llcommon/lllivefile.h index fddf006..72f16fd 100644 --- a/linden/indra/llcommon/lllivefile.h +++ b/linden/indra/llcommon/lllivefile.h | |||
@@ -36,7 +36,7 @@ | |||
36 | const F32 configFileRefreshRate = 5.0; // seconds | 36 | const F32 configFileRefreshRate = 5.0; // seconds |
37 | 37 | ||
38 | 38 | ||
39 | class LLLiveFile | 39 | class LL_COMMON_API LLLiveFile |
40 | { | 40 | { |
41 | public: | 41 | public: |
42 | LLLiveFile(const std::string &filename, const F32 refresh_period = 5.f); | 42 | LLLiveFile(const std::string &filename, const F32 refresh_period = 5.f); |
diff --git a/linden/indra/llcommon/lllog.h b/linden/indra/llcommon/lllog.h index 7ac6c8a..4b6777b 100644 --- a/linden/indra/llcommon/lllog.h +++ b/linden/indra/llcommon/lllog.h | |||
@@ -41,7 +41,7 @@ class LLLogImpl; | |||
41 | class LLApp; | 41 | class LLApp; |
42 | class LLSD; | 42 | class LLSD; |
43 | 43 | ||
44 | class LLLog | 44 | class LL_COMMON_API LLLog |
45 | { | 45 | { |
46 | public: | 46 | public: |
47 | LLLog(LLApp* app); | 47 | LLLog(LLApp* app); |
diff --git a/linden/indra/llcommon/lllslconstants.h b/linden/indra/llcommon/lllslconstants.h index fc5363f..25a15e4 100644..100755 --- a/linden/indra/llcommon/lllslconstants.h +++ b/linden/indra/llcommon/lllslconstants.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * $LicenseInfo:firstyear=2006&license=viewergpl$ | 6 | * $LicenseInfo:firstyear=2006&license=viewergpl$ |
7 | * | 7 | * |
8 | * Copyright (c) 2006-2009, Linden Research, Inc. | 8 | * Copyright (c) 2006-2010, Linden Research, Inc. |
9 | * | 9 | * |
10 | * Second Life Viewer Source Code | 10 | * Second Life Viewer Source Code |
11 | * The source code in this file ("Source Code") is provided by Linden Lab | 11 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -189,9 +189,6 @@ const S32 OBJECT_OWNER = 6; | |||
189 | const S32 OBJECT_GROUP = 7; | 189 | const S32 OBJECT_GROUP = 7; |
190 | const S32 OBJECT_CREATOR = 8; | 190 | const S32 OBJECT_CREATOR = 8; |
191 | 191 | ||
192 | // llTextBox() magic token string - yes this is a hack. sue me. | ||
193 | const std::string TEXTBOX_MAGIC_TOKEN = "!!llTextBox!!"; | ||
194 | |||
195 | // changed() event flags | 192 | // changed() event flags |
196 | const U32 CHANGED_NONE = 0x0; | 193 | const U32 CHANGED_NONE = 0x0; |
197 | const U32 CHANGED_INVENTORY = 0x1; | 194 | const U32 CHANGED_INVENTORY = 0x1; |
diff --git a/linden/indra/llcommon/llmd5.cpp b/linden/indra/llcommon/llmd5.cpp index 14b4f9f..887979b 100644 --- a/linden/indra/llcommon/llmd5.cpp +++ b/linden/indra/llcommon/llmd5.cpp | |||
@@ -83,6 +83,7 @@ documentation and/or software. | |||
83 | #include "llmd5.h" | 83 | #include "llmd5.h" |
84 | 84 | ||
85 | #include <cassert> | 85 | #include <cassert> |
86 | #include <iostream> | ||
86 | 87 | ||
87 | // how many bytes to grab at a time when checking files | 88 | // how many bytes to grab at a time when checking files |
88 | const int LLMD5::BLOCK_LEN = 4096; | 89 | const int LLMD5::BLOCK_LEN = 4096; |
diff --git a/linden/indra/llcommon/llmd5.h b/linden/indra/llcommon/llmd5.h index d8bca03..df9d732 100644 --- a/linden/indra/llcommon/llmd5.h +++ b/linden/indra/llcommon/llmd5.h | |||
@@ -80,7 +80,7 @@ const int MD5RAW_BYTES = 16; | |||
80 | const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null | 80 | const int MD5HEX_STR_SIZE = 33; // char hex[MD5HEX_STR_SIZE]; with null |
81 | const int MD5HEX_STR_BYTES = 32; // message system fixed size | 81 | const int MD5HEX_STR_BYTES = 32; // message system fixed size |
82 | 82 | ||
83 | class LLMD5 { | 83 | class LL_COMMON_API LLMD5 { |
84 | // first, some types: | 84 | // first, some types: |
85 | typedef unsigned int uint4; // assumes integer is 4 words long | 85 | typedef unsigned int uint4; // assumes integer is 4 words long |
86 | typedef unsigned short int uint2; // assumes short integer is 2 words long | 86 | typedef unsigned short int uint2; // assumes short integer is 2 words long |
diff --git a/linden/indra/llcommon/llmemory.cpp b/linden/indra/llcommon/llmemory.cpp index a6de3d2..2b01442 100644 --- a/linden/indra/llcommon/llmemory.cpp +++ b/linden/indra/llcommon/llmemory.cpp | |||
@@ -33,6 +33,8 @@ | |||
33 | #include "linden_common.h" | 33 | #include "linden_common.h" |
34 | 34 | ||
35 | #if defined(LL_WINDOWS) | 35 | #if defined(LL_WINDOWS) |
36 | # define WIN32_LEAN_AND_MEAN | ||
37 | # include <winsock2.h> | ||
36 | # include <windows.h> | 38 | # include <windows.h> |
37 | # include <psapi.h> | 39 | # include <psapi.h> |
38 | #elif defined(LL_DARWIN) | 40 | #elif defined(LL_DARWIN) |
@@ -283,6 +285,11 @@ LLRefCount::LLRefCount() : | |||
283 | { | 285 | { |
284 | } | 286 | } |
285 | 287 | ||
288 | LLRefCount::LLRefCount(const LLRefCount& other) | ||
289 | : mRef(0) | ||
290 | { | ||
291 | } | ||
292 | |||
286 | LLRefCount::~LLRefCount() | 293 | LLRefCount::~LLRefCount() |
287 | { | 294 | { |
288 | if (mRef != 0) | 295 | if (mRef != 0) |
@@ -290,7 +297,13 @@ LLRefCount::~LLRefCount() | |||
290 | llerrs << "deleting non-zero reference" << llendl; | 297 | llerrs << "deleting non-zero reference" << llendl; |
291 | } | 298 | } |
292 | } | 299 | } |
293 | 300 | ||
301 | LLRefCount& LLRefCount::operator=(const LLRefCount&) | ||
302 | { | ||
303 | // do nothing, since ref count is specific to *this* reference | ||
304 | return *this; | ||
305 | } | ||
306 | |||
294 | //---------------------------------------------------------------------------- | 307 | //---------------------------------------------------------------------------- |
295 | 308 | ||
296 | #if defined(LL_WINDOWS) | 309 | #if defined(LL_WINDOWS) |
diff --git a/linden/indra/llcommon/llmemory.h b/linden/indra/llcommon/llmemory.h index b5c0711..9aa4b85 100644 --- a/linden/indra/llcommon/llmemory.h +++ b/linden/indra/llcommon/llmemory.h | |||
@@ -45,7 +45,7 @@ const U32 LLREFCOUNT_SENTINEL_VALUE = 0xAAAAAAAA; | |||
45 | 45 | ||
46 | //---------------------------------------------------------------------------- | 46 | //---------------------------------------------------------------------------- |
47 | 47 | ||
48 | class LLMemory | 48 | class LL_COMMON_API LLMemory |
49 | { | 49 | { |
50 | public: | 50 | public: |
51 | static void initClass(); | 51 | static void initClass(); |
@@ -68,12 +68,12 @@ private: | |||
68 | 68 | ||
69 | //---------------------------------------------------------------------------- | 69 | //---------------------------------------------------------------------------- |
70 | 70 | ||
71 | class LLRefCount | 71 | class LL_COMMON_API LLRefCount |
72 | { | 72 | { |
73 | protected: | 73 | protected: |
74 | LLRefCount(const LLRefCount&); // not implemented | 74 | LLRefCount(const LLRefCount&); |
75 | private: | 75 | private: |
76 | LLRefCount&operator=(const LLRefCount&); // not implemented | 76 | LLRefCount&operator=(const LLRefCount&); |
77 | 77 | ||
78 | protected: | 78 | protected: |
79 | virtual ~LLRefCount(); // use unref() | 79 | virtual ~LLRefCount(); // use unref() |
@@ -467,6 +467,6 @@ private: | |||
467 | 467 | ||
468 | // Return the resident set size of the current process, in bytes. | 468 | // Return the resident set size of the current process, in bytes. |
469 | // Return value is zero if not known. | 469 | // Return value is zero if not known. |
470 | U64 getCurrentRSS(); | 470 | LL_COMMON_API U64 getCurrentRSS(); |
471 | 471 | ||
472 | #endif | 472 | #endif |
diff --git a/linden/indra/llcommon/llmemorystream.h b/linden/indra/llcommon/llmemorystream.h index f348632..fa0f5d2 100644 --- a/linden/indra/llcommon/llmemorystream.h +++ b/linden/indra/llcommon/llmemorystream.h | |||
@@ -52,7 +52,7 @@ | |||
52 | * be careful to always pass in a valid memory location that exists | 52 | * be careful to always pass in a valid memory location that exists |
53 | * for at least as long as this streambuf. | 53 | * for at least as long as this streambuf. |
54 | */ | 54 | */ |
55 | class LLMemoryStreamBuf : public std::streambuf | 55 | class LL_COMMON_API LLMemoryStreamBuf : public std::streambuf |
56 | { | 56 | { |
57 | public: | 57 | public: |
58 | LLMemoryStreamBuf(const U8* start, S32 length); | 58 | LLMemoryStreamBuf(const U8* start, S32 length); |
@@ -74,7 +74,7 @@ protected: | |||
74 | * be careful to always pass in a valid memory location that exists | 74 | * be careful to always pass in a valid memory location that exists |
75 | * for at least as long as this streambuf. | 75 | * for at least as long as this streambuf. |
76 | */ | 76 | */ |
77 | class LLMemoryStream : public std::istream | 77 | class LL_COMMON_API LLMemoryStream : public std::istream |
78 | { | 78 | { |
79 | public: | 79 | public: |
80 | LLMemoryStream(const U8* start, S32 length); | 80 | LLMemoryStream(const U8* start, S32 length); |
diff --git a/linden/indra/llcommon/llmemtype.h b/linden/indra/llcommon/llmemtype.h index a9ebc20..d4cc67e 100644 --- a/linden/indra/llcommon/llmemtype.h +++ b/linden/indra/llcommon/llmemtype.h | |||
@@ -57,7 +57,7 @@ static void operator delete(void* p) { ll_release(p); } | |||
57 | 57 | ||
58 | //---------------------------------------------------------------------------- | 58 | //---------------------------------------------------------------------------- |
59 | 59 | ||
60 | class LLMemType | 60 | class LL_COMMON_API LLMemType |
61 | { | 61 | { |
62 | public: | 62 | public: |
63 | // Also update sTypeDesc in llmemory.cpp | 63 | // Also update sTypeDesc in llmemory.cpp |
diff --git a/linden/indra/llcommon/llmetrics.h b/linden/indra/llcommon/llmetrics.h index 1d91e8c..f6f49eb 100644 --- a/linden/indra/llcommon/llmetrics.h +++ b/linden/indra/llcommon/llmetrics.h | |||
@@ -38,7 +38,7 @@ | |||
38 | class LLMetricsImpl; | 38 | class LLMetricsImpl; |
39 | class LLSD; | 39 | class LLSD; |
40 | 40 | ||
41 | class LLMetrics | 41 | class LL_COMMON_API LLMetrics |
42 | { | 42 | { |
43 | public: | 43 | public: |
44 | LLMetrics(); | 44 | LLMetrics(); |
diff --git a/linden/indra/llcommon/llmortician.h b/linden/indra/llcommon/llmortician.h index 247632f..55a101a 100644 --- a/linden/indra/llcommon/llmortician.h +++ b/linden/indra/llcommon/llmortician.h | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include "stdtypes.h" | 36 | #include "stdtypes.h" |
37 | 37 | ||
38 | class LLMortician | 38 | class LL_COMMON_API LLMortician |
39 | { | 39 | { |
40 | public: | 40 | public: |
41 | LLMortician() { mIsDead = FALSE; } | 41 | LLMortician() { mIsDead = FALSE; } |
diff --git a/linden/indra/llcommon/llpreprocessor.h b/linden/indra/llcommon/llpreprocessor.h index 2e4fd47..6886e3a 100644 --- a/linden/indra/llcommon/llpreprocessor.h +++ b/linden/indra/llcommon/llpreprocessor.h | |||
@@ -92,47 +92,63 @@ | |||
92 | 92 | ||
93 | #endif | 93 | #endif |
94 | 94 | ||
95 | |||
96 | // Deal with the differeneces on Windows | 95 | // Deal with the differeneces on Windows |
97 | #if LL_MSVC | ||
98 | namespace snprintf_hack | ||
99 | { | ||
100 | int snprintf(char *str, size_t size, const char *format, ...); | ||
101 | } | ||
102 | |||
103 | // #define snprintf safe_snprintf /* Flawfinder: ignore */ | ||
104 | using snprintf_hack::snprintf; | ||
105 | #endif // LL_MSVC | ||
106 | |||
107 | // Static linking with apr on windows needs to be declared. | ||
108 | #ifdef LL_WINDOWS | ||
109 | #ifndef APR_DECLARE_STATIC | ||
110 | #define APR_DECLARE_STATIC // For APR on Windows | ||
111 | #endif | ||
112 | #ifndef APU_DECLARE_STATIC | ||
113 | #define APU_DECLARE_STATIC // For APR util on Windows | ||
114 | #endif | ||
115 | #endif | ||
116 | |||
117 | #if defined(LL_WINDOWS) | 96 | #if defined(LL_WINDOWS) |
118 | #define BOOST_REGEX_NO_LIB 1 | 97 | #define BOOST_REGEX_NO_LIB 1 |
119 | #define CURL_STATICLIB 1 | 98 | #define CURL_STATICLIB 1 |
120 | #define XML_STATIC | 99 | #define XML_STATIC |
121 | #endif // LL_WINDOWS | 100 | #endif // LL_WINDOWS |
122 | 101 | ||
123 | |||
124 | // Deal with VC6 problems | 102 | // Deal with VC6 problems |
125 | #if LL_MSVC | 103 | #if LL_MSVC |
126 | #pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4. | 104 | #pragma warning( 3 : 4701 ) // "local variable used without being initialized" Treat this as level 3, not level 4. |
127 | #pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. | 105 | #pragma warning( 3 : 4702 ) // "unreachable code" Treat this as level 3, not level 4. |
128 | #pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. | 106 | #pragma warning( 3 : 4189 ) // "local variable initialized but not referenced" Treat this as level 3, not level 4. |
129 | //#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4. | 107 | //#pragma warning( 3 : 4018 ) // "signed/unsigned mismatch" Treat this as level 3, not level 4. |
108 | #pragma warning( 3 : 4263 ) // 'function' : member function does not override any base class virtual member function | ||
109 | #pragma warning( 3 : 4264 ) // "'virtual_function' : no override available for virtual member function from base 'class'; function is hidden" | ||
130 | #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" | 110 | #pragma warning( 3 : 4265 ) // "class has virtual functions, but destructor is not virtual" |
131 | #pragma warning( disable : 4786 ) // silly MS warning deep inside their <map> include file | 111 | //#pragma warning( disable : 4265 ) // boost 1.36.0, non-virtual destructor in boost::exception_detail::* |
112 | #pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden | ||
113 | #pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored | ||
132 | #pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file | 114 | #pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file |
133 | #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. | 115 | #pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation. |
134 | #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) | 116 | #pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning) |
135 | #pragma warning( disable : 4996 ) // warning: deprecated | 117 | #pragma warning( disable : 4996 ) // warning: deprecated |
118 | |||
119 | // Linker optimization with "extern template" generates these warnings | ||
120 | #pragma warning( disable : 4231 ) // nonstandard extension used : 'extern' before template explicit instantiation | ||
121 | #pragma warning( disable : 4506 ) // no definition for inline function | ||
122 | |||
123 | // level 4 warnings that we need to disable: | ||
124 | #pragma warning (disable : 4100) // unreferenced formal parameter | ||
125 | #pragma warning (disable : 4127) // conditional expression is constant (e.g. while(1) ) | ||
126 | #pragma warning (disable : 4244) // possible loss of data on conversions | ||
127 | #pragma warning (disable : 4396) // the inline specifier cannot be used when a friend declaration refers to a specialization of a function template | ||
128 | #pragma warning (disable : 4512) // assignment operator could not be generated | ||
129 | #pragma warning (disable : 4706) // assignment within conditional (even if((x = y)) ) | ||
130 | |||
131 | #pragma warning (disable : 4251) // member needs to have dll-interface to be used by clients of class | ||
132 | #pragma warning (disable : 4275) // non dll-interface class used as base for dll-interface class | ||
136 | #endif // LL_MSVC | 133 | #endif // LL_MSVC |
137 | 134 | ||
135 | #if LL_WINDOWS | ||
136 | #define LL_DLLEXPORT __declspec(dllexport) | ||
137 | #define LL_DLLIMPORT __declspec(dllimport) | ||
138 | #elif LL_LINUX | ||
139 | #define LL_DLLEXPORT __attribute__ ((visibility("default"))) | ||
140 | #define LL_DLLIMPORT | ||
141 | #else | ||
142 | #define LL_DLLEXPORT | ||
143 | #define LL_DLLIMPORT | ||
144 | #endif // LL_WINDOWS | ||
145 | |||
146 | #ifdef llcommon_EXPORTS | ||
147 | // Compiling llcommon (shared) | ||
148 | #define LL_COMMON_API LL_DLLEXPORT | ||
149 | #else // llcommon_EXPORTS | ||
150 | // Using llcommon (shared) | ||
151 | #define LL_COMMON_API LL_DLLIMPORT | ||
152 | #endif // llcommon_EXPORTS | ||
153 | |||
138 | #endif // not LL_LINDEN_PREPROCESSOR_H | 154 | #endif // not LL_LINDEN_PREPROCESSOR_H |
diff --git a/linden/indra/llcommon/llprocesslauncher.cpp b/linden/indra/llcommon/llprocesslauncher.cpp new file mode 100644 index 0000000..e27aaa3 --- /dev/null +++ b/linden/indra/llcommon/llprocesslauncher.cpp | |||
@@ -0,0 +1,346 @@ | |||
1 | /** | ||
2 | * @file llprocesslauncher.cpp | ||
3 | * @brief Utility class for launching, terminating, and tracking the state of processes. | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2008&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2008-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include "linden_common.h" | ||
34 | |||
35 | #include "llprocesslauncher.h" | ||
36 | |||
37 | #include <iostream> | ||
38 | #if LL_DARWIN || LL_LINUX | ||
39 | // not required or present on Win32 | ||
40 | #include <sys/wait.h> | ||
41 | #endif | ||
42 | |||
43 | LLProcessLauncher::LLProcessLauncher() | ||
44 | { | ||
45 | #if LL_WINDOWS | ||
46 | mProcessHandle = 0; | ||
47 | #else | ||
48 | mProcessID = 0; | ||
49 | #endif | ||
50 | } | ||
51 | |||
52 | LLProcessLauncher::~LLProcessLauncher() | ||
53 | { | ||
54 | kill(); | ||
55 | } | ||
56 | |||
57 | void LLProcessLauncher::setExecutable(const std::string &executable) | ||
58 | { | ||
59 | mExecutable = executable; | ||
60 | } | ||
61 | |||
62 | void LLProcessLauncher::setWorkingDirectory(const std::string &dir) | ||
63 | { | ||
64 | mWorkingDir = dir; | ||
65 | } | ||
66 | |||
67 | void LLProcessLauncher::clearArguments() | ||
68 | { | ||
69 | mLaunchArguments.clear(); | ||
70 | } | ||
71 | |||
72 | void LLProcessLauncher::addArgument(const std::string &arg) | ||
73 | { | ||
74 | mLaunchArguments.push_back(arg); | ||
75 | } | ||
76 | |||
77 | void LLProcessLauncher::addArgument(const char *arg) | ||
78 | { | ||
79 | mLaunchArguments.push_back(std::string(arg)); | ||
80 | } | ||
81 | |||
82 | #if LL_WINDOWS | ||
83 | |||
84 | int LLProcessLauncher::launch(void) | ||
85 | { | ||
86 | // If there was already a process associated with this object, kill it. | ||
87 | kill(); | ||
88 | orphan(); | ||
89 | |||
90 | int result = 0; | ||
91 | |||
92 | PROCESS_INFORMATION pinfo; | ||
93 | STARTUPINFOA sinfo; | ||
94 | memset(&sinfo, 0, sizeof(sinfo)); | ||
95 | |||
96 | std::string args = "\"" + mExecutable + "\""; | ||
97 | for(int i = 0; i < (int)mLaunchArguments.size(); i++) | ||
98 | { | ||
99 | args += " "; | ||
100 | args += mLaunchArguments[i]; | ||
101 | } | ||
102 | LL_INFOS("Plugin") << "Executable: " << mExecutable << " arguments: " << args << LL_ENDL; | ||
103 | |||
104 | // So retarded. Windows requires that the second parameter to CreateProcessA be a writable (non-const) string... | ||
105 | char *args2 = new char[args.size() + 1]; | ||
106 | strcpy(args2, args.c_str()); | ||
107 | |||
108 | if( ! CreateProcessA( NULL, args2, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo ) ) | ||
109 | { | ||
110 | // TODO: do better than returning the OS-specific error code on failure... | ||
111 | result = GetLastError(); | ||
112 | if(result == 0) | ||
113 | { | ||
114 | // Make absolutely certain we return a non-zero value on failure. | ||
115 | result = -1; | ||
116 | } | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | // foo = pinfo.dwProcessId; // get your pid here if you want to use it later on | ||
121 | // CloseHandle(pinfo.hProcess); // stops leaks - nothing else | ||
122 | mProcessHandle = pinfo.hProcess; | ||
123 | CloseHandle(pinfo.hThread); // stops leaks - nothing else | ||
124 | } | ||
125 | |||
126 | delete[] args2; | ||
127 | |||
128 | return result; | ||
129 | } | ||
130 | |||
131 | bool LLProcessLauncher::isRunning(void) | ||
132 | { | ||
133 | if(mProcessHandle != 0) | ||
134 | { | ||
135 | DWORD waitresult = WaitForSingleObject(mProcessHandle, 0); | ||
136 | if(waitresult == WAIT_OBJECT_0) | ||
137 | { | ||
138 | // the process has completed. | ||
139 | mProcessHandle = 0; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | return (mProcessHandle != 0); | ||
144 | } | ||
145 | bool LLProcessLauncher::kill(void) | ||
146 | { | ||
147 | bool result = true; | ||
148 | |||
149 | if(mProcessHandle != 0) | ||
150 | { | ||
151 | TerminateProcess(mProcessHandle,0); | ||
152 | |||
153 | if(isRunning()) | ||
154 | { | ||
155 | result = false; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | return result; | ||
160 | } | ||
161 | |||
162 | void LLProcessLauncher::orphan(void) | ||
163 | { | ||
164 | // Forget about the process | ||
165 | mProcessHandle = 0; | ||
166 | } | ||
167 | |||
168 | // static | ||
169 | void LLProcessLauncher::reap(void) | ||
170 | { | ||
171 | // No actions necessary on Windows. | ||
172 | } | ||
173 | |||
174 | #else // Mac and linux | ||
175 | |||
176 | #include <signal.h> | ||
177 | #include <fcntl.h> | ||
178 | #include <errno.h> | ||
179 | |||
180 | static std::list<pid_t> sZombies; | ||
181 | |||
182 | // Attempt to reap a process ID -- returns true if the process has exited and been reaped, false otherwise. | ||
183 | static bool reap_pid(pid_t pid) | ||
184 | { | ||
185 | bool result = false; | ||
186 | |||
187 | pid_t wait_result = ::waitpid(pid, NULL, WNOHANG); | ||
188 | if(wait_result == pid) | ||
189 | { | ||
190 | result = true; | ||
191 | } | ||
192 | else if(wait_result == -1) | ||
193 | { | ||
194 | if(errno == ECHILD) | ||
195 | { | ||
196 | // No such process -- this may mean we're ignoring SIGCHILD. | ||
197 | result = true; | ||
198 | } | ||
199 | } | ||
200 | |||
201 | return result; | ||
202 | } | ||
203 | |||
204 | int LLProcessLauncher::launch(void) | ||
205 | { | ||
206 | // If there was already a process associated with this object, kill it. | ||
207 | kill(); | ||
208 | orphan(); | ||
209 | |||
210 | int result = 0; | ||
211 | int current_wd = -1; | ||
212 | |||
213 | // create an argv vector for the child process | ||
214 | const char ** fake_argv = new const char *[mLaunchArguments.size() + 2]; // 1 for the executable path, 1 for the NULL terminator | ||
215 | |||
216 | int i = 0; | ||
217 | |||
218 | // add the executable path | ||
219 | fake_argv[i++] = mExecutable.c_str(); | ||
220 | |||
221 | // and any arguments | ||
222 | for(int j=0; j < mLaunchArguments.size(); j++) | ||
223 | fake_argv[i++] = mLaunchArguments[j].c_str(); | ||
224 | |||
225 | // terminate with a null pointer | ||
226 | fake_argv[i] = NULL; | ||
227 | |||
228 | if(!mWorkingDir.empty()) | ||
229 | { | ||
230 | // save the current working directory | ||
231 | current_wd = ::open(".", O_RDONLY); | ||
232 | |||
233 | // and change to the one the child will be executed in | ||
234 | if (::chdir(mWorkingDir.c_str())) | ||
235 | { | ||
236 | // chdir failed | ||
237 | } | ||
238 | } | ||
239 | |||
240 | // flush all buffers before the child inherits them | ||
241 | ::fflush(NULL); | ||
242 | |||
243 | pid_t id = vfork(); | ||
244 | if(id == 0) | ||
245 | { | ||
246 | // child process | ||
247 | |||
248 | ::execv(mExecutable.c_str(), (char * const *)fake_argv); | ||
249 | |||
250 | // If we reach this point, the exec failed. | ||
251 | // Use _exit() instead of exit() per the vfork man page. | ||
252 | _exit(0); | ||
253 | } | ||
254 | |||
255 | // parent process | ||
256 | |||
257 | if(current_wd >= 0) | ||
258 | { | ||
259 | // restore the previous working directory | ||
260 | if (::fchdir(current_wd)) | ||
261 | { | ||
262 | // chdir failed | ||
263 | } | ||
264 | ::close(current_wd); | ||
265 | } | ||
266 | |||
267 | delete[] fake_argv; | ||
268 | |||
269 | mProcessID = id; | ||
270 | |||
271 | // At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked) | ||
272 | // If the process doesn't exist at this point, the exec failed. | ||
273 | if(!isRunning()) | ||
274 | { | ||
275 | result = -1; | ||
276 | } | ||
277 | |||
278 | return result; | ||
279 | } | ||
280 | |||
281 | bool LLProcessLauncher::isRunning(void) | ||
282 | { | ||
283 | if(mProcessID != 0) | ||
284 | { | ||
285 | // Check whether the process has exited, and reap it if it has. | ||
286 | if(reap_pid(mProcessID)) | ||
287 | { | ||
288 | // the process has exited. | ||
289 | mProcessID = 0; | ||
290 | } | ||
291 | } | ||
292 | |||
293 | return (mProcessID != 0); | ||
294 | } | ||
295 | |||
296 | bool LLProcessLauncher::kill(void) | ||
297 | { | ||
298 | bool result = true; | ||
299 | |||
300 | if(mProcessID != 0) | ||
301 | { | ||
302 | // Try to kill the process. We'll do approximately the same thing whether the kill returns an error or not, so we ignore the result. | ||
303 | (void)::kill(mProcessID, SIGTERM); | ||
304 | |||
305 | // This will have the side-effect of reaping the zombie if the process has exited. | ||
306 | if(isRunning()) | ||
307 | { | ||
308 | result = false; | ||
309 | } | ||
310 | } | ||
311 | |||
312 | return result; | ||
313 | } | ||
314 | |||
315 | void LLProcessLauncher::orphan(void) | ||
316 | { | ||
317 | // Disassociate the process from this object | ||
318 | if(mProcessID != 0) | ||
319 | { | ||
320 | // We may still need to reap the process's zombie eventually | ||
321 | sZombies.push_back(mProcessID); | ||
322 | |||
323 | mProcessID = 0; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | // static | ||
328 | void LLProcessLauncher::reap(void) | ||
329 | { | ||
330 | // Attempt to real all saved process ID's. | ||
331 | |||
332 | std::list<pid_t>::iterator iter = sZombies.begin(); | ||
333 | while(iter != sZombies.end()) | ||
334 | { | ||
335 | if(reap_pid(*iter)) | ||
336 | { | ||
337 | iter = sZombies.erase(iter); | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | iter++; | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | |||
346 | #endif | ||
diff --git a/linden/indra/llcommon/llprocesslauncher.h b/linden/indra/llcommon/llprocesslauncher.h new file mode 100644 index 0000000..9833a13 --- /dev/null +++ b/linden/indra/llcommon/llprocesslauncher.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /** | ||
2 | * @file llprocesslauncher.h | ||
3 | * @brief Utility class for launching, terminating, and tracking the state of processes. | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2008&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2008-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #ifndef LL_LLPROCESSLAUNCHER_H | ||
34 | #define LL_LLPROCESSLAUNCHER_H | ||
35 | |||
36 | #if LL_WINDOWS | ||
37 | # define WIN32_LEAN_AND_MEAN | ||
38 | # include <winsock2.h> | ||
39 | #include <windows.h> | ||
40 | #endif | ||
41 | |||
42 | |||
43 | /* | ||
44 | LLProcessLauncher handles launching external processes with specified command line arguments. | ||
45 | It also keeps track of whether the process is still running, and can kill it if required. | ||
46 | */ | ||
47 | |||
48 | class LL_COMMON_API LLProcessLauncher | ||
49 | { | ||
50 | LOG_CLASS(LLProcessLauncher); | ||
51 | public: | ||
52 | LLProcessLauncher(); | ||
53 | virtual ~LLProcessLauncher(); | ||
54 | |||
55 | void setExecutable(const std::string &executable); | ||
56 | void setWorkingDirectory(const std::string &dir); | ||
57 | |||
58 | void clearArguments(); | ||
59 | void addArgument(const std::string &arg); | ||
60 | void addArgument(const char *arg); | ||
61 | |||
62 | int launch(void); | ||
63 | bool isRunning(void); | ||
64 | |||
65 | // Attempt to kill the process -- returns true if the process is no longer running when it returns. | ||
66 | // Note that even if this returns false, the process may exit some time after it's called. | ||
67 | bool kill(void); | ||
68 | |||
69 | // Use this if you want the external process to continue execution after the LLProcessLauncher instance controlling it is deleted. | ||
70 | // Normally, the destructor will attempt to kill the process and wait for termination. | ||
71 | // This should only be used if the viewer is about to exit -- otherwise, the child process will become a zombie after it exits. | ||
72 | void orphan(void); | ||
73 | |||
74 | // This needs to be called periodically on Mac/Linux to clean up zombie processes. | ||
75 | static void reap(void); | ||
76 | private: | ||
77 | std::string mExecutable; | ||
78 | std::string mWorkingDir; | ||
79 | std::vector<std::string> mLaunchArguments; | ||
80 | |||
81 | #if LL_WINDOWS | ||
82 | HANDLE mProcessHandle; | ||
83 | #else | ||
84 | pid_t mProcessID; | ||
85 | |||
86 | public: | ||
87 | pid_t getProcessID() const { return mProcessID; } | ||
88 | #endif | ||
89 | }; | ||
90 | |||
91 | #endif // LL_LLPROCESSLAUNCHER_H | ||
diff --git a/linden/indra/llcommon/llqueuedthread.cpp b/linden/indra/llcommon/llqueuedthread.cpp index caf4c2a..bee95be 100644 --- a/linden/indra/llcommon/llqueuedthread.cpp +++ b/linden/indra/llcommon/llqueuedthread.cpp | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "linden_common.h" | 32 | #include "linden_common.h" |
33 | #include "llqueuedthread.h" | 33 | #include "llqueuedthread.h" |
34 | #include "llstl.h" | 34 | #include "llstl.h" |
35 | #include "lltimer.h" | ||
35 | 36 | ||
36 | //============================================================================ | 37 | //============================================================================ |
37 | 38 | ||
diff --git a/linden/indra/llcommon/llqueuedthread.h b/linden/indra/llcommon/llqueuedthread.h index aa7c6e4..e0e0f1b 100644 --- a/linden/indra/llcommon/llqueuedthread.h +++ b/linden/indra/llcommon/llqueuedthread.h | |||
@@ -47,7 +47,7 @@ | |||
47 | // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small | 47 | // Note: ~LLQueuedThread is O(N) N=# of queued threads, assumed to be small |
48 | // It is assumed that LLQueuedThreads are rarely created/destroyed. | 48 | // It is assumed that LLQueuedThreads are rarely created/destroyed. |
49 | 49 | ||
50 | class LLQueuedThread : public LLThread | 50 | class LL_COMMON_API LLQueuedThread : public LLThread |
51 | { | 51 | { |
52 | //------------------------------------------------------------------------ | 52 | //------------------------------------------------------------------------ |
53 | public: | 53 | public: |
@@ -80,7 +80,7 @@ public: | |||
80 | //------------------------------------------------------------------------ | 80 | //------------------------------------------------------------------------ |
81 | public: | 81 | public: |
82 | 82 | ||
83 | class QueuedRequest : public LLSimpleHashEntry<handle_t> | 83 | class LL_COMMON_API QueuedRequest : public LLSimpleHashEntry<handle_t> |
84 | { | 84 | { |
85 | friend class LLQueuedThread; | 85 | friend class LLQueuedThread; |
86 | 86 | ||
diff --git a/linden/indra/llcommon/llrand.h b/linden/indra/llcommon/llrand.h index d12597b..73ea179 100644 --- a/linden/indra/llcommon/llrand.h +++ b/linden/indra/llcommon/llrand.h | |||
@@ -65,32 +65,32 @@ | |||
65 | /** | 65 | /** |
66 | *@brief Generate a float from [0, RAND_MAX). | 66 | *@brief Generate a float from [0, RAND_MAX). |
67 | */ | 67 | */ |
68 | S32 ll_rand(); | 68 | LL_COMMON_API S32 ll_rand(); |
69 | 69 | ||
70 | /** | 70 | /** |
71 | *@brief Generate a float from [0, val) or (val, 0]. | 71 | *@brief Generate a float from [0, val) or (val, 0]. |
72 | */ | 72 | */ |
73 | S32 ll_rand(S32 val); | 73 | LL_COMMON_API S32 ll_rand(S32 val); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | *@brief Generate a float from [0, 1.0). | 76 | *@brief Generate a float from [0, 1.0). |
77 | */ | 77 | */ |
78 | F32 ll_frand(); | 78 | LL_COMMON_API F32 ll_frand(); |
79 | 79 | ||
80 | /** | 80 | /** |
81 | *@brief Generate a float from [0, val) or (val, 0]. | 81 | *@brief Generate a float from [0, val) or (val, 0]. |
82 | */ | 82 | */ |
83 | F32 ll_frand(F32 val); | 83 | LL_COMMON_API F32 ll_frand(F32 val); |
84 | 84 | ||
85 | /** | 85 | /** |
86 | *@brief Generate a double from [0, 1.0). | 86 | *@brief Generate a double from [0, 1.0). |
87 | */ | 87 | */ |
88 | F64 ll_drand(); | 88 | LL_COMMON_API F64 ll_drand(); |
89 | 89 | ||
90 | /** | 90 | /** |
91 | *@brief Generate a double from [0, val) or (val, 0]. | 91 | *@brief Generate a double from [0, val) or (val, 0]. |
92 | */ | 92 | */ |
93 | F64 ll_drand(F64 val); | 93 | LL_COMMON_API F64 ll_drand(F64 val); |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * @brief typedefs for good boost lagged fibonacci. | 96 | * @brief typedefs for good boost lagged fibonacci. |
diff --git a/linden/indra/llcommon/llrun.h b/linden/indra/llcommon/llrun.h index 77b23d9..0f8d51d 100644 --- a/linden/indra/llcommon/llrun.h +++ b/linden/indra/llcommon/llrun.h | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <vector> | 38 | #include <vector> |
39 | #include <boost/shared_ptr.hpp> | 39 | #include <boost/shared_ptr.hpp> |
40 | 40 | ||
41 | #include "llpreprocessor.h" | ||
42 | |||
41 | class LLRunnable; | 43 | class LLRunnable; |
42 | 44 | ||
43 | /** | 45 | /** |
@@ -48,7 +50,7 @@ class LLRunnable; | |||
48 | * which are scheduled to run on a repeating or one time basis. | 50 | * which are scheduled to run on a repeating or one time basis. |
49 | * @see LLRunnable | 51 | * @see LLRunnable |
50 | */ | 52 | */ |
51 | class LLRunner | 53 | class LL_COMMON_API LLRunner |
52 | { | 54 | { |
53 | public: | 55 | public: |
54 | /** | 56 | /** |
@@ -149,7 +151,7 @@ protected: | |||
149 | * something useful. | 151 | * something useful. |
150 | * @see LLRunner | 152 | * @see LLRunner |
151 | */ | 153 | */ |
152 | class LLRunnable | 154 | class LL_COMMON_API LLRunnable |
153 | { | 155 | { |
154 | public: | 156 | public: |
155 | LLRunnable(); | 157 | LLRunnable(); |
diff --git a/linden/indra/llcommon/llscopedvolatileaprpool.h b/linden/indra/llcommon/llscopedvolatileaprpool.h new file mode 100644 index 0000000..724dc7f --- /dev/null +++ b/linden/indra/llcommon/llscopedvolatileaprpool.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /** | ||
2 | * @file llscopedvolatileaprpool.h | ||
3 | * @brief Implementation of LLScopedVolatileAPRPool | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2010&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2010, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #ifndef LL_LLSCOPEDVOLATILEAPRPOOL_H | ||
34 | #define LL_LLSCOPEDVOLATILEAPRPOOL_H | ||
35 | |||
36 | #include "llthread.h" | ||
37 | |||
38 | //! Scoped volatile memory pool. | ||
39 | // | ||
40 | // As the AIVolatileAPRPool should never keep allocations very | ||
41 | // long, it's most common use is for allocations with a lifetime | ||
42 | // equal to it's scope. | ||
43 | // | ||
44 | // This is a convenience class that makes just a little easier to type. | ||
45 | // | ||
46 | class LLScopedVolatileAPRPool | ||
47 | { | ||
48 | private: | ||
49 | AIVolatileAPRPool& mPool; | ||
50 | apr_pool_t* mScopedAPRpool; | ||
51 | public: | ||
52 | LLScopedVolatileAPRPool() : mPool(AIThreadLocalData::tldata().mVolatileAPRPool), mScopedAPRpool(mPool.getVolatileAPRPool()) { } | ||
53 | ~LLScopedVolatileAPRPool() { mPool.clearVolatileAPRPool(); } | ||
54 | // Only use this to pass the pointer to a libapr-1 function that requires it. | ||
55 | operator apr_pool_t*() const { return mScopedAPRpool; } | ||
56 | }; | ||
57 | |||
58 | #endif | ||
diff --git a/linden/indra/llcommon/llsd.cpp b/linden/indra/llcommon/llsd.cpp index 2cc94c2..be40bb6 100644 --- a/linden/indra/llcommon/llsd.cpp +++ b/linden/indra/llcommon/llsd.cpp | |||
@@ -75,7 +75,7 @@ protected: | |||
75 | ///< This constructor is used for static objects and causes the | 75 | ///< This constructor is used for static objects and causes the |
76 | // suppresses adjusting the debugging counters when they are | 76 | // suppresses adjusting the debugging counters when they are |
77 | // finally initialized. | 77 | // finally initialized. |
78 | 78 | ||
79 | virtual ~Impl(); | 79 | virtual ~Impl(); |
80 | 80 | ||
81 | bool shared() const { return mUseCount > 1; } | 81 | bool shared() const { return mUseCount > 1; } |
@@ -162,6 +162,7 @@ namespace | |||
162 | 162 | ||
163 | virtual LLSD::Type type() const { return T; } | 163 | virtual LLSD::Type type() const { return T; } |
164 | 164 | ||
165 | using LLSD::Impl::assign; | ||
165 | virtual void assign(LLSD::Impl*& var, DataRef value) { | 166 | virtual void assign(LLSD::Impl*& var, DataRef value) { |
166 | if (shared()) | 167 | if (shared()) |
167 | { | 168 | { |
@@ -348,6 +349,10 @@ namespace | |||
348 | 349 | ||
349 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } | 350 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } |
350 | 351 | ||
352 | using LLSD::Impl::get; // Unhiding get(LLSD::Integer) | ||
353 | using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) | ||
354 | using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) | ||
355 | |||
351 | virtual bool has(const LLSD::String&) const; | 356 | virtual bool has(const LLSD::String&) const; |
352 | virtual LLSD get(const LLSD::String&) const; | 357 | virtual LLSD get(const LLSD::String&) const; |
353 | LLSD& insert(const LLSD::String& k, const LLSD& v); | 358 | LLSD& insert(const LLSD::String& k, const LLSD& v); |
@@ -440,6 +445,11 @@ namespace | |||
440 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } | 445 | virtual LLSD::Boolean asBoolean() const { return !mData.empty(); } |
441 | 446 | ||
442 | virtual int size() const; | 447 | virtual int size() const; |
448 | |||
449 | using LLSD::Impl::get; // Unhiding get(LLSD::Integer) | ||
450 | using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) | ||
451 | using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) | ||
452 | |||
443 | virtual LLSD get(LLSD::Integer) const; | 453 | virtual LLSD get(LLSD::Integer) const; |
444 | void set(LLSD::Integer, const LLSD&); | 454 | void set(LLSD::Integer, const LLSD&); |
445 | LLSD& insert(LLSD::Integer, const LLSD&); | 455 | LLSD& insert(LLSD::Integer, const LLSD&); |
diff --git a/linden/indra/llcommon/llsd.h b/linden/indra/llcommon/llsd.h index d2845a3..552bb57 100644 --- a/linden/indra/llcommon/llsd.h +++ b/linden/indra/llcommon/llsd.h | |||
@@ -89,7 +89,7 @@ | |||
89 | @nosubgrouping | 89 | @nosubgrouping |
90 | */ | 90 | */ |
91 | 91 | ||
92 | class LLSD | 92 | class LL_COMMON_API LLSD |
93 | { | 93 | { |
94 | public: | 94 | public: |
95 | LLSD(); ///< initially Undefined | 95 | LLSD(); ///< initially Undefined |
@@ -387,7 +387,7 @@ struct llsd_select_string : public std::unary_function<LLSD, LLSD::String> | |||
387 | } | 387 | } |
388 | }; | 388 | }; |
389 | 389 | ||
390 | std::ostream& operator<<(std::ostream& s, const LLSD& llsd); | 390 | LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLSD& llsd); |
391 | 391 | ||
392 | /** QUESTIONS & TO DOS | 392 | /** QUESTIONS & TO DOS |
393 | - Would Binary be more convenient as usigned char* buffer semantics? | 393 | - Would Binary be more convenient as usigned char* buffer semantics? |
diff --git a/linden/indra/llcommon/llsdserialize.h b/linden/indra/llcommon/llsdserialize.h index f7cd91b..a01b6dc 100644 --- a/linden/indra/llcommon/llsdserialize.h +++ b/linden/indra/llcommon/llsdserialize.h | |||
@@ -43,7 +43,7 @@ | |||
43 | * @class LLSDParser | 43 | * @class LLSDParser |
44 | * @brief Abstract base class for LLSD parsers. | 44 | * @brief Abstract base class for LLSD parsers. |
45 | */ | 45 | */ |
46 | class LLSDParser : public LLRefCount | 46 | class LL_COMMON_API LLSDParser : public LLRefCount |
47 | { | 47 | { |
48 | protected: | 48 | protected: |
49 | /** | 49 | /** |
@@ -220,7 +220,7 @@ protected: | |||
220 | * @class LLSDNotationParser | 220 | * @class LLSDNotationParser |
221 | * @brief Parser which handles the original notation format for LLSD. | 221 | * @brief Parser which handles the original notation format for LLSD. |
222 | */ | 222 | */ |
223 | class LLSDNotationParser : public LLSDParser | 223 | class LL_COMMON_API LLSDNotationParser : public LLSDParser |
224 | { | 224 | { |
225 | protected: | 225 | protected: |
226 | /** | 226 | /** |
@@ -293,7 +293,7 @@ private: | |||
293 | * @class LLSDXMLParser | 293 | * @class LLSDXMLParser |
294 | * @brief Parser which handles XML format LLSD. | 294 | * @brief Parser which handles XML format LLSD. |
295 | */ | 295 | */ |
296 | class LLSDXMLParser : public LLSDParser | 296 | class LL_COMMON_API LLSDXMLParser : public LLSDParser |
297 | { | 297 | { |
298 | protected: | 298 | protected: |
299 | /** | 299 | /** |
@@ -341,7 +341,7 @@ private: | |||
341 | * @class LLSDBinaryParser | 341 | * @class LLSDBinaryParser |
342 | * @brief Parser which handles binary formatted LLSD. | 342 | * @brief Parser which handles binary formatted LLSD. |
343 | */ | 343 | */ |
344 | class LLSDBinaryParser : public LLSDParser | 344 | class LL_COMMON_API LLSDBinaryParser : public LLSDParser |
345 | { | 345 | { |
346 | protected: | 346 | protected: |
347 | /** | 347 | /** |
@@ -406,7 +406,7 @@ private: | |||
406 | * @class LLSDFormatter | 406 | * @class LLSDFormatter |
407 | * @brief Abstract base class for formatting LLSD. | 407 | * @brief Abstract base class for formatting LLSD. |
408 | */ | 408 | */ |
409 | class LLSDFormatter : public LLRefCount | 409 | class LL_COMMON_API LLSDFormatter : public LLRefCount |
410 | { | 410 | { |
411 | protected: | 411 | protected: |
412 | /** | 412 | /** |
@@ -478,7 +478,7 @@ protected: | |||
478 | * @class LLSDNotationFormatter | 478 | * @class LLSDNotationFormatter |
479 | * @brief Formatter which outputs the original notation format for LLSD. | 479 | * @brief Formatter which outputs the original notation format for LLSD. |
480 | */ | 480 | */ |
481 | class LLSDNotationFormatter : public LLSDFormatter | 481 | class LL_COMMON_API LLSDNotationFormatter : public LLSDFormatter |
482 | { | 482 | { |
483 | protected: | 483 | protected: |
484 | /** | 484 | /** |
@@ -519,7 +519,7 @@ public: | |||
519 | * @class LLSDXMLFormatter | 519 | * @class LLSDXMLFormatter |
520 | * @brief Formatter which outputs the LLSD as XML. | 520 | * @brief Formatter which outputs the LLSD as XML. |
521 | */ | 521 | */ |
522 | class LLSDXMLFormatter : public LLSDFormatter | 522 | class LL_COMMON_API LLSDXMLFormatter : public LLSDFormatter |
523 | { | 523 | { |
524 | protected: | 524 | protected: |
525 | /** | 525 | /** |
@@ -587,7 +587,7 @@ protected: | |||
587 | * Map: '{' + 4 byte integer size every(key + value) + '}'<br> | 587 | * Map: '{' + 4 byte integer size every(key + value) + '}'<br> |
588 | * map keys are serialized as 'k' + 4 byte integer size + string | 588 | * map keys are serialized as 'k' + 4 byte integer size + string |
589 | */ | 589 | */ |
590 | class LLSDBinaryFormatter : public LLSDFormatter | 590 | class LL_COMMON_API LLSDBinaryFormatter : public LLSDFormatter |
591 | { | 591 | { |
592 | protected: | 592 | protected: |
593 | /** | 593 | /** |
@@ -676,7 +676,7 @@ typedef LLSDOStreamer<LLSDXMLFormatter> LLSDXMLStreamer; | |||
676 | * @class LLSDSerialize | 676 | * @class LLSDSerialize |
677 | * @brief Serializer / deserializer for the various LLSD formats | 677 | * @brief Serializer / deserializer for the various LLSD formats |
678 | */ | 678 | */ |
679 | class LLSDSerialize | 679 | class LL_COMMON_API LLSDSerialize |
680 | { | 680 | { |
681 | public: | 681 | public: |
682 | enum ELLSD_Serialize | 682 | enum ELLSD_Serialize |
diff --git a/linden/indra/llcommon/llsdserialize_xml.cpp b/linden/indra/llcommon/llsdserialize_xml.cpp index c12ca35..33206b4 100644 --- a/linden/indra/llcommon/llsdserialize_xml.cpp +++ b/linden/indra/llcommon/llsdserialize_xml.cpp | |||
@@ -562,7 +562,7 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, int len) | |||
562 | 562 | ||
563 | #ifdef XML_PARSER_PERFORMANCE_TESTS | 563 | #ifdef XML_PARSER_PERFORMANCE_TESTS |
564 | 564 | ||
565 | extern U64 totalTime(); | 565 | extern LL_COMMON_API U64 totalTime(); |
566 | U64 readElementTime = 0; | 566 | U64 readElementTime = 0; |
567 | U64 startElementTime = 0; | 567 | U64 startElementTime = 0; |
568 | U64 endElementTime = 0; | 568 | U64 endElementTime = 0; |
diff --git a/linden/indra/llcommon/llsdutil.h b/linden/indra/llcommon/llsdutil.h index b67ad52..4740a30 100644 --- a/linden/indra/llcommon/llsdutil.h +++ b/linden/indra/llcommon/llsdutil.h | |||
@@ -68,28 +68,28 @@ LLSD ll_sd_from_color4(const LLColor4& c); | |||
68 | LLColor4 ll_color4_from_sd(const LLSD& sd); | 68 | LLColor4 ll_color4_from_sd(const LLSD& sd); |
69 | 69 | ||
70 | // U32 | 70 | // U32 |
71 | LLSD ll_sd_from_U32(const U32); | 71 | LL_COMMON_API LLSD ll_sd_from_U32(const U32); |
72 | U32 ll_U32_from_sd(const LLSD& sd); | 72 | LL_COMMON_API U32 ll_U32_from_sd(const LLSD& sd); |
73 | 73 | ||
74 | // U64 | 74 | // U64 |
75 | LLSD ll_sd_from_U64(const U64); | 75 | LL_COMMON_API LLSD ll_sd_from_U64(const U64); |
76 | U64 ll_U64_from_sd(const LLSD& sd); | 76 | LL_COMMON_API U64 ll_U64_from_sd(const LLSD& sd); |
77 | 77 | ||
78 | // IP Address | 78 | // IP Address |
79 | LLSD ll_sd_from_ipaddr(const U32); | 79 | LL_COMMON_API LLSD ll_sd_from_ipaddr(const U32); |
80 | U32 ll_ipaddr_from_sd(const LLSD& sd); | 80 | LL_COMMON_API U32 ll_ipaddr_from_sd(const LLSD& sd); |
81 | 81 | ||
82 | // Binary to string | 82 | // Binary to string |
83 | LLSD ll_string_from_binary(const LLSD& sd); | 83 | LL_COMMON_API LLSD ll_string_from_binary(const LLSD& sd); |
84 | 84 | ||
85 | //String to binary | 85 | //String to binary |
86 | LLSD ll_binary_from_string(const LLSD& sd); | 86 | LL_COMMON_API LLSD ll_binary_from_string(const LLSD& sd); |
87 | 87 | ||
88 | // Serializes sd to static buffer and returns pointer, useful for gdb debugging. | 88 | // Serializes sd to static buffer and returns pointer, useful for gdb debugging. |
89 | char* ll_print_sd(const LLSD& sd); | 89 | LL_COMMON_API char* ll_print_sd(const LLSD& sd); |
90 | 90 | ||
91 | // Serializes sd to static buffer and returns pointer, using "pretty printing" mode. | 91 | // Serializes sd to static buffer and returns pointer, using "pretty printing" mode. |
92 | char* ll_pretty_print_sd(const LLSD& sd); | 92 | LL_COMMON_API char* ll_pretty_print_sd(const LLSD& sd); |
93 | 93 | ||
94 | //compares the structure of an LLSD to a template LLSD and stores the | 94 | //compares the structure of an LLSD to a template LLSD and stores the |
95 | //"valid" values in a 3rd LLSD. Default values | 95 | //"valid" values in a 3rd LLSD. Default values |
@@ -98,7 +98,7 @@ char* ll_pretty_print_sd(const LLSD& sd); | |||
98 | //Returns false if the test is of same type but values differ in type | 98 | //Returns false if the test is of same type but values differ in type |
99 | //Otherwise, returns true | 99 | //Otherwise, returns true |
100 | 100 | ||
101 | BOOL compare_llsd_with_template( | 101 | LL_COMMON_API BOOL compare_llsd_with_template( |
102 | const LLSD& llsd_to_test, | 102 | const LLSD& llsd_to_test, |
103 | const LLSD& template_llsd, | 103 | const LLSD& template_llsd, |
104 | LLSD& resultant_llsd); | 104 | LLSD& resultant_llsd); |
diff --git a/linden/indra/llcommon/llsecondlifeurls.h b/linden/indra/llcommon/llsecondlifeurls.h index 9c64b57..e3932d0 100644 --- a/linden/indra/llcommon/llsecondlifeurls.h +++ b/linden/indra/llcommon/llsecondlifeurls.h | |||
@@ -34,14 +34,14 @@ | |||
34 | #define LL_LLSECONDLIFEURLS_H | 34 | #define LL_LLSECONDLIFEURLS_H |
35 | 35 | ||
36 | 36 | ||
37 | extern const std::string AUCTION_URL; | 37 | LL_COMMON_API extern const std::string AUCTION_URL; |
38 | 38 | ||
39 | extern const std::string EVENTS_URL; | 39 | LL_COMMON_API extern const std::string EVENTS_URL; |
40 | 40 | ||
41 | // Currency page | 41 | // Currency page |
42 | extern const std::string BUY_CURRENCY_URL; | 42 | LL_COMMON_API extern const std::string BUY_CURRENCY_URL; |
43 | 43 | ||
44 | // Release Notes Redirect URL for Server and Viewer | 44 | // Release Notes Redirect URL for Server and Viewer |
45 | extern const std::string RELEASE_NOTES_BASE_URL; | 45 | LL_COMMON_API extern const std::string RELEASE_NOTES_BASE_URL; |
46 | 46 | ||
47 | #endif | 47 | #endif |
diff --git a/linden/indra/llcommon/llsimplehash.h b/linden/indra/llcommon/llsimplehash.h index 0ba2a30..5df93b6 100644 --- a/linden/indra/llcommon/llsimplehash.h +++ b/linden/indra/llcommon/llsimplehash.h | |||
@@ -64,7 +64,7 @@ public: | |||
64 | }; | 64 | }; |
65 | 65 | ||
66 | template <typename HASH_KEY_TYPE, int TABLE_SIZE> | 66 | template <typename HASH_KEY_TYPE, int TABLE_SIZE> |
67 | class LLSimpleHash | 67 | class LL_COMMON_API LLSimpleHash |
68 | { | 68 | { |
69 | public: | 69 | public: |
70 | LLSimpleHash() | 70 | LLSimpleHash() |
diff --git a/linden/indra/llcommon/llstat.h b/linden/indra/llcommon/llstat.h index 66521a3..951091b 100644 --- a/linden/indra/llcommon/llstat.h +++ b/linden/indra/llcommon/llstat.h | |||
@@ -52,7 +52,7 @@ class LLSD; | |||
52 | // amounts of time with very low memory cost. | 52 | // amounts of time with very low memory cost. |
53 | // | 53 | // |
54 | 54 | ||
55 | class LLStatAccum | 55 | class LL_COMMON_API LLStatAccum |
56 | { | 56 | { |
57 | protected: | 57 | protected: |
58 | LLStatAccum(bool use_frame_timer); | 58 | LLStatAccum(bool use_frame_timer); |
@@ -109,7 +109,7 @@ public: | |||
109 | F64 mLastSampleValue; | 109 | F64 mLastSampleValue; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | class LLStatMeasure : public LLStatAccum | 112 | class LL_COMMON_API LLStatMeasure : public LLStatAccum |
113 | // gathers statistics about things that are measured | 113 | // gathers statistics about things that are measured |
114 | // ex.: tempature, time dilation | 114 | // ex.: tempature, time dilation |
115 | { | 115 | { |
@@ -124,7 +124,7 @@ public: | |||
124 | }; | 124 | }; |
125 | 125 | ||
126 | 126 | ||
127 | class LLStatRate : public LLStatAccum | 127 | class LL_COMMON_API LLStatRate : public LLStatAccum |
128 | // gathers statistics about things that can be counted over time | 128 | // gathers statistics about things that can be counted over time |
129 | // ex.: LSL instructions executed, messages sent, simulator frames completed | 129 | // ex.: LSL instructions executed, messages sent, simulator frames completed |
130 | // renders it in terms of rate of thing per second | 130 | // renders it in terms of rate of thing per second |
@@ -140,7 +140,7 @@ public: | |||
140 | }; | 140 | }; |
141 | 141 | ||
142 | 142 | ||
143 | class LLStatTime : public LLStatAccum | 143 | class LL_COMMON_API LLStatTime : public LLStatAccum |
144 | // gathers statistics about time spent in a block of code | 144 | // gathers statistics about time spent in a block of code |
145 | // measure average duration per second in the block | 145 | // measure average duration per second in the block |
146 | { | 146 | { |
@@ -171,7 +171,7 @@ private: | |||
171 | 171 | ||
172 | 172 | ||
173 | // Use this class on the stack to record statistics about an area of code | 173 | // Use this class on the stack to record statistics about an area of code |
174 | class LLPerfBlock | 174 | class LL_COMMON_API LLPerfBlock |
175 | { | 175 | { |
176 | public: | 176 | public: |
177 | struct StatEntry | 177 | struct StatEntry |
@@ -213,7 +213,7 @@ private: | |||
213 | 213 | ||
214 | // ---------------------------------------------------------------------------- | 214 | // ---------------------------------------------------------------------------- |
215 | 215 | ||
216 | class LLPerfStats | 216 | class LL_COMMON_API LLPerfStats |
217 | { | 217 | { |
218 | public: | 218 | public: |
219 | LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); | 219 | LLPerfStats(const std::string& process_name = "unknown", S32 process_pid = 0); |
@@ -249,7 +249,7 @@ private: | |||
249 | }; | 249 | }; |
250 | 250 | ||
251 | // ---------------------------------------------------------------------------- | 251 | // ---------------------------------------------------------------------------- |
252 | class LLStat | 252 | class LL_COMMON_API LLStat |
253 | { | 253 | { |
254 | public: | 254 | public: |
255 | LLStat(const U32 num_bins = 32, BOOL use_frame_timer = FALSE); | 255 | LLStat(const U32 num_bins = 32, BOOL use_frame_timer = FALSE); |
diff --git a/linden/indra/llcommon/llstreamtools.h b/linden/indra/llcommon/llstreamtools.h index a6dc4d5..371fac5 100644 --- a/linden/indra/llcommon/llstreamtools.h +++ b/linden/indra/llcommon/llstreamtools.h | |||
@@ -39,23 +39,23 @@ | |||
39 | // unless specifed otherwise these all return input_stream.good() | 39 | // unless specifed otherwise these all return input_stream.good() |
40 | 40 | ||
41 | // skips spaces and tabs | 41 | // skips spaces and tabs |
42 | bool skip_whitespace(std::istream& input_stream); | 42 | LL_COMMON_API bool skip_whitespace(std::istream& input_stream); |
43 | 43 | ||
44 | // skips whitespace and newlines | 44 | // skips whitespace and newlines |
45 | bool skip_emptyspace(std::istream& input_stream); | 45 | LL_COMMON_API bool skip_emptyspace(std::istream& input_stream); |
46 | 46 | ||
47 | // skips emptyspace and lines that start with a # | 47 | // skips emptyspace and lines that start with a # |
48 | bool skip_comments_and_emptyspace(std::istream& input_stream); | 48 | LL_COMMON_API bool skip_comments_and_emptyspace(std::istream& input_stream); |
49 | 49 | ||
50 | // skips to character after next newline | 50 | // skips to character after next newline |
51 | bool skip_line(std::istream& input_stream); | 51 | LL_COMMON_API bool skip_line(std::istream& input_stream); |
52 | 52 | ||
53 | // skips to beginning of next non-emptyspace | 53 | // skips to beginning of next non-emptyspace |
54 | bool skip_to_next_word(std::istream& input_stream); | 54 | LL_COMMON_API bool skip_to_next_word(std::istream& input_stream); |
55 | 55 | ||
56 | // skips to character after the end of next keyword | 56 | // skips to character after the end of next keyword |
57 | // a 'keyword' is defined as the first word on a line | 57 | // a 'keyword' is defined as the first word on a line |
58 | bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream); | 58 | LL_COMMON_API bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream); |
59 | 59 | ||
60 | // skip_to_start_of_next_keyword() is disabled -- might tickle corruption bug | 60 | // skip_to_start_of_next_keyword() is disabled -- might tickle corruption bug |
61 | // in windows iostream | 61 | // in windows iostream |
@@ -65,14 +65,14 @@ bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream | |||
65 | 65 | ||
66 | // characters are pulled out of input_stream and appended to output_string | 66 | // characters are pulled out of input_stream and appended to output_string |
67 | // returns result of input_stream.good() after characters are pulled | 67 | // returns result of input_stream.good() after characters are pulled |
68 | bool get_word(std::string& output_string, std::istream& input_stream); | 68 | LL_COMMON_API bool get_word(std::string& output_string, std::istream& input_stream); |
69 | bool get_line(std::string& output_string, std::istream& input_stream); | 69 | LL_COMMON_API bool get_line(std::string& output_string, std::istream& input_stream); |
70 | 70 | ||
71 | // characters are pulled out of input_stream (up to a max of 'n') | 71 | // characters are pulled out of input_stream (up to a max of 'n') |
72 | // and appended to output_string | 72 | // and appended to output_string |
73 | // returns result of input_stream.good() after characters are pulled | 73 | // returns result of input_stream.good() after characters are pulled |
74 | bool get_word(std::string& output_string, std::istream& input_stream, int n); | 74 | LL_COMMON_API bool get_word(std::string& output_string, std::istream& input_stream, int n); |
75 | bool get_line(std::string& output_string, std::istream& input_stream, int n); | 75 | LL_COMMON_API bool get_line(std::string& output_string, std::istream& input_stream, int n); |
76 | 76 | ||
77 | // unget_line() is disabled -- might tickle corruption bug in windows iostream | 77 | // unget_line() is disabled -- might tickle corruption bug in windows iostream |
78 | //// backs up the input_stream by line_size + 1 characters | 78 | //// backs up the input_stream by line_size + 1 characters |
@@ -82,28 +82,28 @@ bool get_line(std::string& output_string, std::istream& input_stream, int n); | |||
82 | 82 | ||
83 | // removes the last char in 'line' if it matches 'c' | 83 | // removes the last char in 'line' if it matches 'c' |
84 | // returns true if removed last char | 84 | // returns true if removed last char |
85 | bool remove_last_char(char c, std::string& line); | 85 | LL_COMMON_API bool remove_last_char(char c, std::string& line); |
86 | 86 | ||
87 | // replaces escaped characters with the correct characters from left to right | 87 | // replaces escaped characters with the correct characters from left to right |
88 | // "\\" ---> '\\' | 88 | // "\\" ---> '\\' |
89 | // "\n" ---> '\n' | 89 | // "\n" ---> '\n' |
90 | void unescape_string(std::string& line); | 90 | LL_COMMON_API void unescape_string(std::string& line); |
91 | 91 | ||
92 | // replaces unescaped characters with expanded equivalents from left to right | 92 | // replaces unescaped characters with expanded equivalents from left to right |
93 | // '\\' ---> "\\" | 93 | // '\\' ---> "\\" |
94 | // '\n' ---> "\n" | 94 | // '\n' ---> "\n" |
95 | void escape_string(std::string& line); | 95 | LL_COMMON_API void escape_string(std::string& line); |
96 | 96 | ||
97 | // replaces each '\n' character with ' ' | 97 | // replaces each '\n' character with ' ' |
98 | void replace_newlines_with_whitespace(std::string& line); | 98 | LL_COMMON_API void replace_newlines_with_whitespace(std::string& line); |
99 | 99 | ||
100 | // erases any double-quote characters in line | 100 | // erases any double-quote characters in line |
101 | void remove_double_quotes(std::string& line); | 101 | LL_COMMON_API void remove_double_quotes(std::string& line); |
102 | 102 | ||
103 | // the 'keyword' is defined as the first word on a line | 103 | // the 'keyword' is defined as the first word on a line |
104 | // the 'value' is everything after the keyword on the same line | 104 | // the 'value' is everything after the keyword on the same line |
105 | // starting at the first non-whitespace and ending right before the newline | 105 | // starting at the first non-whitespace and ending right before the newline |
106 | void get_keyword_and_value(std::string& keyword, | 106 | LL_COMMON_API void get_keyword_and_value(std::string& keyword, |
107 | std::string& value, | 107 | std::string& value, |
108 | const std::string& line); | 108 | const std::string& line); |
109 | 109 | ||
@@ -111,13 +111,13 @@ void get_keyword_and_value(std::string& keyword, | |||
111 | // read anymore or until we hit the count. Some istream | 111 | // read anymore or until we hit the count. Some istream |
112 | // implimentations have a max that they will read. | 112 | // implimentations have a max that they will read. |
113 | // Returns the number of bytes read. | 113 | // Returns the number of bytes read. |
114 | std::streamsize fullread( | 114 | LL_COMMON_API std::streamsize fullread( |
115 | std::istream& istr, | 115 | std::istream& istr, |
116 | char* buf, | 116 | char* buf, |
117 | std::streamsize requested); | 117 | std::streamsize requested); |
118 | 118 | ||
119 | 119 | ||
120 | std::istream& operator>>(std::istream& str, const char *tocheck); | 120 | LL_COMMON_API std::istream& operator>>(std::istream& str, const char *tocheck); |
121 | 121 | ||
122 | #endif | 122 | #endif |
123 | 123 | ||
diff --git a/linden/indra/llcommon/llstring.cpp b/linden/indra/llcommon/llstring.cpp index 1f653c1..cd5a9f2 100644 --- a/linden/indra/llcommon/llstring.cpp +++ b/linden/indra/llcommon/llstring.cpp | |||
@@ -50,7 +50,8 @@ std::string ll_safe_string(const char* in) | |||
50 | 50 | ||
51 | std::string ll_safe_string(const char* in, S32 maxlen) | 51 | std::string ll_safe_string(const char* in, S32 maxlen) |
52 | { | 52 | { |
53 | if(in) return std::string(in, maxlen); | 53 | //KOKUA FIXME: Which wormhole all the antistrings (strings with negative length) come from ? |
54 | if(in && maxlen > 0) return std::string(in, maxlen); | ||
54 | return std::string(); | 55 | return std::string(); |
55 | } | 56 | } |
56 | 57 | ||
@@ -595,6 +596,40 @@ std::string utf8str_removeCRLF(const std::string& utf8str) | |||
595 | return out; | 596 | return out; |
596 | } | 597 | } |
597 | 598 | ||
599 | bool is_hex_string(U8* str, S32 len) | ||
600 | { | ||
601 | bool rv = true; | ||
602 | U8* c = str; | ||
603 | while(rv && len--) | ||
604 | { | ||
605 | switch(*c) | ||
606 | { | ||
607 | case '0': | ||
608 | case '1': | ||
609 | case '2': | ||
610 | case '3': | ||
611 | case '4': | ||
612 | case '5': | ||
613 | case '6': | ||
614 | case '7': | ||
615 | case '8': | ||
616 | case '9': | ||
617 | case 'a': | ||
618 | case 'b': | ||
619 | case 'c': | ||
620 | case 'd': | ||
621 | case 'e': | ||
622 | case 'f': | ||
623 | ++c; | ||
624 | break; | ||
625 | default: | ||
626 | rv = false; | ||
627 | break; | ||
628 | } | ||
629 | } | ||
630 | return rv; | ||
631 | } | ||
632 | |||
598 | #if LL_WINDOWS | 633 | #if LL_WINDOWS |
599 | // documentation moved to header. Phoenix 2007-11-27 | 634 | // documentation moved to header. Phoenix 2007-11-27 |
600 | namespace snprintf_hack | 635 | namespace snprintf_hack |
diff --git a/linden/indra/llcommon/llstring.h b/linden/indra/llcommon/llstring.h index 7db62bc..a592e2c 100644 --- a/linden/indra/llcommon/llstring.h +++ b/linden/indra/llcommon/llstring.h | |||
@@ -34,12 +34,14 @@ | |||
34 | #define LL_LLSTRING_H | 34 | #define LL_LLSTRING_H |
35 | 35 | ||
36 | #include <string> | 36 | #include <string> |
37 | #include <cstdio> | ||
38 | #include <algorithm> | ||
39 | #include <map> | ||
37 | 40 | ||
38 | #if LL_LINUX || LL_SOLARIS | 41 | #if LL_LINUX || LL_SOLARIS |
39 | #include <wctype.h> | 42 | #include <wctype.h> |
40 | #include <wchar.h> | 43 | #include <wchar.h> |
41 | #endif | 44 | #endif |
42 | #include "linden_common.h" | ||
43 | 45 | ||
44 | #include <string.h> | 46 | #include <string.h> |
45 | 47 | ||
@@ -144,7 +146,7 @@ struct char_traits<U16> | |||
144 | }; | 146 | }; |
145 | #endif | 147 | #endif |
146 | 148 | ||
147 | class LLStringOps | 149 | class LL_COMMON_API LLStringOps |
148 | { | 150 | { |
149 | public: | 151 | public: |
150 | static char toUpper(char elem) { return toupper((unsigned char)elem); } | 152 | static char toUpper(char elem) { return toupper((unsigned char)elem); } |
@@ -179,8 +181,8 @@ public: | |||
179 | * @brief Return a string constructed from in without crashing if the | 181 | * @brief Return a string constructed from in without crashing if the |
180 | * pointer is NULL. | 182 | * pointer is NULL. |
181 | */ | 183 | */ |
182 | std::string ll_safe_string(const char* in); | 184 | std::string LL_COMMON_API ll_safe_string(const char* in); |
183 | std::string ll_safe_string(const char* in, S32 maxlen); | 185 | std::string LL_COMMON_API ll_safe_string(const char* in, S32 maxlen); |
184 | 186 | ||
185 | 187 | ||
186 | // Allowing assignments from non-strings into format_map_t is apparently | 188 | // Allowing assignments from non-strings into format_map_t is apparently |
@@ -209,7 +211,7 @@ public: | |||
209 | ///////////////////////////////////////////////////////////////////////////////////////// | 211 | ///////////////////////////////////////////////////////////////////////////////////////// |
210 | // Static Utility functions that operate on std::strings | 212 | // Static Utility functions that operate on std::strings |
211 | 213 | ||
212 | static std::basic_string<T> null; | 214 | static std::basic_string<T> const null; |
213 | 215 | ||
214 | typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; | 216 | typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t; |
215 | static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); | 217 | static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map); |
@@ -236,7 +238,8 @@ public: | |||
236 | static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab ); | 238 | static void replaceTabsWithSpaces( std::basic_string<T>& string, size_type spaces_per_tab ); |
237 | static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement ); | 239 | static void replaceNonstandardASCII( std::basic_string<T>& string, T replacement ); |
238 | static void replaceChar( std::basic_string<T>& string, T target, T replacement ); | 240 | static void replaceChar( std::basic_string<T>& string, T target, T replacement ); |
239 | 241 | static void replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement ); | |
242 | |||
240 | static BOOL containsNonprintable(const std::basic_string<T>& string); | 243 | static BOOL containsNonprintable(const std::basic_string<T>& string); |
241 | static void stripNonprintable(std::basic_string<T>& string); | 244 | static void stripNonprintable(std::basic_string<T>& string); |
242 | 245 | ||
@@ -299,7 +302,7 @@ public: | |||
299 | 302 | ||
300 | }; | 303 | }; |
301 | 304 | ||
302 | template<class T> std::basic_string<T> LLStringUtilBase<T>::null; | 305 | template<class T> std::basic_string<T> const LLStringUtilBase<T>::null; |
303 | 306 | ||
304 | typedef LLStringUtilBase<char> LLStringUtil; | 307 | typedef LLStringUtilBase<char> LLStringUtil; |
305 | typedef LLStringUtilBase<llwchar> LLWStringUtil; | 308 | typedef LLStringUtilBase<llwchar> LLWStringUtil; |
@@ -349,7 +352,7 @@ inline std::string chop_tail_copy( | |||
349 | * @brief This translates a nybble stored as a hex value from 0-f back | 352 | * @brief This translates a nybble stored as a hex value from 0-f back |
350 | * to a nybble in the low order bits of the return byte. | 353 | * to a nybble in the low order bits of the return byte. |
351 | */ | 354 | */ |
352 | U8 hex_as_nybble(char hex); | 355 | LL_COMMON_API U8 hex_as_nybble(char hex); |
353 | 356 | ||
354 | /** | 357 | /** |
355 | * @brief read the contents of a file into a string. | 358 | * @brief read the contents of a file into a string. |
@@ -360,7 +363,7 @@ U8 hex_as_nybble(char hex); | |||
360 | * @param filename The full name of the file to read. | 363 | * @param filename The full name of the file to read. |
361 | * @return Returns true on success. If false, str is unmodified. | 364 | * @return Returns true on success. If false, str is unmodified. |
362 | */ | 365 | */ |
363 | bool _read_file_into_string(std::string& str, const std::string& filename); | 366 | LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename); |
364 | 367 | ||
365 | /** | 368 | /** |
366 | * Unicode support | 369 | * Unicode support |
@@ -369,52 +372,52 @@ bool _read_file_into_string(std::string& str, const std::string& filename); | |||
369 | // Make the incoming string a utf8 string. Replaces any unknown glyph | 372 | // Make the incoming string a utf8 string. Replaces any unknown glyph |
370 | // with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest | 373 | // with the UNKOWN_CHARACTER. Once any unknown glph is found, the rest |
371 | // of the data may not be recovered. | 374 | // of the data may not be recovered. |
372 | std::string rawstr_to_utf8(const std::string& raw); | 375 | LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw); |
373 | 376 | ||
374 | // | 377 | // |
375 | // We should never use UTF16 except when communicating with Win32! | 378 | // We should never use UTF16 except when communicating with Win32! |
376 | // | 379 | // |
377 | typedef std::basic_string<U16> llutf16string; | 380 | typedef std::basic_string<U16> llutf16string; |
378 | 381 | ||
379 | LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); | 382 | LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len); |
380 | LLWString utf16str_to_wstring(const llutf16string &utf16str); | 383 | LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str); |
381 | 384 | ||
382 | llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); | 385 | LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len); |
383 | llutf16string wstring_to_utf16str(const LLWString &utf32str); | 386 | LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str); |
384 | 387 | ||
385 | llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); | 388 | LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len); |
386 | llutf16string utf8str_to_utf16str ( const std::string& utf8str ); | 389 | LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str ); |
387 | 390 | ||
388 | LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); | 391 | LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len); |
389 | LLWString utf8str_to_wstring(const std::string &utf8str); | 392 | LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str); |
390 | // Same function, better name. JC | 393 | // Same function, better name. JC |
391 | inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } | 394 | inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } |
392 | 395 | ||
393 | // | 396 | // |
394 | S32 wchar_to_utf8chars(llwchar inchar, char* outchars); | 397 | LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); |
395 | 398 | ||
396 | std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); | 399 | LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len); |
397 | std::string wstring_to_utf8str(const LLWString &utf32str); | 400 | LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str); |
398 | 401 | ||
399 | std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); | 402 | LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len); |
400 | std::string utf16str_to_utf8str(const llutf16string &utf16str); | 403 | LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str); |
401 | 404 | ||
402 | // Length of this UTF32 string in bytes when transformed to UTF8 | 405 | // Length of this UTF32 string in bytes when transformed to UTF8 |
403 | S32 wstring_utf8_length(const LLWString& wstr); | 406 | LL_COMMON_API S32 wstring_utf8_length(const LLWString& wstr); |
404 | 407 | ||
405 | // Length in bytes of this wide char in a UTF8 string | 408 | // Length in bytes of this wide char in a UTF8 string |
406 | S32 wchar_utf8_length(const llwchar wc); | 409 | LL_COMMON_API S32 wchar_utf8_length(const llwchar wc); |
407 | 410 | ||
408 | std::string utf8str_tolower(const std::string& utf8str); | 411 | LL_COMMON_API std::string utf8str_tolower(const std::string& utf8str); |
409 | 412 | ||
410 | // Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string. | 413 | // Length in llwchar (UTF-32) of the first len units (16 bits) of the given UTF-16 string. |
411 | S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len); | 414 | LL_COMMON_API S32 utf16str_wstring_length(const llutf16string &utf16str, S32 len); |
412 | 415 | ||
413 | // Length in utf16string (UTF-16) of wlen wchars beginning at woffset. | 416 | // Length in utf16string (UTF-16) of wlen wchars beginning at woffset. |
414 | S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen); | 417 | LL_COMMON_API S32 wstring_utf16_length(const LLWString & wstr, S32 woffset, S32 wlen); |
415 | 418 | ||
416 | // Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.) | 419 | // Length in wstring (i.e., llwchar count) of a part of a wstring specified by utf16 length (i.e., utf16 units.) |
417 | S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL); | 420 | LL_COMMON_API S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset, S32 utf16_length, BOOL *unaligned = NULL); |
418 | 421 | ||
419 | /** | 422 | /** |
420 | * @brief Properly truncate a utf8 string to a maximum byte count. | 423 | * @brief Properly truncate a utf8 string to a maximum byte count. |
@@ -426,11 +429,11 @@ S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, S32 woffset | |||
426 | * @param max_len The maximum number of bytes in the return value. | 429 | * @param max_len The maximum number of bytes in the return value. |
427 | * @return Returns a valid utf8 string with byte count <= max_len. | 430 | * @return Returns a valid utf8 string with byte count <= max_len. |
428 | */ | 431 | */ |
429 | std::string utf8str_truncate(const std::string& utf8str, const S32 max_len); | 432 | LL_COMMON_API std::string utf8str_truncate(const std::string& utf8str, const S32 max_len); |
430 | 433 | ||
431 | std::string utf8str_trim(const std::string& utf8str); | 434 | LL_COMMON_API std::string utf8str_trim(const std::string& utf8str); |
432 | 435 | ||
433 | S32 utf8str_compare_insensitive( | 436 | LL_COMMON_API S32 utf8str_compare_insensitive( |
434 | const std::string& lhs, | 437 | const std::string& lhs, |
435 | const std::string& rhs); | 438 | const std::string& rhs); |
436 | 439 | ||
@@ -441,17 +444,19 @@ S32 utf8str_compare_insensitive( | |||
441 | * @param target_char The wchar to be replaced | 444 | * @param target_char The wchar to be replaced |
442 | * @param replace_char The wchar which is written on replace | 445 | * @param replace_char The wchar which is written on replace |
443 | */ | 446 | */ |
444 | std::string utf8str_substChar( | 447 | LL_COMMON_API std::string utf8str_substChar( |
445 | const std::string& utf8str, | 448 | const std::string& utf8str, |
446 | const llwchar target_char, | 449 | const llwchar target_char, |
447 | const llwchar replace_char); | 450 | const llwchar replace_char); |
448 | 451 | ||
449 | std::string utf8str_makeASCII(const std::string& utf8str); | 452 | LL_COMMON_API std::string utf8str_makeASCII(const std::string& utf8str); |
450 | 453 | ||
451 | // Hack - used for evil notecards. | 454 | // Hack - used for evil notecards. |
452 | std::string mbcsstring_makeASCII(const std::string& str); | 455 | LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str); |
453 | 456 | ||
454 | std::string utf8str_removeCRLF(const std::string& utf8str); | 457 | LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str); |
458 | |||
459 | LL_COMMON_API bool is_hex_string(U8* str, S32 len); | ||
455 | 460 | ||
456 | 461 | ||
457 | #if LL_WINDOWS | 462 | #if LL_WINDOWS |
@@ -476,14 +481,21 @@ std::string utf8str_removeCRLF(const std::string& utf8str); | |||
476 | * formatted string. | 481 | * formatted string. |
477 | * | 482 | * |
478 | */ | 483 | */ |
479 | int safe_snprintf(char* str, size_t size, const char* format, ...); | 484 | |
485 | // Deal with the differeneces on Windows | ||
486 | namespace snprintf_hack | ||
487 | { | ||
488 | LL_COMMON_API int snprintf(char *str, size_t size, const char *format, ...); | ||
489 | } | ||
490 | |||
491 | using snprintf_hack::snprintf; | ||
480 | 492 | ||
481 | /** | 493 | /** |
482 | * @brief Convert a wide string to std::string | 494 | * @brief Convert a wide string to std::string |
483 | * | 495 | * |
484 | * This replaces the unsafe W2A macro from ATL. | 496 | * This replaces the unsafe W2A macro from ATL. |
485 | */ | 497 | */ |
486 | std::string ll_convert_wide_to_string(const wchar_t* in); | 498 | LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); |
487 | 499 | ||
488 | //@} | 500 | //@} |
489 | #endif // LL_WINDOWS | 501 | #endif // LL_WINDOWS |
@@ -506,7 +518,7 @@ namespace LLStringFn | |||
506 | * with zero non-printable characters. | 518 | * with zero non-printable characters. |
507 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. | 519 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. |
508 | */ | 520 | */ |
509 | void replace_nonprintable_in_ascii( | 521 | LL_COMMON_API void replace_nonprintable_in_ascii( |
510 | std::basic_string<char>& string, | 522 | std::basic_string<char>& string, |
511 | char replacement); | 523 | char replacement); |
512 | 524 | ||
@@ -520,7 +532,7 @@ namespace LLStringFn | |||
520 | * with zero non-printable characters and zero pipe characters. | 532 | * with zero non-printable characters and zero pipe characters. |
521 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. | 533 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. |
522 | */ | 534 | */ |
523 | void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str, | 535 | LL_COMMON_API void replace_nonprintable_and_pipe_in_ascii(std::basic_string<char>& str, |
524 | char replacement); | 536 | char replacement); |
525 | 537 | ||
526 | 538 | ||
@@ -529,7 +541,7 @@ namespace LLStringFn | |||
529 | * Returns a copy of the string with those characters removed. | 541 | * Returns a copy of the string with those characters removed. |
530 | * Works with US ASCII and UTF-8 encoded strings. JC | 542 | * Works with US ASCII and UTF-8 encoded strings. JC |
531 | */ | 543 | */ |
532 | std::string strip_invalid_xml(const std::string& input); | 544 | LL_COMMON_API std::string strip_invalid_xml(const std::string& input); |
533 | 545 | ||
534 | 546 | ||
535 | /** | 547 | /** |
@@ -540,7 +552,7 @@ namespace LLStringFn | |||
540 | * with zero non-printable characters. | 552 | * with zero non-printable characters. |
541 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. | 553 | * @param The replacement character. use LL_UNKNOWN_CHAR if unsure. |
542 | */ | 554 | */ |
543 | void replace_ascii_controlchars( | 555 | LL_COMMON_API void replace_ascii_controlchars( |
544 | std::basic_string<char>& string, | 556 | std::basic_string<char>& string, |
545 | char replacement); | 557 | char replacement); |
546 | } | 558 | } |
@@ -870,6 +882,7 @@ void LLStringUtilBase<T>::addCRLF(std::basic_string<T>& string) | |||
870 | } | 882 | } |
871 | 883 | ||
872 | string.assign(t, size); | 884 | string.assign(t, size); |
885 | delete[] t; | ||
873 | } | 886 | } |
874 | } | 887 | } |
875 | 888 | ||
@@ -900,11 +913,22 @@ template<class T> | |||
900 | void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement ) | 913 | void LLStringUtilBase<T>::replaceChar( std::basic_string<T>& string, T target, T replacement ) |
901 | { | 914 | { |
902 | size_type found_pos = 0; | 915 | size_type found_pos = 0; |
903 | for (found_pos = string.find(target, found_pos); | 916 | while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos ) |
904 | found_pos != std::basic_string<T>::npos; | ||
905 | found_pos = string.find(target, found_pos)) | ||
906 | { | 917 | { |
907 | string[found_pos] = replacement; | 918 | string[found_pos] = replacement; |
919 | found_pos++; // avoid infinite defeat if target == replacement | ||
920 | } | ||
921 | } | ||
922 | |||
923 | //static | ||
924 | template<class T> | ||
925 | void LLStringUtilBase<T>::replaceString( std::basic_string<T>& string, std::basic_string<T> target, std::basic_string<T> replacement ) | ||
926 | { | ||
927 | size_type found_pos = 0; | ||
928 | while( (found_pos = string.find(target, found_pos)) != std::basic_string<T>::npos ) | ||
929 | { | ||
930 | string.replace( found_pos, target.length(), replacement ); | ||
931 | found_pos += replacement.length(); // avoid infinite defeat if replacement contains target | ||
908 | } | 932 | } |
909 | } | 933 | } |
910 | 934 | ||
diff --git a/linden/indra/llcommon/llstringtable.h b/linden/indra/llcommon/llstringtable.h index 4492063..b13b016 100644 --- a/linden/indra/llcommon/llstringtable.h +++ b/linden/indra/llcommon/llstringtable.h | |||
@@ -56,7 +56,7 @@ | |||
56 | 56 | ||
57 | const U32 MAX_STRINGS_LENGTH = 256; | 57 | const U32 MAX_STRINGS_LENGTH = 256; |
58 | 58 | ||
59 | class LLStringTableEntry | 59 | class LL_COMMON_API LLStringTableEntry |
60 | { | 60 | { |
61 | public: | 61 | public: |
62 | LLStringTableEntry(const char *str) | 62 | LLStringTableEntry(const char *str) |
@@ -81,7 +81,7 @@ public: | |||
81 | S32 mCount; | 81 | S32 mCount; |
82 | }; | 82 | }; |
83 | 83 | ||
84 | class LLStringTable | 84 | class LL_COMMON_API LLStringTable |
85 | { | 85 | { |
86 | public: | 86 | public: |
87 | LLStringTable(int tablesize); | 87 | LLStringTable(int tablesize); |
@@ -115,7 +115,7 @@ public: | |||
115 | #endif | 115 | #endif |
116 | }; | 116 | }; |
117 | 117 | ||
118 | extern LLStringTable gStringTable; | 118 | extern LL_COMMON_API LLStringTable gStringTable; |
119 | 119 | ||
120 | //============================================================================ | 120 | //============================================================================ |
121 | 121 | ||
@@ -125,7 +125,7 @@ extern LLStringTable gStringTable; | |||
125 | 125 | ||
126 | typedef const std::string* LLStdStringHandle; | 126 | typedef const std::string* LLStdStringHandle; |
127 | 127 | ||
128 | class LLStdStringTable | 128 | class LL_COMMON_API LLStdStringTable |
129 | { | 129 | { |
130 | public: | 130 | public: |
131 | LLStdStringTable(S32 tablesize = 0) | 131 | LLStdStringTable(S32 tablesize = 0) |
diff --git a/linden/indra/llcommon/llsys.cpp b/linden/indra/llcommon/llsys.cpp index a56ac47..95dd2e5 100644 --- a/linden/indra/llcommon/llsys.cpp +++ b/linden/indra/llcommon/llsys.cpp | |||
@@ -76,6 +76,75 @@ extern int errno; | |||
76 | static const S32 CPUINFO_BUFFER_SIZE = 16383; | 76 | static const S32 CPUINFO_BUFFER_SIZE = 16383; |
77 | LLCPUInfo gSysCPU; | 77 | LLCPUInfo gSysCPU; |
78 | 78 | ||
79 | #if LL_WINDOWS | ||
80 | #ifndef DLLVERSIONINFO | ||
81 | typedef struct _DllVersionInfo | ||
82 | { | ||
83 | DWORD cbSize; | ||
84 | DWORD dwMajorVersion; | ||
85 | DWORD dwMinorVersion; | ||
86 | DWORD dwBuildNumber; | ||
87 | DWORD dwPlatformID; | ||
88 | }DLLVERSIONINFO; | ||
89 | #endif | ||
90 | |||
91 | #ifndef DLLGETVERSIONPROC | ||
92 | typedef int (FAR WINAPI *DLLGETVERSIONPROC) (DLLVERSIONINFO *); | ||
93 | #endif | ||
94 | |||
95 | bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number) | ||
96 | { | ||
97 | bool result = false; | ||
98 | const U32 BUFF_SIZE = 32767; | ||
99 | WCHAR tempBuf[BUFF_SIZE]; | ||
100 | if(GetSystemDirectory((LPWSTR)&tempBuf, BUFF_SIZE)) | ||
101 | { | ||
102 | |||
103 | std::basic_string<WCHAR> shell32_path(tempBuf); | ||
104 | |||
105 | // Shell32.dll contains the DLLGetVersion function. | ||
106 | // according to msdn its not part of the API | ||
107 | // so you have to go in and get it. | ||
108 | // http://msdn.microsoft.com/en-us/library/bb776404(VS.85).aspx | ||
109 | shell32_path += TEXT("\\shell32.dll"); | ||
110 | |||
111 | HMODULE hDllInst = LoadLibrary(shell32_path.c_str()); //load the DLL | ||
112 | if(hDllInst) | ||
113 | { // Could successfully load the DLL | ||
114 | DLLGETVERSIONPROC pDllGetVersion; | ||
115 | /* | ||
116 | You must get this function explicitly because earlier versions of the DLL | ||
117 | don't implement this function. That makes the lack of implementation of the | ||
118 | function a version marker in itself. | ||
119 | */ | ||
120 | pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hDllInst, | ||
121 | "DllGetVersion"); | ||
122 | |||
123 | if(pDllGetVersion) | ||
124 | { | ||
125 | // DLL supports version retrieval function | ||
126 | DLLVERSIONINFO dvi; | ||
127 | |||
128 | ZeroMemory(&dvi, sizeof(dvi)); | ||
129 | dvi.cbSize = sizeof(dvi); | ||
130 | HRESULT hr = (*pDllGetVersion)(&dvi); | ||
131 | |||
132 | if(SUCCEEDED(hr)) | ||
133 | { // Finally, the version is at our hands | ||
134 | major = dvi.dwMajorVersion; | ||
135 | minor = dvi.dwMinorVersion; | ||
136 | build_number = dvi.dwBuildNumber; | ||
137 | result = true; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | FreeLibrary(hDllInst); // Release DLL | ||
142 | } | ||
143 | } | ||
144 | return result; | ||
145 | } | ||
146 | #endif // LL_WINDOWS | ||
147 | |||
79 | LLOSInfo::LLOSInfo() : | 148 | LLOSInfo::LLOSInfo() : |
80 | mMajorVer(0), mMinorVer(0), mBuild(0) | 149 | mMajorVer(0), mMinorVer(0), mBuild(0) |
81 | { | 150 | { |
@@ -98,44 +167,74 @@ LLOSInfo::LLOSInfo() : | |||
98 | mMinorVer = osvi.dwMinorVersion; | 167 | mMinorVer = osvi.dwMinorVersion; |
99 | mBuild = osvi.dwBuildNumber; | 168 | mBuild = osvi.dwBuildNumber; |
100 | 169 | ||
170 | DWORD shell32_major, shell32_minor, shell32_build; | ||
171 | bool got_shell32_version = get_shell32_dll_version(shell32_major, | ||
172 | shell32_minor, | ||
173 | shell32_build); | ||
174 | |||
101 | switch(osvi.dwPlatformId) | 175 | switch(osvi.dwPlatformId) |
102 | { | 176 | { |
103 | case VER_PLATFORM_WIN32_NT: | 177 | case VER_PLATFORM_WIN32_NT: |
104 | { | 178 | { |
105 | // Test for the product. | 179 | // Test for the product. |
106 | if(osvi.dwMajorVersion <= 4) | 180 | if (osvi.dwMajorVersion <= 4) |
107 | { | 181 | { |
108 | mOSStringSimple = "Microsoft Windows NT "; | 182 | mOSStringSimple = "Microsoft Windows NT "; |
109 | } | 183 | } |
110 | else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) | 184 | else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) |
111 | { | 185 | { |
112 | mOSStringSimple = "Microsoft Windows 2000 "; | 186 | mOSStringSimple = "Microsoft Windows 2000 "; |
113 | } | 187 | } |
114 | else if(osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1) | 188 | else if (osvi.dwMajorVersion ==5 && osvi.dwMinorVersion == 1) |
115 | { | 189 | { |
116 | mOSStringSimple = "Microsoft Windows XP "; | 190 | mOSStringSimple = "Microsoft Windows XP "; |
117 | } | 191 | } |
118 | else if(osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) | 192 | else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) |
119 | { | 193 | { |
120 | if(osvi.wProductType == VER_NT_WORKSTATION) | 194 | if (osvi.wProductType == VER_NT_WORKSTATION) |
195 | { | ||
121 | mOSStringSimple = "Microsoft Windows XP x64 Edition "; | 196 | mOSStringSimple = "Microsoft Windows XP x64 Edition "; |
122 | else | 197 | } |
123 | mOSStringSimple = "Microsoft Windows Server 2003 "; | 198 | else |
199 | { | ||
200 | mOSStringSimple = "Microsoft Windows Server 2003 "; | ||
201 | } | ||
124 | } | 202 | } |
125 | else if(osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 1) | 203 | else if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 2) |
126 | { | 204 | { |
127 | if(osvi.dwMinorVersion == 0) | 205 | if (osvi.dwMinorVersion == 0) |
128 | { | 206 | { |
129 | mOSStringSimple = "Microsoft Windows Vista "; | 207 | if (osvi.wProductType == VER_NT_WORKSTATION) |
208 | { | ||
209 | mOSStringSimple = "Microsoft Windows Vista "; | ||
210 | } | ||
211 | else | ||
212 | { | ||
213 | mOSStringSimple = "Windows Server 2008 "; | ||
214 | } | ||
215 | |||
130 | } | 216 | } |
131 | else if(osvi.dwMinorVersion == 1) | 217 | else if (osvi.dwMinorVersion == 1) |
132 | { | 218 | { |
133 | mOSStringSimple = "Microsoft Windows 7 "; | 219 | if (osvi.wProductType == VER_NT_WORKSTATION) |
220 | { | ||
221 | mOSStringSimple = "Microsoft Windows 7 "; | ||
222 | } | ||
223 | else | ||
224 | { | ||
225 | mOSStringSimple = "Windows Server 2008 R2 "; | ||
226 | } | ||
134 | } | 227 | } |
135 | 228 | else if (osvi.dwMinorVersion == 2) | |
136 | if(osvi.wProductType != VER_NT_WORKSTATION) | ||
137 | { | 229 | { |
138 | mOSStringSimple += "Server "; | 230 | if (osvi.wProductType == VER_NT_WORKSTATION) |
231 | { | ||
232 | mOSStringSimple = "Microsoft Windows 8 "; | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | mOSStringSimple = "Windows Server 2012 "; | ||
237 | } | ||
139 | } | 238 | } |
140 | 239 | ||
141 | ///get native system info if available.. | 240 | ///get native system info if available.. |
@@ -146,8 +245,8 @@ LLOSInfo::LLOSInfo() : | |||
146 | pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function | 245 | pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); //load kernel32 get function |
147 | if(NULL != pGNSI) //check if it has failed | 246 | if(NULL != pGNSI) //check if it has failed |
148 | pGNSI(&si); //success | 247 | pGNSI(&si); //success |
149 | else | 248 | else |
150 | GetSystemInfo(&si); //if it fails get regular system info | 249 | GetSystemInfo(&si); //if it fails get regular system info |
151 | //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) | 250 | //(Warning: If GetSystemInfo it may result in incorrect information in a WOW64 machine, if the kernel fails to load) |
152 | 251 | ||
153 | //msdn microsoft finds 32 bit and 64 bit flavors this way.. | 252 | //msdn microsoft finds 32 bit and 64 bit flavors this way.. |
@@ -206,6 +305,7 @@ LLOSInfo::LLOSInfo() : | |||
206 | csdversion.c_str(), | 305 | csdversion.c_str(), |
207 | (osvi.dwBuildNumber & 0xffff)); | 306 | (osvi.dwBuildNumber & 0xffff)); |
208 | } | 307 | } |
308 | |||
209 | mOSString = mOSStringSimple + tmpstr; | 309 | mOSString = mOSStringSimple + tmpstr; |
210 | } | 310 | } |
211 | break; | 311 | break; |
@@ -235,6 +335,20 @@ LLOSInfo::LLOSInfo() : | |||
235 | mOSString = mOSStringSimple; | 335 | mOSString = mOSStringSimple; |
236 | break; | 336 | break; |
237 | } | 337 | } |
338 | |||
339 | std::string compatibility_mode; | ||
340 | if(got_shell32_version) | ||
341 | { | ||
342 | if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) | ||
343 | { | ||
344 | compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)", | ||
345 | shell32_major, | ||
346 | shell32_minor, | ||
347 | shell32_build); | ||
348 | } | ||
349 | } | ||
350 | mOSString += compatibility_mode; | ||
351 | |||
238 | #else | 352 | #else |
239 | struct utsname un; | 353 | struct utsname un; |
240 | if(uname(&un) != -1) | 354 | if(uname(&un) != -1) |
@@ -262,8 +376,8 @@ LLOSInfo::LLOSInfo() : | |||
262 | else if (ostype == "Linux") | 376 | else if (ostype == "Linux") |
263 | { | 377 | { |
264 | // Only care about major and minor Linux versions, truncate at second '.' | 378 | // Only care about major and minor Linux versions, truncate at second '.' |
265 | S32 idx1 = mOSStringSimple.find_first_of(".", 0); | 379 | std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0); |
266 | S32 idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos; | 380 | std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos; |
267 | std::string simple = mOSStringSimple.substr(0, idx2); | 381 | std::string simple = mOSStringSimple.substr(0, idx2); |
268 | if (simple.length() > 0) | 382 | if (simple.length() > 0) |
269 | mOSStringSimple = simple; | 383 | mOSStringSimple = simple; |
@@ -429,15 +543,15 @@ LLCPUInfo::LLCPUInfo() | |||
429 | mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions; | 543 | mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions; |
430 | mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions; | 544 | mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions; |
431 | mHasAltivec = info->_Ext.Altivec_Extensions; | 545 | mHasAltivec = info->_Ext.Altivec_Extensions; |
432 | mCPUMhz = (S32)(proc.GetCPUFrequency(50)/1000000.0); | 546 | mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0); |
433 | mFamily.assign( info->strFamily ); | 547 | mFamily.assign( info->strFamily ); |
434 | mCPUString = "Unknown"; | 548 | mCPUString = "Unknown"; |
435 | 549 | ||
436 | #if LL_WINDOWS || LL_DARWIN || LL_SOLARIS | 550 | #if LL_WINDOWS || LL_DARWIN || LL_SOLARIS |
437 | out << proc.strCPUName; | 551 | out << proc.strCPUName; |
438 | if (200 < mCPUMhz && mCPUMhz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check | 552 | if (200 < mCPUMHz && mCPUMHz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check |
439 | { | 553 | { |
440 | out << " (" << mCPUMhz << " MHz)"; | 554 | out << " (" << mCPUMHz << " MHz)"; |
441 | } | 555 | } |
442 | mCPUString = out.str(); | 556 | mCPUString = out.str(); |
443 | 557 | ||
@@ -482,7 +596,7 @@ LLCPUInfo::LLCPUInfo() | |||
482 | if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) | 596 | if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) |
483 | && 200.0 < mhz && mhz < 10000.0) | 597 | && 200.0 < mhz && mhz < 10000.0) |
484 | { | 598 | { |
485 | mCPUMhz = (S32)llrint(mhz); | 599 | mCPUMHz = (F64)llrint(mhz); |
486 | } | 600 | } |
487 | if (!cpuinfo["model name"].empty()) | 601 | if (!cpuinfo["model name"].empty()) |
488 | mCPUString = cpuinfo["model name"]; | 602 | mCPUString = cpuinfo["model name"]; |
@@ -505,9 +619,9 @@ bool LLCPUInfo::hasSSE2() const | |||
505 | return mHasSSE2; | 619 | return mHasSSE2; |
506 | } | 620 | } |
507 | 621 | ||
508 | S32 LLCPUInfo::getMhz() const | 622 | F64 LLCPUInfo::getMHz() const |
509 | { | 623 | { |
510 | return mCPUMhz; | 624 | return mCPUMHz; |
511 | } | 625 | } |
512 | 626 | ||
513 | std::string LLCPUInfo::getCPUString() const | 627 | std::string LLCPUInfo::getCPUString() const |
@@ -554,7 +668,7 @@ void LLCPUInfo::stream(std::ostream& s) const | |||
554 | s << "->mHasSSE: " << (U32)mHasSSE << std::endl; | 668 | s << "->mHasSSE: " << (U32)mHasSSE << std::endl; |
555 | s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl; | 669 | s << "->mHasSSE2: " << (U32)mHasSSE2 << std::endl; |
556 | s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl; | 670 | s << "->mHasAltivec: " << (U32)mHasAltivec << std::endl; |
557 | s << "->mCPUMhz: " << mCPUMhz << std::endl; | 671 | s << "->mCPUMHz: " << mCPUMHz << std::endl; |
558 | s << "->mCPUString: " << mCPUString << std::endl; | 672 | s << "->mCPUString: " << mCPUString << std::endl; |
559 | } | 673 | } |
560 | 674 | ||
@@ -631,6 +745,26 @@ U32 LLMemoryInfo::getPhysicalMemoryClamped() const | |||
631 | } | 745 | } |
632 | } | 746 | } |
633 | 747 | ||
748 | //static | ||
749 | void LLMemoryInfo::getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb) | ||
750 | { | ||
751 | #if LL_WINDOWS | ||
752 | MEMORYSTATUSEX state; | ||
753 | state.dwLength = sizeof(state); | ||
754 | GlobalMemoryStatusEx(&state); | ||
755 | |||
756 | avail_physical_mem_kb = (U32)(state.ullAvailPhys/1024) ; | ||
757 | avail_virtual_mem_kb = (U32)(state.ullAvailVirtual/1024) ; | ||
758 | |||
759 | #else | ||
760 | //do not know how to collect available memory info for other systems. | ||
761 | //leave it blank here for now. | ||
762 | |||
763 | avail_physical_mem_kb = -1 ; | ||
764 | avail_virtual_mem_kb = -1 ; | ||
765 | #endif | ||
766 | } | ||
767 | |||
634 | void LLMemoryInfo::stream(std::ostream& s) const | 768 | void LLMemoryInfo::stream(std::ostream& s) const |
635 | { | 769 | { |
636 | #if LL_WINDOWS | 770 | #if LL_WINDOWS |
diff --git a/linden/indra/llcommon/llsys.h b/linden/indra/llcommon/llsys.h index 03f48ca..e481c88 100644 --- a/linden/indra/llcommon/llsys.h +++ b/linden/indra/llcommon/llsys.h | |||
@@ -45,7 +45,7 @@ | |||
45 | #include <iosfwd> | 45 | #include <iosfwd> |
46 | #include <string> | 46 | #include <string> |
47 | 47 | ||
48 | class LLOSInfo | 48 | class LL_COMMON_API LLOSInfo |
49 | { | 49 | { |
50 | public: | 50 | public: |
51 | LLOSInfo(); | 51 | LLOSInfo(); |
@@ -70,7 +70,7 @@ private: | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | 72 | ||
73 | class LLCPUInfo | 73 | class LL_COMMON_API LLCPUInfo |
74 | { | 74 | { |
75 | public: | 75 | public: |
76 | LLCPUInfo(); | 76 | LLCPUInfo(); |
@@ -81,7 +81,7 @@ public: | |||
81 | bool hasAltivec() const; | 81 | bool hasAltivec() const; |
82 | bool hasSSE() const; | 82 | bool hasSSE() const; |
83 | bool hasSSE2() const; | 83 | bool hasSSE2() const; |
84 | S32 getMhz() const; | 84 | F64 getMHz() const; |
85 | 85 | ||
86 | // Family is "AMD Duron" or "Intel Pentium Pro" | 86 | // Family is "AMD Duron" or "Intel Pentium Pro" |
87 | const std::string& getFamily() const { return mFamily; } | 87 | const std::string& getFamily() const { return mFamily; } |
@@ -90,7 +90,7 @@ private: | |||
90 | bool mHasSSE; | 90 | bool mHasSSE; |
91 | bool mHasSSE2; | 91 | bool mHasSSE2; |
92 | bool mHasAltivec; | 92 | bool mHasAltivec; |
93 | S32 mCPUMhz; | 93 | F64 mCPUMHz; |
94 | std::string mFamily; | 94 | std::string mFamily; |
95 | std::string mCPUString; | 95 | std::string mCPUString; |
96 | }; | 96 | }; |
@@ -99,7 +99,7 @@ private: | |||
99 | // | 99 | // |
100 | // CLASS LLMemoryInfo | 100 | // CLASS LLMemoryInfo |
101 | 101 | ||
102 | class LLMemoryInfo | 102 | class LL_COMMON_API LLMemoryInfo |
103 | 103 | ||
104 | /*! @brief Class to query the memory subsystem | 104 | /*! @brief Class to query the memory subsystem |
105 | 105 | ||
@@ -120,18 +120,21 @@ public: | |||
120 | ** be returned. | 120 | ** be returned. |
121 | */ | 121 | */ |
122 | U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes | 122 | U32 getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes |
123 | |||
124 | //get the available memory infomation in KiloBytes. | ||
125 | static void getAvailableMemoryKB(U32& avail_physical_mem_kb, U32& avail_virtual_mem_kb); | ||
123 | }; | 126 | }; |
124 | 127 | ||
125 | 128 | ||
126 | std::ostream& operator<<(std::ostream& s, const LLOSInfo& info); | 129 | LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLOSInfo& info); |
127 | std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); | 130 | LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info); |
128 | std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); | 131 | LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info); |
129 | 132 | ||
130 | // gunzip srcfile into dstfile. Returns FALSE on error. | 133 | // gunzip srcfile into dstfile. Returns FALSE on error. |
131 | BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); | 134 | LL_COMMON_API BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile); |
132 | // gzip srcfile into dstfile. Returns FALSE on error. | 135 | // gzip srcfile into dstfile. Returns FALSE on error. |
133 | BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); | 136 | LL_COMMON_API BOOL gzip_file(const std::string& srcfile, const std::string& dstfile); |
134 | 137 | ||
135 | extern LLCPUInfo gSysCPU; | 138 | LL_COMMON_API extern LLCPUInfo gSysCPU; |
136 | 139 | ||
137 | #endif // LL_LLSYS_H | 140 | #endif // LL_LLSYS_H |
diff --git a/linden/indra/llcommon/llthread.cpp b/linden/indra/llcommon/llthread.cpp index 692d6c4..f7732cb 100644 --- a/linden/indra/llcommon/llthread.cpp +++ b/linden/indra/llcommon/llthread.cpp | |||
@@ -72,8 +72,8 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap | |||
72 | // Set thread state to running | 72 | // Set thread state to running |
73 | threadp->mStatus = RUNNING; | 73 | threadp->mStatus = RUNNING; |
74 | 74 | ||
75 | // Create a thread local APRFile pool. | 75 | // Create a thread local data. |
76 | LLVolatileAPRPool::createLocalAPRFilePool(); | 76 | AIThreadLocalData::create(threadp); |
77 | 77 | ||
78 | // Run the user supplied function | 78 | // Run the user supplied function |
79 | threadp->run(); | 79 | threadp->run(); |
@@ -87,24 +87,14 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap | |||
87 | } | 87 | } |
88 | 88 | ||
89 | 89 | ||
90 | LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : | 90 | LLThread::LLThread(std::string const& name) : |
91 | mPaused(false), | 91 | mPaused(false), |
92 | mName(name), | 92 | mName(name), |
93 | mAPRThreadp(NULL), | 93 | mAPRThreadp(NULL), |
94 | mStatus(STOPPED) | 94 | mStatus(STOPPED), |
95 | mThreadLocalData(NULL) | ||
95 | { | 96 | { |
96 | // Thread creation probably CAN be paranoid about APR being initialized, if necessary | 97 | mRunCondition = new LLCondition; |
97 | if (poolp) | ||
98 | { | ||
99 | mIsLocalPool = false; | ||
100 | mAPRPoolp = poolp; | ||
101 | } | ||
102 | else | ||
103 | { | ||
104 | mIsLocalPool = true; | ||
105 | apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread | ||
106 | } | ||
107 | mRunCondition = new LLCondition(mAPRPoolp); | ||
108 | } | 98 | } |
109 | 99 | ||
110 | 100 | ||
@@ -147,24 +137,18 @@ void LLThread::shutdown() | |||
147 | if (!isStopped()) | 137 | if (!isStopped()) |
148 | { | 138 | { |
149 | // This thread just wouldn't stop, even though we gave it time | 139 | // This thread just wouldn't stop, even though we gave it time |
150 | llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl; | 140 | llwarns << "LLThread::shutdown() exiting thread before clean exit!" << llendl; |
151 | return; | 141 | return; |
152 | } | 142 | } |
153 | mAPRThreadp = NULL; | 143 | mAPRThreadp = NULL; |
154 | } | 144 | } |
155 | 145 | ||
156 | delete mRunCondition; | 146 | delete mRunCondition; |
157 | |||
158 | if (mIsLocalPool) | ||
159 | { | ||
160 | apr_pool_destroy(mAPRPoolp); | ||
161 | } | ||
162 | } | 147 | } |
163 | 148 | ||
164 | |||
165 | void LLThread::start() | 149 | void LLThread::start() |
166 | { | 150 | { |
167 | apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp); | 151 | apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, tldata().mRootPool()); |
168 | 152 | ||
169 | // We won't bother joining | 153 | // We won't bother joining |
170 | apr_thread_detach(mAPRThreadp); | 154 | apr_thread_detach(mAPRThreadp); |
@@ -265,38 +249,72 @@ void LLThread::wakeLocked() | |||
265 | } | 249 | } |
266 | } | 250 | } |
267 | 251 | ||
268 | //============================================================================ | 252 | #ifdef SHOW_ASSERT |
253 | // This allows the use of llassert(is_main_thread()) to assure the current thread is the main thread. | ||
254 | static apr_os_thread_t main_thread_id; | ||
255 | bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); } | ||
256 | #endif | ||
269 | 257 | ||
270 | LLMutex::LLMutex(apr_pool_t *poolp) : | 258 | // The thread private handle to access the AIThreadLocalData instance. |
271 | mAPRMutexp(NULL) | 259 | apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey; |
260 | |||
261 | //static | ||
262 | void AIThreadLocalData::init(void) | ||
272 | { | 263 | { |
273 | //if (poolp) | 264 | // Only do this once. |
274 | //{ | 265 | if (sThreadLocalDataKey) |
275 | // mIsLocalPool = false; | ||
276 | // mAPRPoolp = poolp; | ||
277 | //} | ||
278 | //else | ||
279 | { | 266 | { |
280 | mIsLocalPool = true; | 267 | return; |
281 | apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread | ||
282 | } | 268 | } |
283 | apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp); | 269 | |
270 | apr_status_t status = apr_threadkey_private_create(&sThreadLocalDataKey, &AIThreadLocalData::destroy, AIAPRRootPool::get()()); | ||
271 | ll_apr_assert_status(status); // Or out of memory, or system-imposed limit on the | ||
272 | // total number of keys per process {PTHREAD_KEYS_MAX} | ||
273 | // has been exceeded. | ||
274 | |||
275 | // Create the thread-local data for the main thread (this function is called by the main thread). | ||
276 | AIThreadLocalData::create(NULL); | ||
277 | |||
278 | #ifdef SHOW_ASSERT | ||
279 | // This function is called by the main thread. | ||
280 | main_thread_id = apr_os_thread_current(); | ||
281 | #endif | ||
284 | } | 282 | } |
285 | 283 | ||
286 | LLMutex::~LLMutex() | 284 | // This is called once for every thread when the thread is destructed. |
285 | //static | ||
286 | void AIThreadLocalData::destroy(void* thread_local_data) | ||
287 | { | 287 | { |
288 | #if _DEBUG | 288 | delete reinterpret_cast<AIThreadLocalData*>(thread_local_data); |
289 | llassert(!isLocked()); // better not be locked! | 289 | } |
290 | #endif | 290 | |
291 | apr_thread_mutex_destroy(mAPRMutexp); | 291 | //static |
292 | mAPRMutexp = NULL; | 292 | void AIThreadLocalData::create(LLThread* threadp) |
293 | if (mIsLocalPool) | 293 | { |
294 | AIThreadLocalData* new_tld = new AIThreadLocalData; | ||
295 | if (threadp) | ||
294 | { | 296 | { |
295 | apr_pool_destroy(mAPRPoolp); | 297 | threadp->mThreadLocalData = new_tld; |
296 | } | 298 | } |
299 | apr_status_t status = apr_threadkey_private_set(new_tld, sThreadLocalDataKey); | ||
300 | llassert_always(status == APR_SUCCESS); | ||
297 | } | 301 | } |
298 | 302 | ||
299 | bool LLMutex::isLocked() | 303 | //static |
304 | AIThreadLocalData& AIThreadLocalData::tldata(void) | ||
305 | { | ||
306 | if (!sThreadLocalDataKey) | ||
307 | AIThreadLocalData::init(); | ||
308 | |||
309 | void* data; | ||
310 | apr_status_t status = apr_threadkey_private_get(&data, sThreadLocalDataKey); | ||
311 | llassert_always(status == APR_SUCCESS); | ||
312 | return *static_cast<AIThreadLocalData*>(data); | ||
313 | } | ||
314 | |||
315 | //============================================================================ | ||
316 | |||
317 | bool LLMutexBase::isLocked() | ||
300 | { | 318 | { |
301 | if (!tryLock()) | 319 | if (!tryLock()) |
302 | { | 320 | { |
@@ -308,12 +326,9 @@ bool LLMutex::isLocked() | |||
308 | 326 | ||
309 | //============================================================================ | 327 | //============================================================================ |
310 | 328 | ||
311 | LLCondition::LLCondition(apr_pool_t *poolp) : | 329 | LLCondition::LLCondition(AIAPRPool& parent) : LLMutex(parent) |
312 | LLMutex(poolp) | ||
313 | { | 330 | { |
314 | // base class (LLMutex) has already ensured that mAPRPoolp is set up. | 331 | apr_thread_cond_create(&mAPRCondp, mPool()); |
315 | |||
316 | apr_thread_cond_create(&mAPRCondp, mAPRPoolp); | ||
317 | } | 332 | } |
318 | 333 | ||
319 | LLCondition::~LLCondition() | 334 | LLCondition::~LLCondition() |
@@ -349,7 +364,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() | |||
349 | { | 364 | { |
350 | if (!sMutex) | 365 | if (!sMutex) |
351 | { | 366 | { |
352 | sMutex = new LLMutex(0); | 367 | sMutex = new LLMutex; |
353 | } | 368 | } |
354 | } | 369 | } |
355 | 370 | ||
diff --git a/linden/indra/llcommon/llthread.h b/linden/indra/llcommon/llthread.h index ed76a3b..1e982cc 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h | |||
@@ -38,12 +38,29 @@ | |||
38 | #include "llmemory.h" | 38 | #include "llmemory.h" |
39 | 39 | ||
40 | #include "apr_thread_cond.h" | 40 | #include "apr_thread_cond.h" |
41 | #include "aiaprpool.h" | ||
41 | 42 | ||
42 | class LLThread; | 43 | class LLThread; |
43 | class LLMutex; | 44 | class LLMutex; |
44 | class LLCondition; | 45 | class LLCondition; |
45 | 46 | ||
46 | class LLThread | 47 | class LL_COMMON_API AIThreadLocalData |
48 | { | ||
49 | private: | ||
50 | static apr_threadkey_t* sThreadLocalDataKey; | ||
51 | |||
52 | public: | ||
53 | // Thread-local memory pool. | ||
54 | AIAPRRootPool mRootPool; | ||
55 | AIVolatileAPRPool mVolatileAPRPool; | ||
56 | |||
57 | static void init(void); | ||
58 | static void destroy(void* thread_local_data); | ||
59 | static void create(LLThread* pthread); | ||
60 | static AIThreadLocalData& tldata(void); | ||
61 | }; | ||
62 | |||
63 | class LL_COMMON_API LLThread | ||
47 | { | 64 | { |
48 | public: | 65 | public: |
49 | typedef enum e_thread_status | 66 | typedef enum e_thread_status |
@@ -53,7 +70,7 @@ public: | |||
53 | QUITTING= 2 // Someone wants this thread to quit | 70 | QUITTING= 2 // Someone wants this thread to quit |
54 | } EThreadStatus; | 71 | } EThreadStatus; |
55 | 72 | ||
56 | LLThread(const std::string& name, apr_pool_t *poolp = NULL); | 73 | LLThread(std::string const& name); |
57 | virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. | 74 | virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state. |
58 | virtual void shutdown(); // stops the thread | 75 | virtual void shutdown(); // stops the thread |
59 | 76 | ||
@@ -82,7 +99,8 @@ public: | |||
82 | // this kicks off the apr thread | 99 | // this kicks off the apr thread |
83 | void start(void); | 100 | void start(void); |
84 | 101 | ||
85 | apr_pool_t *getAPRPool() { return mAPRPoolp; } | 102 | // Return thread-local data for the current thread. |
103 | static AIThreadLocalData& tldata(void) { return AIThreadLocalData::tldata(); } | ||
86 | 104 | ||
87 | private: | 105 | private: |
88 | bool mPaused; | 106 | bool mPaused; |
@@ -95,10 +113,11 @@ protected: | |||
95 | LLCondition* mRunCondition; | 113 | LLCondition* mRunCondition; |
96 | 114 | ||
97 | apr_thread_t *mAPRThreadp; | 115 | apr_thread_t *mAPRThreadp; |
98 | apr_pool_t *mAPRPoolp; | ||
99 | bool mIsLocalPool; | ||
100 | EThreadStatus mStatus; | 116 | EThreadStatus mStatus; |
101 | 117 | ||
118 | friend void AIThreadLocalData::create(LLThread* threadp); | ||
119 | AIThreadLocalData* mThreadLocalData; | ||
120 | |||
102 | void setQuitting(); | 121 | void setQuitting(); |
103 | 122 | ||
104 | // virtual function overridden by subclass -- this will be called when the thread runs | 123 | // virtual function overridden by subclass -- this will be called when the thread runs |
@@ -125,12 +144,9 @@ protected: | |||
125 | 144 | ||
126 | //============================================================================ | 145 | //============================================================================ |
127 | 146 | ||
128 | class LLMutex | 147 | class LL_COMMON_API LLMutexBase |
129 | { | 148 | { |
130 | public: | 149 | public: |
131 | LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex | ||
132 | ~LLMutex(); | ||
133 | |||
134 | void lock() { apr_thread_mutex_lock(mAPRMutexp); } | 150 | void lock() { apr_thread_mutex_lock(mAPRMutexp); } |
135 | void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } | 151 | void unlock() { apr_thread_mutex_unlock(mAPRMutexp); } |
136 | // Returns true if lock was obtained successfully. | 152 | // Returns true if lock was obtained successfully. |
@@ -139,16 +155,60 @@ public: | |||
139 | bool isLocked(); // non-blocking, but does do a lock/unlock so not free | 155 | bool isLocked(); // non-blocking, but does do a lock/unlock so not free |
140 | 156 | ||
141 | protected: | 157 | protected: |
142 | apr_thread_mutex_t *mAPRMutexp; | 158 | // mAPRMutexp is initialized and uninitialized in the derived class. |
143 | apr_pool_t *mAPRPoolp; | 159 | apr_thread_mutex_t* mAPRMutexp; |
144 | bool mIsLocalPool; | 160 | }; |
161 | |||
162 | class LL_COMMON_API LLMutex : public LLMutexBase | ||
163 | { | ||
164 | public: | ||
165 | LLMutex(AIAPRPool& parent = LLThread::tldata().mRootPool) : mPool(parent) | ||
166 | { | ||
167 | apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mPool()); | ||
168 | } | ||
169 | ~LLMutex() | ||
170 | { | ||
171 | llassert(!isLocked()); // better not be locked! | ||
172 | apr_thread_mutex_destroy(mAPRMutexp); | ||
173 | mAPRMutexp = NULL; | ||
174 | } | ||
175 | |||
176 | protected: | ||
177 | AIAPRPool mPool; | ||
145 | }; | 178 | }; |
146 | 179 | ||
180 | #if APR_HAS_THREADS | ||
181 | // No need to use a root pool in this case. | ||
182 | typedef LLMutex LLMutexRootPool; | ||
183 | #else // APR_HAS_THREADS | ||
184 | class LL_COMMON_API LLMutexRootPool : public LLMutexBase | ||
185 | { | ||
186 | public: | ||
187 | LLMutexRootPool(void) | ||
188 | { | ||
189 | apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mRootPool()); | ||
190 | } | ||
191 | ~LLMutexRootPool() | ||
192 | { | ||
193 | #if APR_POOL_DEBUG | ||
194 | // It is allowed to destruct root pools from a different thread. | ||
195 | mRootPool.grab_ownership(); | ||
196 | #endif | ||
197 | llassert(!isLocked()); // better not be locked! | ||
198 | apr_thread_mutex_destroy(mAPRMutexp); | ||
199 | mAPRMutexp = NULL; | ||
200 | } | ||
201 | |||
202 | protected: | ||
203 | AIAPRRootPool mRootPool; | ||
204 | }; | ||
205 | #endif // APR_HAS_THREADS | ||
206 | |||
147 | // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). | 207 | // Actually a condition/mutex pair (since each condition needs to be associated with a mutex). |
148 | class LLCondition : public LLMutex | 208 | class LL_COMMON_API LLCondition : public LLMutex |
149 | { | 209 | { |
150 | public: | 210 | public: |
151 | LLCondition(apr_pool_t *apr_poolp); // Defaults to global pool, could use the thread pool as well. | 211 | LLCondition(AIAPRPool& parent = LLThread::tldata().mRootPool); |
152 | ~LLCondition(); | 212 | ~LLCondition(); |
153 | 213 | ||
154 | void wait(); // blocks | 214 | void wait(); // blocks |
@@ -159,10 +219,10 @@ protected: | |||
159 | apr_thread_cond_t *mAPRCondp; | 219 | apr_thread_cond_t *mAPRCondp; |
160 | }; | 220 | }; |
161 | 221 | ||
162 | class LLMutexLock | 222 | class LL_COMMON_API LLMutexLock |
163 | { | 223 | { |
164 | public: | 224 | public: |
165 | LLMutexLock(LLMutex* mutex) | 225 | LLMutexLock(LLMutexBase* mutex) |
166 | { | 226 | { |
167 | mMutex = mutex; | 227 | mMutex = mutex; |
168 | mMutex->lock(); | 228 | mMutex->lock(); |
@@ -172,7 +232,102 @@ public: | |||
172 | mMutex->unlock(); | 232 | mMutex->unlock(); |
173 | } | 233 | } |
174 | private: | 234 | private: |
175 | LLMutex* mMutex; | 235 | LLMutexBase* mMutex; |
236 | }; | ||
237 | |||
238 | class AIRWLock | ||
239 | { | ||
240 | public: | ||
241 | AIRWLock(AIAPRPool& parent = LLThread::tldata().mRootPool) : | ||
242 | mWriterWaitingMutex(parent), mNoHoldersCondition(parent), mHoldersCount(0), mWriterIsWaiting(false) { } | ||
243 | |||
244 | private: | ||
245 | LLMutex mWriterWaitingMutex; //!< This mutex is locked while some writer is waiting for access. | ||
246 | LLCondition mNoHoldersCondition; //!< Access control for mHoldersCount. Condition true when there are no more holders. | ||
247 | int mHoldersCount; //!< Number of readers or -1 if a writer locked this object. | ||
248 | // This is volatile because we read it outside the critical area of mWriterWaitingMutex, at [1]. | ||
249 | // That means that other threads can change it while we are already in the (inlined) function rdlock. | ||
250 | // Without volatile, the following assembly would fail: | ||
251 | // register x = mWriterIsWaiting; | ||
252 | // /* some thread changes mWriterIsWaiting */ | ||
253 | // if (x ... | ||
254 | // However, because the function is fuzzy to begin with (we don't mind that this race | ||
255 | // condition exists) it would work fine without volatile. So, basically it's just here | ||
256 | // out of principle ;). -- Aleric | ||
257 | bool volatile mWriterIsWaiting; //!< True when there is a writer waiting for write access. | ||
258 | |||
259 | public: | ||
260 | void rdlock(bool high_priority = false) | ||
261 | { | ||
262 | // Give a writer a higher priority (kinda fuzzy). | ||
263 | if (mWriterIsWaiting && !high_priority) // [1] If there is a writer interested, | ||
264 | { | ||
265 | mWriterWaitingMutex.lock(); // [2] then give it precedence and wait here. | ||
266 | // If we get here then the writer got it's access; mHoldersCount == -1. | ||
267 | mWriterWaitingMutex.unlock(); | ||
268 | } | ||
269 | mNoHoldersCondition.lock(); // [3] Get exclusive access to mHoldersCount. | ||
270 | while (mHoldersCount == -1) // [4] | ||
271 | { | ||
272 | mNoHoldersCondition.wait(); // [5] Wait till mHoldersCount is (or just was) 0. | ||
273 | } | ||
274 | ++mHoldersCount; // One more reader. | ||
275 | mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. | ||
276 | } | ||
277 | void rdunlock(void) | ||
278 | { | ||
279 | mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. | ||
280 | if (--mHoldersCount == 0) // Was this the last reader? | ||
281 | { | ||
282 | mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7]. | ||
283 | } | ||
284 | mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. | ||
285 | } | ||
286 | void wrlock(void) | ||
287 | { | ||
288 | mWriterWaitingMutex.lock(); // Block new readers, see [2], | ||
289 | mWriterIsWaiting = true; // from this moment on, see [1]. | ||
290 | mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. | ||
291 | while (mHoldersCount != 0) // Other readers or writers have this lock? | ||
292 | { | ||
293 | mNoHoldersCondition.wait(); // [6] Wait till mHoldersCount is (or just was) 0. | ||
294 | } | ||
295 | mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1]. | ||
296 | mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3]. | ||
297 | mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]). | ||
298 | mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]). | ||
299 | } | ||
300 | void wrunlock(void) | ||
301 | { | ||
302 | mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. | ||
303 | mHoldersCount = 0; // We have no writer anymore. | ||
304 | mNoHoldersCondition.signal(); // Tell waiting threads, see [5], [6] and [7]. | ||
305 | mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. | ||
306 | } | ||
307 | void rd2wrlock(void) | ||
308 | { | ||
309 | mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. Blocks new readers at [3]. | ||
310 | if (--mHoldersCount > 0) // Any other reads left? | ||
311 | { | ||
312 | mWriterWaitingMutex.lock(); // Block new readers, see [2], | ||
313 | mWriterIsWaiting = true; // from this moment on, see [1]. | ||
314 | while (mHoldersCount != 0) // Other readers (still) have this lock? | ||
315 | { | ||
316 | mNoHoldersCondition.wait(); // [7] Wait till mHoldersCount is (or just was) 0. | ||
317 | } | ||
318 | mWriterIsWaiting = false; // Stop checking the lock for new readers, see [1]. | ||
319 | mWriterWaitingMutex.unlock(); // Release blocked readers, they will still hang at [3]. | ||
320 | } | ||
321 | mHoldersCount = -1; // We are a writer now (will cause a hang at [5], see [4]). | ||
322 | mNoHoldersCondition.unlock(); // Release lock on mHolders (readers go from [3] to [5]). | ||
323 | } | ||
324 | void wr2rdlock(void) | ||
325 | { | ||
326 | mNoHoldersCondition.lock(); // Get exclusive access to mHoldersCount. | ||
327 | mHoldersCount = 1; // Turn writer into a reader. | ||
328 | mNoHoldersCondition.signal(); // Tell waiting readers, see [5]. | ||
329 | mNoHoldersCondition.unlock(); // Release lock on mHoldersCount. | ||
330 | } | ||
176 | }; | 331 | }; |
177 | 332 | ||
178 | //============================================================================ | 333 | //============================================================================ |
@@ -187,12 +342,11 @@ void LLThread::unlockData() | |||
187 | mRunCondition->unlock(); | 342 | mRunCondition->unlock(); |
188 | } | 343 | } |
189 | 344 | ||
190 | |||
191 | //============================================================================ | 345 | //============================================================================ |
192 | 346 | ||
193 | // see llmemory.h for LLPointer<> definition | 347 | // see llmemory.h for LLPointer<> definition |
194 | 348 | ||
195 | class LLThreadSafeRefCount | 349 | class LL_COMMON_API LLThreadSafeRefCount |
196 | { | 350 | { |
197 | public: | 351 | public: |
198 | static void initThreadSafeRefCount(); // creates sMutex | 352 | static void initThreadSafeRefCount(); // creates sMutex |
@@ -244,7 +398,7 @@ private: | |||
244 | 398 | ||
245 | // Simple responder for self destructing callbacks | 399 | // Simple responder for self destructing callbacks |
246 | // Pure virtual class | 400 | // Pure virtual class |
247 | class LLResponder : public LLThreadSafeRefCount | 401 | class LL_COMMON_API LLResponder : public LLThreadSafeRefCount |
248 | { | 402 | { |
249 | protected: | 403 | protected: |
250 | virtual ~LLResponder(); | 404 | virtual ~LLResponder(); |
diff --git a/linden/indra/llcommon/lltimer.cpp b/linden/indra/llcommon/lltimer.cpp index fa6efaf..b825c1e 100644 --- a/linden/indra/llcommon/lltimer.cpp +++ b/linden/indra/llcommon/lltimer.cpp | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "linden_common.h" | 33 | #include "linden_common.h" |
34 | 34 | ||
35 | #include "lltimer.h" | 35 | #include "lltimer.h" |
36 | #include "timing.h" // totalTime prototype. | ||
36 | 37 | ||
37 | #include "u64.h" | 38 | #include "u64.h" |
38 | 39 | ||
@@ -51,9 +52,6 @@ | |||
51 | // | 52 | // |
52 | // Locally used constants | 53 | // Locally used constants |
53 | // | 54 | // |
54 | const U32 SEC_PER_DAY = 86400; | ||
55 | const F64 SEC_TO_MICROSEC = 1000000.f; | ||
56 | const U64 SEC_TO_MICROSEC_U64 = 1000000; | ||
57 | const F64 USEC_TO_SEC_F64 = 0.000001; | 55 | const F64 USEC_TO_SEC_F64 = 0.000001; |
58 | 56 | ||
59 | 57 | ||
@@ -527,6 +525,34 @@ struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time) | |||
527 | } | 525 | } |
528 | 526 | ||
529 | 527 | ||
528 | struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST) | ||
529 | { | ||
530 | if (DST) | ||
531 | { | ||
532 | //Add one then | ||
533 | offset++; | ||
534 | } | ||
535 | |||
536 | // We subtract off the PST/PDT offset _before_ getting | ||
537 | // "UTC" time, because this will handle wrapping around | ||
538 | // for 5 AM UTC -> 10 PM PDT of the previous day. | ||
539 | utc_time -= (-1 * offset) * MIN_PER_HOUR * SEC_PER_MIN; | ||
540 | |||
541 | // Internal buffer to PST/PDT (see above) | ||
542 | struct tm* internal_time = gmtime(&utc_time); | ||
543 | |||
544 | /* | ||
545 | // Don't do this, this won't correctly tell you if daylight savings is active in CA or not. | ||
546 | if (pacific_daylight_time) | ||
547 | { | ||
548 | internal_time->tm_isdst = 1; | ||
549 | } | ||
550 | */ | ||
551 | |||
552 | return internal_time; | ||
553 | } | ||
554 | |||
555 | |||
530 | void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) | 556 | void microsecondsToTimecodeString(U64 current_time, std::string& tcstring) |
531 | { | 557 | { |
532 | U64 hours; | 558 | U64 hours; |
diff --git a/linden/indra/llcommon/lltimer.h b/linden/indra/llcommon/lltimer.h index e2cf1c7..8590328 100644 --- a/linden/indra/llcommon/lltimer.h +++ b/linden/indra/llcommon/lltimer.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <limits.h> | 39 | #include <limits.h> |
40 | 40 | ||
41 | #include "stdtypes.h" | 41 | #include "stdtypes.h" |
42 | #include "llpreprocessor.h" | ||
42 | #include "lldate.h" | 43 | #include "lldate.h" |
43 | 44 | ||
44 | #include <string> | 45 | #include <string> |
@@ -54,7 +55,7 @@ const U32 USEC_PER_HOUR = USEC_PER_MIN * MIN_PER_HOUR; | |||
54 | const U32 SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR; | 55 | const U32 SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR; |
55 | const F64 SEC_PER_USEC = 1.0 / (F64) USEC_PER_SEC; | 56 | const F64 SEC_PER_USEC = 1.0 / (F64) USEC_PER_SEC; |
56 | 57 | ||
57 | class LLTimer | 58 | class LL_COMMON_API LLTimer |
58 | { | 59 | { |
59 | public: | 60 | public: |
60 | static LLTimer *sTimer; // global timer | 61 | static LLTimer *sTimer; // global timer |
@@ -113,17 +114,17 @@ public: | |||
113 | // | 114 | // |
114 | // Various functions for initializing/accessing clock and timing stuff. Don't use these without REALLY knowing how they work. | 115 | // Various functions for initializing/accessing clock and timing stuff. Don't use these without REALLY knowing how they work. |
115 | // | 116 | // |
116 | U64 get_clock_count(); | 117 | LL_COMMON_API U64 get_clock_count(); |
117 | F64 calc_clock_frequency(U32 msecs); | 118 | LL_COMMON_API F64 calc_clock_frequency(U32 msecs); |
118 | void update_clock_frequencies(); | 119 | LL_COMMON_API void update_clock_frequencies(); |
119 | 120 | ||
120 | // Sleep for milliseconds | 121 | // Sleep for milliseconds |
121 | void ms_sleep(U32 ms); | 122 | LL_COMMON_API void ms_sleep(U32 ms); |
122 | U32 micro_sleep(U64 us, U32 max_yields = 0xFFFFFFFF); | 123 | LL_COMMON_API U32 micro_sleep(U64 us, U32 max_yields = 0xFFFFFFFF); |
123 | 124 | ||
124 | // Returns the correct UTC time in seconds, like time(NULL). | 125 | // Returns the correct UTC time in seconds, like time(NULL). |
125 | // Useful on the viewer, which may have its local clock set wrong. | 126 | // Useful on the viewer, which may have its local clock set wrong. |
126 | time_t time_corrected(); | 127 | LL_COMMON_API time_t time_corrected(); |
127 | 128 | ||
128 | static inline time_t time_min() | 129 | static inline time_t time_min() |
129 | { | 130 | { |
@@ -154,24 +155,25 @@ static inline time_t time_max() | |||
154 | } | 155 | } |
155 | 156 | ||
156 | // Correction factor used by time_corrected() above. | 157 | // Correction factor used by time_corrected() above. |
157 | extern S32 gUTCOffset; | 158 | LL_COMMON_API extern S32 gUTCOffset; |
158 | 159 | ||
159 | // Is the current computer (in its current time zone) | 160 | // Is the current computer (in its current time zone) |
160 | // observing daylight savings time? | 161 | // observing daylight savings time? |
161 | BOOL is_daylight_savings(); | 162 | LL_COMMON_API BOOL is_daylight_savings(); |
162 | 163 | ||
163 | // Converts internal "struct tm" time buffer to Pacific Standard/Daylight Time | 164 | // Converts internal "struct tm" time buffer to Pacific Standard/Daylight Time |
164 | // Usage: | 165 | // Usage: |
165 | // S32 utc_time; | 166 | // S32 utc_time; |
166 | // utc_time = time_corrected(); | 167 | // utc_time = time_corrected(); |
167 | // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); | 168 | // struct tm* internal_time = utc_to_pacific_time(utc_time, gDaylight); |
168 | struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); | 169 | LL_COMMON_API struct tm* utc_to_pacific_time(time_t utc_time, BOOL pacific_daylight_time); |
170 | LL_COMMON_API struct tm* utc_to_offset_time(time_t utc_time, S32 offset, BOOL DST); | ||
169 | 171 | ||
170 | void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); | 172 | LL_COMMON_API void microsecondsToTimecodeString(U64 current_time, std::string& tcstring); |
171 | void secondsToTimecodeString(F32 current_time, std::string& tcstring); | 173 | LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstring); |
172 | 174 | ||
173 | // class for scheduling a function to be called at a given frequency (approximate, inprecise) | 175 | // class for scheduling a function to be called at a given frequency (approximate, inprecise) |
174 | class LLEventTimer | 176 | class LL_COMMON_API LLEventTimer |
175 | { | 177 | { |
176 | public: | 178 | public: |
177 | LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds | 179 | LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds |
diff --git a/linden/indra/llcommon/lluri.h b/linden/indra/llcommon/lluri.h index 156d80b..57bbedf 100644 --- a/linden/indra/llcommon/lluri.h +++ b/linden/indra/llcommon/lluri.h | |||
@@ -47,7 +47,7 @@ class LLApp; | |||
47 | * See: http://www.ietf.org/rfc/rfc3986.txt | 47 | * See: http://www.ietf.org/rfc/rfc3986.txt |
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | class LLURI | 50 | class LL_COMMON_API LLURI |
51 | { | 51 | { |
52 | public: | 52 | public: |
53 | LLURI(); | 53 | LLURI(); |
@@ -189,6 +189,6 @@ private: | |||
189 | }; | 189 | }; |
190 | 190 | ||
191 | // this operator required for tut | 191 | // this operator required for tut |
192 | bool operator!=(const LLURI& first, const LLURI& second); | 192 | LL_COMMON_API bool operator!=(const LLURI& first, const LLURI& second); |
193 | 193 | ||
194 | #endif // LL_LLURI_H | 194 | #endif // LL_LLURI_H |
diff --git a/linden/indra/llcommon/lluuid.h b/linden/indra/llcommon/lluuid.h index 4b32138..c78fb12 100644 --- a/linden/indra/llcommon/lluuid.h +++ b/linden/indra/llcommon/lluuid.h | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <iostream> | 35 | #include <iostream> |
36 | #include <set> | 36 | #include <set> |
37 | #include "stdtypes.h" | 37 | #include "stdtypes.h" |
38 | #include "llpreprocessor.h" | ||
38 | 39 | ||
39 | const S32 UUID_BYTES = 16; | 40 | const S32 UUID_BYTES = 16; |
40 | const S32 UUID_WORDS = 4; | 41 | const S32 UUID_WORDS = 4; |
@@ -47,7 +48,7 @@ struct uuid_time_t { | |||
47 | U32 low; | 48 | U32 low; |
48 | }; | 49 | }; |
49 | 50 | ||
50 | class LLUUID | 51 | class LL_COMMON_API LLUUID |
51 | { | 52 | { |
52 | public: | 53 | public: |
53 | // | 54 | // |
@@ -106,8 +107,8 @@ public: | |||
106 | LLUUID combine(const LLUUID& other) const; | 107 | LLUUID combine(const LLUUID& other) const; |
107 | void combine(const LLUUID& other, LLUUID& result) const; | 108 | void combine(const LLUUID& other, LLUUID& result) const; |
108 | 109 | ||
109 | friend std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); | 110 | friend LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLUUID &uuid); |
110 | friend std::istream& operator>>(std::istream& s, LLUUID &uuid); | 111 | friend LL_COMMON_API std::istream& operator>>(std::istream& s, LLUUID &uuid); |
111 | 112 | ||
112 | void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) | 113 | void toString(char *out) const; // Does not allocate memory, needs 36 characters (including \0) |
113 | void toString(std::string& out) const; | 114 | void toString(std::string& out) const; |
@@ -323,7 +324,7 @@ typedef std::set<LLUUID, lluuid_less> uuid_list_t; | |||
323 | */ | 324 | */ |
324 | typedef LLUUID LLAssetID; | 325 | typedef LLUUID LLAssetID; |
325 | 326 | ||
326 | class LLTransactionID : public LLUUID | 327 | class LL_COMMON_API LLTransactionID : public LLUUID |
327 | { | 328 | { |
328 | public: | 329 | public: |
329 | LLTransactionID() : LLUUID() { } | 330 | LLTransactionID() : LLUUID() { } |
diff --git a/linden/indra/llcommon/llworkerthread.cpp b/linden/indra/llcommon/llworkerthread.cpp index 8195e1c..e238a89 100644 --- a/linden/indra/llcommon/llworkerthread.cpp +++ b/linden/indra/llcommon/llworkerthread.cpp | |||
@@ -43,7 +43,7 @@ | |||
43 | LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : | 43 | LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : |
44 | LLQueuedThread(name, threaded) | 44 | LLQueuedThread(name, threaded) |
45 | { | 45 | { |
46 | mDeleteMutex = new LLMutex(NULL); | 46 | mDeleteMutex = new LLMutex; |
47 | } | 47 | } |
48 | 48 | ||
49 | LLWorkerThread::~LLWorkerThread() | 49 | LLWorkerThread::~LLWorkerThread() |
@@ -183,7 +183,6 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na | |||
183 | : mWorkerThread(workerthread), | 183 | : mWorkerThread(workerthread), |
184 | mWorkerClassName(name), | 184 | mWorkerClassName(name), |
185 | mRequestHandle(LLWorkerThread::nullHandle()), | 185 | mRequestHandle(LLWorkerThread::nullHandle()), |
186 | mMutex(NULL), | ||
187 | mWorkFlags(0) | 186 | mWorkFlags(0) |
188 | { | 187 | { |
189 | if (!mWorkerThread) | 188 | if (!mWorkerThread) |
diff --git a/linden/indra/llcommon/llworkerthread.h b/linden/indra/llcommon/llworkerthread.h index 708d812..8e0dd8a 100644 --- a/linden/indra/llcommon/llworkerthread.h +++ b/linden/indra/llcommon/llworkerthread.h | |||
@@ -50,7 +50,7 @@ class LLWorkerClass; | |||
50 | // Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small | 50 | // Note: ~LLWorkerThread is O(N) N=# of worker threads, assumed to be small |
51 | // It is assumed that LLWorkerThreads are rarely created/destroyed. | 51 | // It is assumed that LLWorkerThreads are rarely created/destroyed. |
52 | 52 | ||
53 | class LLWorkerThread : public LLQueuedThread | 53 | class LL_COMMON_API LLWorkerThread : public LLQueuedThread |
54 | { | 54 | { |
55 | friend class LLWorkerClass; | 55 | friend class LLWorkerClass; |
56 | public: | 56 | public: |
@@ -114,7 +114,7 @@ public: | |||
114 | // Only one background task can be active at a time (per instance). | 114 | // Only one background task can be active at a time (per instance). |
115 | // i.e. don't call addWork() if haveWork() returns true | 115 | // i.e. don't call addWork() if haveWork() returns true |
116 | 116 | ||
117 | class LLWorkerClass | 117 | class LL_COMMON_API LLWorkerClass |
118 | { | 118 | { |
119 | friend class LLWorkerThread; | 119 | friend class LLWorkerThread; |
120 | friend class LLWorkerThread::WorkRequest; | 120 | friend class LLWorkerThread::WorkRequest; |
@@ -194,7 +194,7 @@ protected: | |||
194 | U32 mRequestPriority; // last priority set | 194 | U32 mRequestPriority; // last priority set |
195 | 195 | ||
196 | private: | 196 | private: |
197 | LLMutex mMutex; | 197 | LLMutexRootPool mMutex; // Use LLMutexRootPool since this object is created and destructed by multiple threads. |
198 | LLAtomicU32 mWorkFlags; | 198 | LLAtomicU32 mWorkFlags; |
199 | }; | 199 | }; |
200 | 200 | ||
diff --git a/linden/indra/llcommon/metaclass.h b/linden/indra/llcommon/metaclass.h index cc10f16..f38bcd2 100644 --- a/linden/indra/llcommon/metaclass.h +++ b/linden/indra/llcommon/metaclass.h | |||
@@ -43,7 +43,7 @@ | |||
43 | class LLReflective; | 43 | class LLReflective; |
44 | class LLMetaProperty; | 44 | class LLMetaProperty; |
45 | class LLMetaMethod; | 45 | class LLMetaMethod; |
46 | class LLMetaClass | 46 | class LL_COMMON_API LLMetaClass |
47 | { | 47 | { |
48 | public: | 48 | public: |
49 | 49 | ||
diff --git a/linden/indra/llcommon/metaproperty.h b/linden/indra/llcommon/metaproperty.h index e5ac359..6c016c5 100644 --- a/linden/indra/llcommon/metaproperty.h +++ b/linden/indra/llcommon/metaproperty.h | |||
@@ -41,7 +41,7 @@ | |||
41 | 41 | ||
42 | class LLMetaClass; | 42 | class LLMetaClass; |
43 | class LLReflective; | 43 | class LLReflective; |
44 | class LLMetaProperty | 44 | class LL_COMMON_API LLMetaProperty |
45 | { | 45 | { |
46 | public: | 46 | public: |
47 | LLMetaProperty(const std::string& name, const LLMetaClass& object_class); | 47 | LLMetaProperty(const std::string& name, const LLMetaClass& object_class); |
diff --git a/linden/indra/llcommon/reflective.h b/linden/indra/llcommon/reflective.h index e2c18eb..a135376 100644 --- a/linden/indra/llcommon/reflective.h +++ b/linden/indra/llcommon/reflective.h | |||
@@ -36,7 +36,7 @@ | |||
36 | #define LL_REFLECTIVE_H | 36 | #define LL_REFLECTIVE_H |
37 | 37 | ||
38 | class LLMetaClass; | 38 | class LLMetaClass; |
39 | class LLReflective | 39 | class LL_COMMON_API LLReflective |
40 | { | 40 | { |
41 | public: | 41 | public: |
42 | LLReflective(); | 42 | LLReflective(); |
diff --git a/linden/indra/llcommon/stdtypes.h b/linden/indra/llcommon/stdtypes.h index af0b4dd..aed1e46 100644 --- a/linden/indra/llcommon/stdtypes.h +++ b/linden/indra/llcommon/stdtypes.h | |||
@@ -64,10 +64,17 @@ typedef long long unsigned int U64; | |||
64 | #endif | 64 | #endif |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | #ifdef LL_DARWIN | ||
68 | #ifndef BOOL | ||
69 | #define BOOL S32 | ||
70 | #endif | ||
71 | #else | ||
72 | typedef S32 BOOL; | ||
73 | #endif | ||
74 | |||
67 | typedef float F32; | 75 | typedef float F32; |
68 | typedef double F64; | 76 | typedef double F64; |
69 | 77 | ||
70 | typedef S32 BOOL; | ||
71 | typedef U8 KEY; | 78 | typedef U8 KEY; |
72 | typedef U32 MASK; | 79 | typedef U32 MASK; |
73 | typedef U32 TPACKETID; | 80 | typedef U32 TPACKETID; |
diff --git a/linden/indra/llcommon/timing.h b/linden/indra/llcommon/timing.h index 2b9f60a..cfc637e 100644 --- a/linden/indra/llcommon/timing.h +++ b/linden/indra/llcommon/timing.h | |||
@@ -44,6 +44,6 @@ const U64 SEC_TO_MICROSEC_U64 = 1000000; | |||
44 | const U32 SEC_PER_DAY = 86400; | 44 | const U32 SEC_PER_DAY = 86400; |
45 | 45 | ||
46 | // This is just a stub, implementation in lltimer.cpp. This file will be deprecated in the future. | 46 | // This is just a stub, implementation in lltimer.cpp. This file will be deprecated in the future. |
47 | U64 totalTime(); // Returns current system time in microseconds | 47 | LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds |
48 | 48 | ||
49 | #endif | 49 | #endif |
diff --git a/linden/indra/llcommon/u64.h b/linden/indra/llcommon/u64.h index 09a6b3e..eb51131 100644 --- a/linden/indra/llcommon/u64.h +++ b/linden/indra/llcommon/u64.h | |||
@@ -39,14 +39,14 @@ | |||
39 | * @param str The string to parse. | 39 | * @param str The string to parse. |
40 | * @return Returns the first U64 value found in the string or 0 on failure. | 40 | * @return Returns the first U64 value found in the string or 0 on failure. |
41 | */ | 41 | */ |
42 | U64 str_to_U64(const std::string& str); | 42 | LL_COMMON_API U64 str_to_U64(const std::string& str); |
43 | 43 | ||
44 | /** | 44 | /** |
45 | * @brief Given a U64 value, return a printable representation. | 45 | * @brief Given a U64 value, return a printable representation. |
46 | * @param value The U64 to turn into a printable character array. | 46 | * @param value The U64 to turn into a printable character array. |
47 | * @return Returns the result string. | 47 | * @return Returns the result string. |
48 | */ | 48 | */ |
49 | std::string U64_to_str(U64 value); | 49 | LL_COMMON_API std::string U64_to_str(U64 value); |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * @brief Given a U64 value, return a printable representation. | 52 | * @brief Given a U64 value, return a printable representation. |
@@ -65,16 +65,16 @@ std::string U64_to_str(U64 value); | |||
65 | * @param result_size The size of the buffer allocated. Use U64_BUF. | 65 | * @param result_size The size of the buffer allocated. Use U64_BUF. |
66 | * @return Returns the result pointer. | 66 | * @return Returns the result pointer. |
67 | */ | 67 | */ |
68 | char* U64_to_str(U64 value, char* result, S32 result_size); | 68 | LL_COMMON_API char* U64_to_str(U64 value, char* result, S32 result_size); |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * @brief Convert a U64 to the closest F64 value. | 71 | * @brief Convert a U64 to the closest F64 value. |
72 | */ | 72 | */ |
73 | F64 U64_to_F64(const U64 value); | 73 | LL_COMMON_API F64 U64_to_F64(const U64 value); |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * @brief Helper function to wrap strtoull() which is not available on windows. | 76 | * @brief Helper function to wrap strtoull() which is not available on windows. |
77 | */ | 77 | */ |
78 | U64 llstrtou64(const char* str, char** end, S32 base); | 78 | LL_COMMON_API U64 llstrtou64(const char* str, char** end, S32 base); |
79 | 79 | ||
80 | #endif | 80 | #endif |