diff options
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 |