diff options
Diffstat (limited to '')
56 files changed, 878 insertions, 732 deletions
diff --git a/linden/doc/contributions.txt b/linden/doc/contributions.txt index 6646a40..c8dd773 100644 --- a/linden/doc/contributions.txt +++ b/linden/doc/contributions.txt | |||
@@ -80,6 +80,7 @@ Aleric Inglewood | |||
80 | IMP-578 | 80 | IMP-578 |
81 | IMP-579 | 81 | IMP-579 |
82 | IMP-581 | 82 | IMP-581 |
83 | IMP-590 | ||
83 | IMP-592 | 84 | IMP-592 |
84 | IMP-595 | 85 | IMP-595 |
85 | IMP-660 | 86 | IMP-660 |
diff --git a/linden/indra/llcommon/CMakeLists.txt b/linden/indra/llcommon/CMakeLists.txt index 5d590a9..a05ee6f 100644 --- a/linden/indra/llcommon/CMakeLists.txt +++ b/linden/indra/llcommon/CMakeLists.txt | |||
@@ -13,6 +13,7 @@ include_directories( | |||
13 | ) | 13 | ) |
14 | 14 | ||
15 | set(llcommon_SOURCE_FILES | 15 | set(llcommon_SOURCE_FILES |
16 | aiaprpool.cpp | ||
16 | imageids.cpp | 17 | imageids.cpp |
17 | indra_constants.cpp | 18 | indra_constants.cpp |
18 | llapp.cpp | 19 | llapp.cpp |
@@ -74,6 +75,7 @@ set(llcommon_SOURCE_FILES | |||
74 | set(llcommon_HEADER_FILES | 75 | set(llcommon_HEADER_FILES |
75 | CMakeLists.txt | 76 | CMakeLists.txt |
76 | 77 | ||
78 | aiaprpool.h | ||
77 | bitpack.h | 79 | bitpack.h |
78 | ctype_workaround.h | 80 | ctype_workaround.h |
79 | doublelinkedlist.h | 81 | doublelinkedlist.h |
@@ -147,6 +149,7 @@ set(llcommon_HEADER_FILES | |||
147 | llqueuedthread.h | 149 | llqueuedthread.h |
148 | llrand.h | 150 | llrand.h |
149 | llrun.h | 151 | llrun.h |
152 | llscopedvolatileaprpool.h | ||
150 | llsd.h | 153 | llsd.h |
151 | llsdserialize.h | 154 | llsdserialize.h |
152 | llsdserialize_xml.h | 155 | llsdserialize_xml.h |
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..f6d7ffa --- /dev/null +++ b/linden/indra/llcommon/aiaprpool.h | |||
@@ -0,0 +1,236 @@ | |||
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> // Needed before including apr_portable.h | ||
42 | #endif | ||
43 | |||
44 | #include "apr_portable.h" | ||
45 | #include "apr_pools.h" | ||
46 | #include "llerror.h" | ||
47 | |||
48 | extern void ll_init_apr(); | ||
49 | |||
50 | /** | ||
51 | * @brief A wrapper around the APR memory pool API. | ||
52 | * | ||
53 | * Usage of this class should be restricted to passing it to libapr-1 function calls that need it. | ||
54 | * | ||
55 | */ | ||
56 | class LL_COMMON_API AIAPRPool | ||
57 | { | ||
58 | protected: | ||
59 | apr_pool_t* mPool; //!< Pointer to the underlaying pool. NULL if not initialized. | ||
60 | AIAPRPool* mParent; //!< Pointer to the parent pool, if any. Only valid when mPool is non-zero. | ||
61 | apr_os_thread_t mOwner; //!< The thread that owns this memory pool. Only valid when mPool is non-zero. | ||
62 | |||
63 | public: | ||
64 | //! Construct an uninitialized (destructed) pool. | ||
65 | AIAPRPool(void) : mPool(NULL) { } | ||
66 | |||
67 | //! Construct a subpool from an existing pool. | ||
68 | // This is not a copy-constructor, this class doesn't have one! | ||
69 | AIAPRPool(AIAPRPool& parent) : mPool(NULL) { create(parent); } | ||
70 | |||
71 | //! Destruct the memory pool (free all of it's subpools and allocated memory). | ||
72 | ~AIAPRPool() { destroy(); } | ||
73 | |||
74 | protected: | ||
75 | // Create a pool that is allocated from the Operating System. Only used by AIAPRRootPool. | ||
76 | AIAPRPool(int) : mPool(NULL), mParent(NULL), mOwner(apr_os_thread_current()) | ||
77 | { | ||
78 | apr_status_t const apr_pool_create_status = apr_pool_create(&mPool, NULL); | ||
79 | llassert_always(apr_pool_create_status == APR_SUCCESS); | ||
80 | llassert(mPool); | ||
81 | apr_pool_cleanup_register(mPool, this, &s_plain_cleanup, &apr_pool_cleanup_null); | ||
82 | } | ||
83 | |||
84 | public: | ||
85 | //! Create a subpool from parent. May only be called for an uninitialized/destroyed pool. | ||
86 | // The default parameter causes the root pool of the current thread to be used. | ||
87 | void create(AIAPRPool& parent = *static_cast<AIAPRPool*>(NULL)); | ||
88 | |||
89 | //! Destroy the (sub)pool, if any. | ||
90 | void destroy(void); | ||
91 | |||
92 | // Use some safebool idiom (http://www.artima.com/cppsource/safebool.html) rather than operator bool. | ||
93 | typedef apr_pool_t* const AIAPRPool::* const bool_type; | ||
94 | //! Return true if the pool is initialized. | ||
95 | operator bool_type() const { return mPool ? &AIAPRPool::mPool : 0; } | ||
96 | |||
97 | // Painful, but we have to either provide access to this, or wrap | ||
98 | // every APR function call that needs a apr_pool_t* to be passed. | ||
99 | // NEVER destroy a pool that is returned by this function! | ||
100 | apr_pool_t* operator()(void) const | ||
101 | { | ||
102 | llassert(mPool); | ||
103 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
104 | return mPool; | ||
105 | } | ||
106 | |||
107 | // Free all memory without destructing the pool. | ||
108 | void clear(void) | ||
109 | { | ||
110 | llassert(mPool); | ||
111 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
112 | apr_pool_clear(mPool); | ||
113 | } | ||
114 | |||
115 | // These methods would make this class 'complete' (as wrapper around the libapr | ||
116 | // pool functions), but we don't use memory pools in the viewer (only when | ||
117 | // we are forced to pass one to a libapr call), so don't define them in order | ||
118 | // not to encourage people to use them. | ||
119 | #if 0 | ||
120 | void* palloc(size_t size) | ||
121 | { | ||
122 | llassert(mPool); | ||
123 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
124 | return apr_palloc(mPool, size); | ||
125 | } | ||
126 | void* pcalloc(size_t size) | ||
127 | { | ||
128 | llassert(mPool); | ||
129 | llassert(apr_os_thread_equal(mOwner, apr_os_thread_current())); | ||
130 | return apr_pcalloc(mPool, size); | ||
131 | } | ||
132 | #endif | ||
133 | |||
134 | private: | ||
135 | bool parent_is_being_destructed(void); | ||
136 | static apr_status_t s_plain_cleanup(void* userdata) { return static_cast<AIAPRPool*>(userdata)->plain_cleanup(); } | ||
137 | |||
138 | apr_status_t plain_cleanup(void) | ||
139 | { | ||
140 | if (mPool && // We are not being destructed, | ||
141 | parent_is_being_destructed()) // but our parent is. | ||
142 | // This means the pool is being destructed recursively by libapr | ||
143 | // because one of it's parents is being destructed. | ||
144 | { | ||
145 | mPool = NULL; // Stop destroy() from destructing the pool again. | ||
146 | } | ||
147 | return APR_SUCCESS; | ||
148 | } | ||
149 | }; | ||
150 | |||
151 | class AIAPRInitialization | ||
152 | { | ||
153 | public: | ||
154 | AIAPRInitialization(void); | ||
155 | }; | ||
156 | |||
157 | /** | ||
158 | * @brief Root memory pool (allocates memory from the operating system). | ||
159 | * | ||
160 | * This class should only be used by AIThreadLocalData (and LLMutexRootPool | ||
161 | * when APR_HAS_THREADS isn't defined). | ||
162 | */ | ||
163 | class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool | ||
164 | { | ||
165 | private: | ||
166 | friend class AIThreadLocalData; | ||
167 | #if !APR_HAS_THREADS | ||
168 | friend class LLMutexRootPool; | ||
169 | #endif | ||
170 | //! Construct a root memory pool. Should only be used by AIThreadLocalData. | ||
171 | AIAPRRootPool(void); | ||
172 | ~AIAPRRootPool(); | ||
173 | |||
174 | private: | ||
175 | // Keep track of how many root pools exist and when the last one is destructed. | ||
176 | static bool sCountInitialized; | ||
177 | static apr_uint32_t volatile sCount; | ||
178 | |||
179 | public: | ||
180 | // Return a global root pool that is independent of AIThreadLocalData. | ||
181 | // Normally you should not use this. Only use for early initialization | ||
182 | // (before main) and deinitialization (after main). | ||
183 | static AIAPRRootPool& get(void); | ||
184 | |||
185 | #if APR_POOL_DEBUG | ||
186 | void grab_ownership(void) | ||
187 | { | ||
188 | // You need a patched libapr to use this. | ||
189 | // See http://web.archiveorange.com/archive/v/5XO9y2zoxUOMt6Gmi1OI | ||
190 | apr_pool_owner_set(mPool); | ||
191 | } | ||
192 | #endif | ||
193 | |||
194 | private: | ||
195 | // Used for constructing the Special Global Root Pool (returned by AIAPRRootPool::get). | ||
196 | // It is the same as the default constructor but omits to increment sCount. As a result, | ||
197 | // we must be sure that at least one other AIAPRRootPool is created before termination | ||
198 | // of the application (which is the case: we create one AIAPRRootPool per thread). | ||
199 | AIAPRRootPool(int) : AIAPRInitialization(), AIAPRPool(0) { } | ||
200 | }; | ||
201 | |||
202 | //! Volatile memory pool | ||
203 | // | ||
204 | // 'Volatile' APR memory pool which normally only clears memory, | ||
205 | // and does not destroy the pool (the same pool is reused) for | ||
206 | // greater efficiency. However, as a safe guard the apr pool | ||
207 | // is destructed every FULL_VOLATILE_APR_POOL uses to allow | ||
208 | // the system memory to be allocated more efficiently and not | ||
209 | // get scattered through RAM. | ||
210 | // | ||
211 | class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool | ||
212 | { | ||
213 | public: | ||
214 | AIVolatileAPRPool(void) : mNumActiveRef(0), mNumTotalRef(0) { } | ||
215 | |||
216 | apr_pool_t* getVolatileAPRPool(void) | ||
217 | { | ||
218 | if (!mPool) create(); | ||
219 | ++mNumActiveRef; | ||
220 | ++mNumTotalRef; | ||
221 | return AIAPRPool::operator()(); | ||
222 | } | ||
223 | void clearVolatileAPRPool(void); | ||
224 | |||
225 | bool isOld(void) const { return mNumTotalRef > FULL_VOLATILE_APR_POOL; } | ||
226 | bool isUnused() const { return mNumActiveRef == 0; } | ||
227 | |||
228 | private: | ||
229 | S32 mNumActiveRef; // Number of active uses of the pool. | ||
230 | S32 mNumTotalRef; // Number of total uses of the pool since last creation. | ||
231 | |||
232 | // Maximum number of references to AIVolatileAPRPool until the pool is recreated. | ||
233 | static S32 const FULL_VOLATILE_APR_POOL = 1024; | ||
234 | }; | ||
235 | |||
236 | #endif // AIAPRPOOL_H | ||
diff --git a/linden/indra/llcommon/llapp.cpp b/linden/indra/llcommon/llapp.cpp index e269f59..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) : |
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 2aed515..ded15f5 100644 --- a/linden/indra/llcommon/llapr.h +++ b/linden/indra/llcommon/llapr.h | |||
@@ -48,73 +48,8 @@ | |||
48 | #include "apr_atomic.h" | 48 | #include "apr_atomic.h" |
49 | #include "llstring.h" | 49 | #include "llstring.h" |
50 | 50 | ||
51 | extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; | 51 | class AIAPRPool; |
52 | 52 | class AIVolatileAPRPool; | |
53 | /** | ||
54 | * @brief initialize the common apr constructs -- apr itself, the | ||
55 | * global pool, and a mutex. | ||
56 | */ | ||
57 | void LL_COMMON_API ll_init_apr(); | ||
58 | |||
59 | /** | ||
60 | * @brief Cleanup those common apr constructs. | ||
61 | */ | ||
62 | void LL_COMMON_API ll_cleanup_apr(); | ||
63 | |||
64 | // | ||
65 | //LL apr_pool | ||
66 | //manage apr_pool_t, destroy allocated apr_pool in the destruction function. | ||
67 | // | ||
68 | class LL_COMMON_API LLAPRPool | ||
69 | { | ||
70 | public: | ||
71 | LLAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE) ; | ||
72 | ~LLAPRPool() ; | ||
73 | |||
74 | apr_pool_t* getAPRPool() ; | ||
75 | apr_status_t getStatus() {return mStatus ; } | ||
76 | |||
77 | protected: | ||
78 | void releaseAPRPool() ; | ||
79 | void createAPRPool() ; | ||
80 | |||
81 | protected: | ||
82 | apr_pool_t* mPool ; //pointing to an apr_pool | ||
83 | apr_pool_t* mParent ; //parent pool | ||
84 | 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. | ||
85 | apr_status_t mStatus ; //status when creating the pool | ||
86 | BOOL mReleasePoolFlag ; //if set, mPool is destroyed when LLAPRPool is deleted. default value is true. | ||
87 | }; | ||
88 | |||
89 | // | ||
90 | //volatile LL apr_pool | ||
91 | //which clears memory automatically. | ||
92 | //so it can not hold static data or data after memory is cleared | ||
93 | // | ||
94 | class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool | ||
95 | { | ||
96 | public: | ||
97 | LLVolatileAPRPool(apr_pool_t *parent = NULL, apr_size_t size = 0, BOOL releasePoolFlag = TRUE); | ||
98 | ~LLVolatileAPRPool(){} | ||
99 | |||
100 | apr_pool_t* getVolatileAPRPool() ; | ||
101 | |||
102 | void clearVolatileAPRPool() ; | ||
103 | |||
104 | BOOL isFull() ; | ||
105 | BOOL isEmpty() {return !mNumActiveRef ;} | ||
106 | |||
107 | static void initLocalAPRFilePool(); | ||
108 | static void createLocalAPRFilePool(); | ||
109 | static void destroyLocalAPRFilePool(void* thread_local_data); | ||
110 | static LLVolatileAPRPool* getLocalAPRFilePool(); | ||
111 | |||
112 | private: | ||
113 | S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. | ||
114 | S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. | ||
115 | |||
116 | static apr_threadkey_t* sLocalAPRFilePoolKey; | ||
117 | } ; | ||
118 | 53 | ||
119 | /** | 54 | /** |
120 | * @class LLScopedLock | 55 | * @class LLScopedLock |
@@ -205,7 +140,8 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable | |||
205 | // make this non copyable since a copy closes the file | 140 | // make this non copyable since a copy closes the file |
206 | private: | 141 | private: |
207 | apr_file_t* mFile ; | 142 | apr_file_t* mFile ; |
208 | 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. | ||
209 | 145 | ||
210 | public: | 146 | public: |
211 | enum access_t { | 147 | enum access_t { |
@@ -260,6 +196,4 @@ bool LL_COMMON_API ll_apr_warn_status(apr_status_t status); | |||
260 | 196 | ||
261 | void LL_COMMON_API ll_apr_assert_status(apr_status_t status); | 197 | void LL_COMMON_API ll_apr_assert_status(apr_status_t status); |
262 | 198 | ||
263 | extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool | ||
264 | |||
265 | #endif // LL_LLAPR_H | 199 | #endif // LL_LLAPR_H |
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 851d4ac..300ebe2 100644 --- a/linden/indra/llcommon/llcommon.h +++ b/linden/indra/llcommon/llcommon.h | |||
@@ -43,8 +43,6 @@ class LL_COMMON_API LLCommon | |||
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/llerror.cpp b/linden/indra/llcommon/llerror.cpp index edc570f..b9be370 100644 --- a/linden/indra/llcommon/llerror.cpp +++ b/linden/indra/llcommon/llerror.cpp | |||
@@ -871,6 +871,9 @@ You get: | |||
871 | 871 | ||
872 | */ | 872 | */ |
873 | 873 | ||
874 | apr_thread_mutex_t* gLogMutexp; | ||
875 | apr_thread_mutex_t* gCallStacksLogMutexp; | ||
876 | |||
874 | namespace { | 877 | namespace { |
875 | bool checkLevelMap(const LevelMap& map, const std::string& key, | 878 | bool checkLevelMap(const LevelMap& map, const std::string& key, |
876 | LLError::ELevel& level) | 879 | LLError::ELevel& level) |
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/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/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 98d64ef..8708929 100644 --- a/linden/indra/llcommon/llthread.h +++ b/linden/indra/llcommon/llthread.h | |||
@@ -38,11 +38,28 @@ | |||
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 | ||
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 | |||
46 | class LL_COMMON_API LLThread | 63 | class LL_COMMON_API LLThread |
47 | { | 64 | { |
48 | public: | 65 | public: |
@@ -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 LL_COMMON_API 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; | ||
178 | }; | ||
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; | ||
145 | }; | 204 | }; |
205 | #endif // APR_HAS_THREADS | ||
146 | 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 LL_COMMON_API 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 |
@@ -162,7 +222,7 @@ protected: | |||
162 | class LL_COMMON_API 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,7 @@ public: | |||
172 | mMutex->unlock(); | 232 | mMutex->unlock(); |
173 | } | 233 | } |
174 | private: | 234 | private: |
175 | LLMutex* mMutex; | 235 | LLMutexBase* mMutex; |
176 | }; | 236 | }; |
177 | 237 | ||
178 | //============================================================================ | 238 | //============================================================================ |
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 33d4c40..8e0dd8a 100644 --- a/linden/indra/llcommon/llworkerthread.h +++ b/linden/indra/llcommon/llworkerthread.h | |||
@@ -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/llcrashlogger/llcrashlogger.cpp b/linden/indra/llcrashlogger/llcrashlogger.cpp index d25be55..b6afbc6 100755 --- a/linden/indra/llcrashlogger/llcrashlogger.cpp +++ b/linden/indra/llcrashlogger/llcrashlogger.cpp | |||
@@ -387,8 +387,7 @@ bool LLCrashLogger::init() | |||
387 | return false; | 387 | return false; |
388 | } | 388 | } |
389 | 389 | ||
390 | gServicePump = new LLPumpIO(gAPRPoolp); | 390 | gServicePump = new LLPumpIO; |
391 | gServicePump->prime(gAPRPoolp); | ||
392 | LLHTTPClient::setPump(*gServicePump); | 391 | LLHTTPClient::setPump(*gServicePump); |
393 | 392 | ||
394 | //If we've opened the crash logger, assume we can delete the marker file if it exists | 393 | //If we've opened the crash logger, assume we can delete the marker file if it exists |
diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp index 776c481..e933750 100644 --- a/linden/indra/llimage/llimage.cpp +++ b/linden/indra/llimage/llimage.cpp | |||
@@ -57,7 +57,7 @@ LLMutex* LLImage::sMutex = NULL; | |||
57 | //static | 57 | //static |
58 | void LLImage::initClass(const bool& useDSO) | 58 | void LLImage::initClass(const bool& useDSO) |
59 | { | 59 | { |
60 | sMutex = new LLMutex(NULL); | 60 | sMutex = new LLMutex; |
61 | if (useDSO) | 61 | if (useDSO) |
62 | { | 62 | { |
63 | LLImageJ2C::openDSO(); | 63 | LLImageJ2C::openDSO(); |
diff --git a/linden/indra/llimage/llimagej2c.cpp b/linden/indra/llimage/llimagej2c.cpp index b99ebff..9e88bcd 100644 --- a/linden/indra/llimage/llimagej2c.cpp +++ b/linden/indra/llimage/llimagej2c.cpp | |||
@@ -46,7 +46,7 @@ typedef const char* (*EngineInfoLLImageJ2CFunction)(); | |||
46 | CreateLLImageJ2CFunction j2cimpl_create_func; | 46 | CreateLLImageJ2CFunction j2cimpl_create_func; |
47 | DestroyLLImageJ2CFunction j2cimpl_destroy_func; | 47 | DestroyLLImageJ2CFunction j2cimpl_destroy_func; |
48 | EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; | 48 | EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; |
49 | apr_pool_t *j2cimpl_dso_memory_pool; | 49 | AIAPRPool j2cimpl_dso_memory_pool; |
50 | apr_dso_handle_t *j2cimpl_dso_handle; | 50 | apr_dso_handle_t *j2cimpl_dso_handle; |
51 | 51 | ||
52 | //Declare the prototype for theses functions here, their functionality | 52 | //Declare the prototype for theses functions here, their functionality |
@@ -81,13 +81,12 @@ void LLImageJ2C::openDSO() | |||
81 | gDirUtilp->getExecutableDir()); | 81 | gDirUtilp->getExecutableDir()); |
82 | 82 | ||
83 | j2cimpl_dso_handle = NULL; | 83 | j2cimpl_dso_handle = NULL; |
84 | j2cimpl_dso_memory_pool = NULL; | 84 | j2cimpl_dso_memory_pool.create(); |
85 | 85 | ||
86 | //attempt to load the shared library | 86 | //attempt to load the shared library |
87 | apr_pool_create(&j2cimpl_dso_memory_pool, NULL); | ||
88 | rv = apr_dso_load(&j2cimpl_dso_handle, | 87 | rv = apr_dso_load(&j2cimpl_dso_handle, |
89 | dso_path.c_str(), | 88 | dso_path.c_str(), |
90 | j2cimpl_dso_memory_pool); | 89 | j2cimpl_dso_memory_pool()); |
91 | 90 | ||
92 | //now, check for success | 91 | //now, check for success |
93 | if ( rv == APR_SUCCESS ) | 92 | if ( rv == APR_SUCCESS ) |
@@ -151,11 +150,7 @@ void LLImageJ2C::openDSO() | |||
151 | j2cimpl_dso_handle = NULL; | 150 | j2cimpl_dso_handle = NULL; |
152 | } | 151 | } |
153 | 152 | ||
154 | if ( j2cimpl_dso_memory_pool ) | 153 | j2cimpl_dso_memory_pool.destroy(); |
155 | { | ||
156 | apr_pool_destroy(j2cimpl_dso_memory_pool); | ||
157 | j2cimpl_dso_memory_pool = NULL; | ||
158 | } | ||
159 | } | 154 | } |
160 | } | 155 | } |
161 | 156 | ||
@@ -163,7 +158,7 @@ void LLImageJ2C::openDSO() | |||
163 | void LLImageJ2C::closeDSO() | 158 | void LLImageJ2C::closeDSO() |
164 | { | 159 | { |
165 | if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); | 160 | if ( j2cimpl_dso_handle ) apr_dso_unload(j2cimpl_dso_handle); |
166 | if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool); | 161 | j2cimpl_dso_memory_pool.destroy(); |
167 | } | 162 | } |
168 | 163 | ||
169 | //static | 164 | //static |
diff --git a/linden/indra/llimage/llimageworker.cpp b/linden/indra/llimage/llimageworker.cpp index 558a968..dc989e5 100644 --- a/linden/indra/llimage/llimageworker.cpp +++ b/linden/indra/llimage/llimageworker.cpp | |||
@@ -41,14 +41,13 @@ | |||
41 | LLImageDecodeThread::LLImageDecodeThread(bool threaded) | 41 | LLImageDecodeThread::LLImageDecodeThread(bool threaded) |
42 | : LLQueuedThread("imagedecode", threaded) | 42 | : LLQueuedThread("imagedecode", threaded) |
43 | { | 43 | { |
44 | mCreationMutex = new LLMutex(getAPRPool()); | ||
45 | } | 44 | } |
46 | 45 | ||
47 | // MAIN THREAD | 46 | // MAIN THREAD |
48 | // virtual | 47 | // virtual |
49 | S32 LLImageDecodeThread::update(U32 max_time_ms) | 48 | S32 LLImageDecodeThread::update(U32 max_time_ms) |
50 | { | 49 | { |
51 | LLMutexLock lock(mCreationMutex); | 50 | LLMutexLock lock(&mCreationMutex); |
52 | for (creation_list_t::iterator iter = mCreationList.begin(); | 51 | for (creation_list_t::iterator iter = mCreationList.begin(); |
53 | iter != mCreationList.end(); ++iter) | 52 | iter != mCreationList.end(); ++iter) |
54 | { | 53 | { |
@@ -71,7 +70,7 @@ S32 LLImageDecodeThread::update(U32 max_time_ms) | |||
71 | LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, | 70 | LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, |
72 | U32 priority, S32 discard, BOOL needs_aux, Responder* responder) | 71 | U32 priority, S32 discard, BOOL needs_aux, Responder* responder) |
73 | { | 72 | { |
74 | LLMutexLock lock(mCreationMutex); | 73 | LLMutexLock lock(&mCreationMutex); |
75 | handle_t handle = generateHandle(); | 74 | handle_t handle = generateHandle(); |
76 | mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); | 75 | mCreationList.push_back(creation_info(handle, image, priority, discard, needs_aux, responder)); |
77 | return handle; | 76 | return handle; |
@@ -81,7 +80,7 @@ LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* | |||
81 | // Returns the size of the mutex guarded list as an indication of sanity | 80 | // Returns the size of the mutex guarded list as an indication of sanity |
82 | S32 LLImageDecodeThread::tut_size() | 81 | S32 LLImageDecodeThread::tut_size() |
83 | { | 82 | { |
84 | LLMutexLock lock(mCreationMutex); | 83 | LLMutexLock lock(&mCreationMutex); |
85 | S32 res = mCreationList.size(); | 84 | S32 res = mCreationList.size(); |
86 | return res; | 85 | return res; |
87 | } | 86 | } |
diff --git a/linden/indra/llimage/llimageworker.h b/linden/indra/llimage/llimageworker.h index 0260206..fa2a8fa 100644 --- a/linden/indra/llimage/llimageworker.h +++ b/linden/indra/llimage/llimageworker.h | |||
@@ -101,7 +101,7 @@ private: | |||
101 | }; | 101 | }; |
102 | typedef std::list<creation_info> creation_list_t; | 102 | typedef std::list<creation_info> creation_list_t; |
103 | creation_list_t mCreationList; | 103 | creation_list_t mCreationList; |
104 | LLMutex* mCreationMutex; | 104 | LLMutex mCreationMutex; |
105 | }; | 105 | }; |
106 | 106 | ||
107 | #endif | 107 | #endif |
diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp index 53641fc..8bfebcb 100644 --- a/linden/indra/llmath/llvolumemgr.cpp +++ b/linden/indra/llmath/llvolumemgr.cpp | |||
@@ -55,7 +55,7 @@ LLVolumeMgr::LLVolumeMgr() | |||
55 | { | 55 | { |
56 | // the LLMutex magic interferes with easy unit testing, | 56 | // the LLMutex magic interferes with easy unit testing, |
57 | // so you now must manually call useMutex() to use it | 57 | // so you now must manually call useMutex() to use it |
58 | //mDataMutex = new LLMutex(gAPRPoolp); | 58 | //mDataMutex = new LLMutex; |
59 | } | 59 | } |
60 | 60 | ||
61 | LLVolumeMgr::~LLVolumeMgr() | 61 | LLVolumeMgr::~LLVolumeMgr() |
@@ -222,7 +222,7 @@ void LLVolumeMgr::useMutex() | |||
222 | { | 222 | { |
223 | if (!mDataMutex) | 223 | if (!mDataMutex) |
224 | { | 224 | { |
225 | mDataMutex = new LLMutex(gAPRPoolp); | 225 | mDataMutex = new LLMutex; |
226 | } | 226 | } |
227 | } | 227 | } |
228 | 228 | ||
diff --git a/linden/indra/llmessage/llares.cpp b/linden/indra/llmessage/llares.cpp index fe37fe8..5a6794e 100644 --- a/linden/indra/llmessage/llares.cpp +++ b/linden/indra/llmessage/llares.cpp | |||
@@ -43,6 +43,7 @@ | |||
43 | 43 | ||
44 | #include "llapr.h" | 44 | #include "llapr.h" |
45 | #include "llares.h" | 45 | #include "llares.h" |
46 | #include "llscopedvolatileaprpool.h" | ||
46 | 47 | ||
47 | #if defined(LL_WINDOWS) | 48 | #if defined(LL_WINDOWS) |
48 | # define ns_c_in 1 | 49 | # define ns_c_in 1 |
@@ -463,11 +464,6 @@ void LLAres::search(const std::string &query, LLResType type, | |||
463 | 464 | ||
464 | bool LLAres::process(U64 timeout) | 465 | bool LLAres::process(U64 timeout) |
465 | { | 466 | { |
466 | if (!gAPRPoolp) | ||
467 | { | ||
468 | ll_init_apr(); | ||
469 | } | ||
470 | |||
471 | int socks[ARES_GETSOCK_MAXNUM]; | 467 | int socks[ARES_GETSOCK_MAXNUM]; |
472 | apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; | 468 | apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM]; |
473 | apr_int32_t nsds = 0; | 469 | apr_int32_t nsds = 0; |
@@ -481,10 +477,7 @@ bool LLAres::process(U64 timeout) | |||
481 | return nsds > 0; | 477 | return nsds > 0; |
482 | } | 478 | } |
483 | 479 | ||
484 | apr_status_t status; | 480 | LLScopedVolatileAPRPool scoped_pool; |
485 | LLAPRPool pool; | ||
486 | status = pool.getStatus() ; | ||
487 | ll_apr_assert_status(status); | ||
488 | 481 | ||
489 | for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) | 482 | for (int i = 0; i < ARES_GETSOCK_MAXNUM; i++) |
490 | { | 483 | { |
@@ -501,7 +494,7 @@ bool LLAres::process(U64 timeout) | |||
501 | 494 | ||
502 | apr_socket_t *aprSock = NULL; | 495 | apr_socket_t *aprSock = NULL; |
503 | 496 | ||
504 | status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], pool.getAPRPool()); | 497 | apr_status_t status = apr_os_sock_put(&aprSock, (apr_os_sock_t *) &socks[i], scoped_pool); |
505 | if (status != APR_SUCCESS) | 498 | if (status != APR_SUCCESS) |
506 | { | 499 | { |
507 | ll_apr_warn_status(status); | 500 | ll_apr_warn_status(status); |
@@ -510,7 +503,7 @@ bool LLAres::process(U64 timeout) | |||
510 | 503 | ||
511 | aprFds[nactive].desc.s = aprSock; | 504 | aprFds[nactive].desc.s = aprSock; |
512 | aprFds[nactive].desc_type = APR_POLL_SOCKET; | 505 | aprFds[nactive].desc_type = APR_POLL_SOCKET; |
513 | aprFds[nactive].p = pool.getAPRPool(); | 506 | aprFds[nactive].p = scoped_pool; |
514 | aprFds[nactive].rtnevents = 0; | 507 | aprFds[nactive].rtnevents = 0; |
515 | aprFds[nactive].client_data = &socks[i]; | 508 | aprFds[nactive].client_data = &socks[i]; |
516 | 509 | ||
@@ -519,7 +512,7 @@ bool LLAres::process(U64 timeout) | |||
519 | 512 | ||
520 | if (nactive > 0) | 513 | if (nactive > 0) |
521 | { | 514 | { |
522 | status = apr_poll(aprFds, nactive, &nsds, timeout); | 515 | apr_status_t status = apr_poll(aprFds, nactive, &nsds, timeout); |
523 | 516 | ||
524 | if (status != APR_SUCCESS && status != APR_TIMEUP) | 517 | if (status != APR_SUCCESS && status != APR_TIMEUP) |
525 | { | 518 | { |
diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp index 202332c..9ecfee4 100644 --- a/linden/indra/llmessage/llcurl.cpp +++ b/linden/indra/llmessage/llcurl.cpp | |||
@@ -1020,7 +1020,7 @@ void LLCurl::initClass() | |||
1020 | S32 mutex_count = CRYPTO_num_locks(); | 1020 | S32 mutex_count = CRYPTO_num_locks(); |
1021 | for (S32 i=0; i<mutex_count; i++) | 1021 | for (S32 i=0; i<mutex_count; i++) |
1022 | { | 1022 | { |
1023 | sSSLMutex.push_back(new LLMutex(NULL)); | 1023 | sSSLMutex.push_back(new LLMutex); |
1024 | } | 1024 | } |
1025 | CRYPTO_set_id_callback(&LLCurl::ssl_thread_id); | 1025 | CRYPTO_set_id_callback(&LLCurl::ssl_thread_id); |
1026 | CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback); | 1026 | CRYPTO_set_locking_callback(&LLCurl::ssl_locking_callback); |
diff --git a/linden/indra/llmessage/lliohttpserver.cpp b/linden/indra/llmessage/lliohttpserver.cpp index 83dfa94..8ad052b 100644 --- a/linden/indra/llmessage/lliohttpserver.cpp +++ b/linden/indra/llmessage/lliohttpserver.cpp | |||
@@ -948,13 +948,9 @@ private: | |||
948 | 948 | ||
949 | 949 | ||
950 | // static | 950 | // static |
951 | LLHTTPNode& LLIOHTTPServer::create( | 951 | LLHTTPNode& LLIOHTTPServer::create(LLPumpIO& pump, U16 port) |
952 | apr_pool_t* pool, LLPumpIO& pump, U16 port) | ||
953 | { | 952 | { |
954 | LLSocket::ptr_t socket = LLSocket::create( | 953 | LLSocket::ptr_t socket = LLSocket::create(LLSocket::STREAM_TCP, port); |
955 | pool, | ||
956 | LLSocket::STREAM_TCP, | ||
957 | port); | ||
958 | if(!socket) | 954 | if(!socket) |
959 | { | 955 | { |
960 | llerrs << "Unable to initialize socket" << llendl; | 956 | llerrs << "Unable to initialize socket" << llendl; |
@@ -963,7 +959,7 @@ LLHTTPNode& LLIOHTTPServer::create( | |||
963 | LLHTTPResponseFactory* factory = new LLHTTPResponseFactory; | 959 | LLHTTPResponseFactory* factory = new LLHTTPResponseFactory; |
964 | boost::shared_ptr<LLChainIOFactory> factory_ptr(factory); | 960 | boost::shared_ptr<LLChainIOFactory> factory_ptr(factory); |
965 | 961 | ||
966 | LLIOServerSocket* server = new LLIOServerSocket(pool, socket, factory_ptr); | 962 | LLIOServerSocket* server = new LLIOServerSocket(socket, factory_ptr); |
967 | 963 | ||
968 | LLPumpIO::chain_t chain; | 964 | LLPumpIO::chain_t chain; |
969 | chain.push_back(LLIOPipe::ptr_t(server)); | 965 | chain.push_back(LLIOPipe::ptr_t(server)); |
diff --git a/linden/indra/llmessage/lliohttpserver.h b/linden/indra/llmessage/lliohttpserver.h index d1c9bdd..d2a8e2a 100644 --- a/linden/indra/llmessage/lliohttpserver.h +++ b/linden/indra/llmessage/lliohttpserver.h | |||
@@ -57,7 +57,7 @@ class LLIOHTTPServer | |||
57 | public: | 57 | public: |
58 | typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); | 58 | typedef void (*timing_callback_t)(const char* hashed_name, F32 time, void* data); |
59 | 59 | ||
60 | static LLHTTPNode& create(apr_pool_t* pool, LLPumpIO& pump, U16 port); | 60 | static LLHTTPNode& create(LLPumpIO& pump, U16 port); |
61 | /**< Creates an HTTP wire server on the pump for the given TCP port. | 61 | /**< Creates an HTTP wire server on the pump for the given TCP port. |
62 | * | 62 | * |
63 | * Returns the root node of the new server. Add LLHTTPNode instances | 63 | * Returns the root node of the new server. Add LLHTTPNode instances |
diff --git a/linden/indra/llmessage/lliosocket.cpp b/linden/indra/llmessage/lliosocket.cpp index 7ec577c..686c037 100644 --- a/linden/indra/llmessage/lliosocket.cpp +++ b/linden/indra/llmessage/lliosocket.cpp | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "llhost.h" | 41 | #include "llhost.h" |
42 | #include "llmemtype.h" | 42 | #include "llmemtype.h" |
43 | #include "llpumpio.h" | 43 | #include "llpumpio.h" |
44 | #include "llthread.h" | ||
44 | 45 | ||
45 | // | 46 | // |
46 | // constants | 47 | // constants |
@@ -104,51 +105,31 @@ void ll_debug_socket(const char* msg, apr_socket_t* apr_sock) | |||
104 | /// | 105 | /// |
105 | 106 | ||
106 | // static | 107 | // static |
107 | LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) | 108 | LLSocket::ptr_t LLSocket::create(EType type, U16 port) |
108 | { | 109 | { |
109 | LLMemType m1(LLMemType::MTYPE_IO_TCP); | 110 | LLMemType m1(LLMemType::MTYPE_IO_TCP); |
110 | LLSocket::ptr_t rv; | ||
111 | apr_socket_t* socket = NULL; | ||
112 | apr_pool_t* new_pool = NULL; | ||
113 | apr_status_t status = APR_EGENERAL; | 111 | apr_status_t status = APR_EGENERAL; |
114 | 112 | LLSocket::ptr_t rv(new LLSocket); | |
115 | // create a pool for the socket | ||
116 | status = apr_pool_create(&new_pool, pool); | ||
117 | if(ll_apr_warn_status(status)) | ||
118 | { | ||
119 | if(new_pool) apr_pool_destroy(new_pool); | ||
120 | return rv; | ||
121 | } | ||
122 | 113 | ||
123 | if(STREAM_TCP == type) | 114 | if(STREAM_TCP == type) |
124 | { | 115 | { |
125 | status = apr_socket_create( | 116 | status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_STREAM, APR_PROTO_TCP, rv->mPool()); |
126 | &socket, | ||
127 | APR_INET, | ||
128 | SOCK_STREAM, | ||
129 | APR_PROTO_TCP, | ||
130 | new_pool); | ||
131 | } | 117 | } |
132 | else if(DATAGRAM_UDP == type) | 118 | else if(DATAGRAM_UDP == type) |
133 | { | 119 | { |
134 | status = apr_socket_create( | 120 | status = apr_socket_create(&rv->mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, rv->mPool()); |
135 | &socket, | ||
136 | APR_INET, | ||
137 | SOCK_DGRAM, | ||
138 | APR_PROTO_UDP, | ||
139 | new_pool); | ||
140 | } | 121 | } |
141 | else | 122 | else |
142 | { | 123 | { |
143 | if(new_pool) apr_pool_destroy(new_pool); | 124 | rv.reset(); |
144 | return rv; | 125 | return rv; |
145 | } | 126 | } |
146 | if(ll_apr_warn_status(status)) | 127 | if(ll_apr_warn_status(status)) |
147 | { | 128 | { |
148 | if(new_pool) apr_pool_destroy(new_pool); | 129 | rv->mSocket = NULL; |
130 | rv.reset(); | ||
149 | return rv; | 131 | return rv; |
150 | } | 132 | } |
151 | rv = ptr_t(new LLSocket(socket, new_pool)); | ||
152 | if(port > 0) | 133 | if(port > 0) |
153 | { | 134 | { |
154 | apr_sockaddr_t* sa = NULL; | 135 | apr_sockaddr_t* sa = NULL; |
@@ -158,7 +139,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) | |||
158 | APR_UNSPEC, | 139 | APR_UNSPEC, |
159 | port, | 140 | port, |
160 | 0, | 141 | 0, |
161 | new_pool); | 142 | rv->mPool()); |
162 | if(ll_apr_warn_status(status)) | 143 | if(ll_apr_warn_status(status)) |
163 | { | 144 | { |
164 | rv.reset(); | 145 | rv.reset(); |
@@ -166,8 +147,8 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) | |||
166 | } | 147 | } |
167 | // This allows us to reuse the address on quick down/up. This | 148 | // This allows us to reuse the address on quick down/up. This |
168 | // is unlikely to create problems. | 149 | // is unlikely to create problems. |
169 | ll_apr_warn_status(apr_socket_opt_set(socket, APR_SO_REUSEADDR, 1)); | 150 | ll_apr_warn_status(apr_socket_opt_set(rv->mSocket, APR_SO_REUSEADDR, 1)); |
170 | status = apr_socket_bind(socket, sa); | 151 | status = apr_socket_bind(rv->mSocket, sa); |
171 | if(ll_apr_warn_status(status)) | 152 | if(ll_apr_warn_status(status)) |
172 | { | 153 | { |
173 | rv.reset(); | 154 | rv.reset(); |
@@ -181,7 +162,7 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) | |||
181 | // to keep a queue of incoming connections for ACCEPT. | 162 | // to keep a queue of incoming connections for ACCEPT. |
182 | lldebugs << "Setting listen state for socket." << llendl; | 163 | lldebugs << "Setting listen state for socket." << llendl; |
183 | status = apr_socket_listen( | 164 | status = apr_socket_listen( |
184 | socket, | 165 | rv->mSocket, |
185 | LL_DEFAULT_LISTEN_BACKLOG); | 166 | LL_DEFAULT_LISTEN_BACKLOG); |
186 | if(ll_apr_warn_status(status)) | 167 | if(ll_apr_warn_status(status)) |
187 | { | 168 | { |
@@ -202,21 +183,28 @@ LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) | |||
202 | } | 183 | } |
203 | 184 | ||
204 | // static | 185 | // static |
205 | LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) | 186 | LLSocket::ptr_t LLSocket::create(apr_status_t& status, LLSocket::ptr_t& listen_socket) |
206 | { | 187 | { |
207 | LLMemType m1(LLMemType::MTYPE_IO_TCP); | 188 | LLMemType m1(LLMemType::MTYPE_IO_TCP); |
208 | LLSocket::ptr_t rv; | 189 | if (!listen_socket->getSocket()) |
209 | if(!socket) | 190 | { |
191 | status = APR_ENOSOCKET; | ||
192 | return LLSocket::ptr_t(); | ||
193 | } | ||
194 | LLSocket::ptr_t rv(new LLSocket); | ||
195 | lldebugs << "accepting socket" << llendl; | ||
196 | status = apr_socket_accept(&rv->mSocket, listen_socket->getSocket(), rv->mPool()); | ||
197 | if (status != APR_SUCCESS) | ||
210 | { | 198 | { |
199 | rv->mSocket = NULL; | ||
200 | rv.reset(); | ||
211 | return rv; | 201 | return rv; |
212 | } | 202 | } |
213 | rv = ptr_t(new LLSocket(socket, pool)); | ||
214 | rv->mPort = PORT_EPHEMERAL; | 203 | rv->mPort = PORT_EPHEMERAL; |
215 | rv->setOptions(); | 204 | rv->setOptions(); |
216 | return rv; | 205 | return rv; |
217 | } | 206 | } |
218 | 207 | ||
219 | |||
220 | bool LLSocket::blockingConnect(const LLHost& host) | 208 | bool LLSocket::blockingConnect(const LLHost& host) |
221 | { | 209 | { |
222 | if(!mSocket) return false; | 210 | if(!mSocket) return false; |
@@ -229,7 +217,7 @@ bool LLSocket::blockingConnect(const LLHost& host) | |||
229 | APR_UNSPEC, | 217 | APR_UNSPEC, |
230 | host.getPort(), | 218 | host.getPort(), |
231 | 0, | 219 | 0, |
232 | mPool))) | 220 | mPool()))) |
233 | { | 221 | { |
234 | return false; | 222 | return false; |
235 | } | 223 | } |
@@ -240,13 +228,11 @@ bool LLSocket::blockingConnect(const LLHost& host) | |||
240 | return true; | 228 | return true; |
241 | } | 229 | } |
242 | 230 | ||
243 | LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : | 231 | LLSocket::LLSocket() : |
244 | mSocket(socket), | 232 | mSocket(NULL), |
245 | mPool(pool), | 233 | mPool(LLThread::tldata().mRootPool), |
246 | mPort(PORT_INVALID) | 234 | mPort(PORT_INVALID) |
247 | { | 235 | { |
248 | ll_debug_socket("Constructing wholely formed socket", mSocket); | ||
249 | LLMemType m1(LLMemType::MTYPE_IO_TCP); | ||
250 | } | 236 | } |
251 | 237 | ||
252 | LLSocket::~LLSocket() | 238 | LLSocket::~LLSocket() |
@@ -258,10 +244,6 @@ LLSocket::~LLSocket() | |||
258 | ll_debug_socket("Destroying socket", mSocket); | 244 | ll_debug_socket("Destroying socket", mSocket); |
259 | apr_socket_close(mSocket); | 245 | apr_socket_close(mSocket); |
260 | } | 246 | } |
261 | if(mPool) | ||
262 | { | ||
263 | apr_pool_destroy(mPool); | ||
264 | } | ||
265 | } | 247 | } |
266 | 248 | ||
267 | void LLSocket::setOptions() | 249 | void LLSocket::setOptions() |
@@ -522,10 +504,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl( | |||
522 | /// | 504 | /// |
523 | 505 | ||
524 | LLIOServerSocket::LLIOServerSocket( | 506 | LLIOServerSocket::LLIOServerSocket( |
525 | apr_pool_t* pool, | ||
526 | LLIOServerSocket::socket_t listener, | 507 | LLIOServerSocket::socket_t listener, |
527 | factory_t factory) : | 508 | factory_t factory) : |
528 | mPool(pool), | ||
529 | mListenSocket(listener), | 509 | mListenSocket(listener), |
530 | mReactor(factory), | 510 | mReactor(factory), |
531 | mInitialized(false), | 511 | mInitialized(false), |
@@ -585,21 +565,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( | |||
585 | lldebugs << "accepting socket" << llendl; | 565 | lldebugs << "accepting socket" << llendl; |
586 | 566 | ||
587 | PUMP_DEBUG; | 567 | PUMP_DEBUG; |
588 | apr_pool_t* new_pool = NULL; | 568 | apr_status_t status; |
589 | apr_status_t status = apr_pool_create(&new_pool, mPool); | 569 | LLSocket::ptr_t llsocket(LLSocket::create(status, mListenSocket)); |
590 | apr_socket_t* socket = NULL; | ||
591 | status = apr_socket_accept( | ||
592 | &socket, | ||
593 | mListenSocket->getSocket(), | ||
594 | new_pool); | ||
595 | LLSocket::ptr_t llsocket(LLSocket::create(socket, new_pool)); | ||
596 | //EStatus rv = STATUS_ERROR; | 570 | //EStatus rv = STATUS_ERROR; |
597 | if(llsocket) | 571 | if(llsocket && status == APR_SUCCESS) |
598 | { | 572 | { |
599 | PUMP_DEBUG; | 573 | PUMP_DEBUG; |
600 | 574 | ||
601 | apr_sockaddr_t* remote_addr; | 575 | apr_sockaddr_t* remote_addr; |
602 | apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); | 576 | apr_socket_addr_get(&remote_addr, APR_REMOTE, llsocket->getSocket()); |
603 | 577 | ||
604 | char* remote_host_string; | 578 | char* remote_host_string; |
605 | apr_sockaddr_ip_get(&remote_host_string, remote_addr); | 579 | apr_sockaddr_ip_get(&remote_host_string, remote_addr); |
@@ -614,7 +588,6 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( | |||
614 | { | 588 | { |
615 | chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); | 589 | chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket))); |
616 | pump->addChain(chain, mResponseTimeout); | 590 | pump->addChain(chain, mResponseTimeout); |
617 | status = STATUS_OK; | ||
618 | } | 591 | } |
619 | else | 592 | else |
620 | { | 593 | { |
@@ -623,7 +596,8 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( | |||
623 | } | 596 | } |
624 | else | 597 | else |
625 | { | 598 | { |
626 | llwarns << "Unable to create linden socket." << llendl; | 599 | char buf[256]; |
600 | llwarns << "Unable to accept linden socket: " << apr_strerror(status, buf, sizeof(buf)) << llendl; | ||
627 | } | 601 | } |
628 | 602 | ||
629 | PUMP_DEBUG; | 603 | PUMP_DEBUG; |
@@ -636,11 +610,10 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl( | |||
636 | #if 0 | 610 | #if 0 |
637 | LLIODataSocket::LLIODataSocket( | 611 | LLIODataSocket::LLIODataSocket( |
638 | U16 suggested_port, | 612 | U16 suggested_port, |
639 | U16 start_discovery_port, | 613 | U16 start_discovery_port) : |
640 | apr_pool_t* pool) : | ||
641 | mSocket(NULL) | 614 | mSocket(NULL) |
642 | { | 615 | { |
643 | if(!pool || (PORT_INVALID == suggested_port)) return; | 616 | if(PORT_INVALID == suggested_port) return; |
644 | if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; | 617 | if(ll_apr_warn_status(apr_socket_create(&mSocket, APR_INET, SOCK_DGRAM, APR_PROTO_UDP, pool))) return; |
645 | apr_sockaddr_t* sa = NULL; | 618 | apr_sockaddr_t* sa = NULL; |
646 | if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; | 619 | if(ll_apr_warn_status(apr_sockaddr_info_get(&sa, APR_ANYADDR, APR_UNSPEC, suggested_port, 0, pool))) return; |
diff --git a/linden/indra/llmessage/lliosocket.h b/linden/indra/llmessage/lliosocket.h index ec09ad8..5ad75e9 100644 --- a/linden/indra/llmessage/lliosocket.h +++ b/linden/indra/llmessage/lliosocket.h | |||
@@ -44,7 +44,6 @@ | |||
44 | */ | 44 | */ |
45 | 45 | ||
46 | #include "lliopipe.h" | 46 | #include "lliopipe.h" |
47 | #include "apr_pools.h" | ||
48 | #include "apr_network_io.h" | 47 | #include "apr_network_io.h" |
49 | #include "llchainio.h" | 48 | #include "llchainio.h" |
50 | 49 | ||
@@ -94,34 +93,22 @@ public: | |||
94 | * socket. If you intend the socket to be known to external | 93 | * socket. If you intend the socket to be known to external |
95 | * clients without prior port notification, do not use | 94 | * clients without prior port notification, do not use |
96 | * PORT_EPHEMERAL. | 95 | * PORT_EPHEMERAL. |
97 | * @param pool The apr pool to use. A child pool will be created | ||
98 | * and associated with the socket. | ||
99 | * @param type The type of socket to create | 96 | * @param type The type of socket to create |
100 | * @param port The port for the socket | 97 | * @param port The port for the socket |
101 | * @return A valid socket shared pointer if the call worked. | 98 | * @return A valid socket shared pointer if the call worked. |
102 | */ | 99 | */ |
103 | static ptr_t create( | 100 | static ptr_t create( |
104 | apr_pool_t* pool, | ||
105 | EType type, | 101 | EType type, |
106 | U16 port = PORT_EPHEMERAL); | 102 | U16 port = PORT_EPHEMERAL); |
107 | 103 | ||
108 | /** | 104 | /** |
109 | * @brief Create a LLSocket when you already have an apr socket. | 105 | * @brief Create a LLSocket by accepting a connection from a listen socket. |
110 | * | 106 | * |
111 | * This method assumes an ephemeral port. This is typically used | 107 | * @param status Output. Status of the accept if a valid listen socket was passed. |
112 | * by calls which spawn a socket such as a call to | 108 | * @param listen_socket The listen socket to use. |
113 | * <code>accept()</code> as in the server socket. This call should | ||
114 | * not fail if you have a valid apr socket. | ||
115 | * Because of the nature of how accept() works, you are expected | ||
116 | * to create a new pool for the socket, use that pool for the | ||
117 | * accept, and pass it in here where it will be bound with the | ||
118 | * socket and destroyed at the same time. | ||
119 | * @param socket The apr socket to use | ||
120 | * @param pool The pool used to create the socket. *NOTE: The pool | ||
121 | * passed in will be DESTROYED. | ||
122 | * @return A valid socket shared pointer if the call worked. | 109 | * @return A valid socket shared pointer if the call worked. |
123 | */ | 110 | */ |
124 | static ptr_t create(apr_socket_t* socket, apr_pool_t* pool); | 111 | static ptr_t create(apr_status_t& status, ptr_t& listen_socket); |
125 | 112 | ||
126 | /** | 113 | /** |
127 | * @brief Perform a blocking connect to a host. Do not use in production. | 114 | * @brief Perform a blocking connect to a host. Do not use in production. |
@@ -156,7 +143,7 @@ protected: | |||
156 | * @brief Protected constructor since should only make sockets | 143 | * @brief Protected constructor since should only make sockets |
157 | * with one of the two <code>create()</code> calls. | 144 | * with one of the two <code>create()</code> calls. |
158 | */ | 145 | */ |
159 | LLSocket(apr_socket_t* socket, apr_pool_t* pool); | 146 | LLSocket(void); |
160 | 147 | ||
161 | /** | 148 | /** |
162 | * @brief Set default socket options. | 149 | * @brief Set default socket options. |
@@ -173,8 +160,8 @@ protected: | |||
173 | // The apr socket. | 160 | // The apr socket. |
174 | apr_socket_t* mSocket; | 161 | apr_socket_t* mSocket; |
175 | 162 | ||
176 | // our memory pool | 163 | // Our memory pool. |
177 | apr_pool_t* mPool; | 164 | AIAPRPool mPool; |
178 | 165 | ||
179 | // The port if we know it. | 166 | // The port if we know it. |
180 | U16 mPort; | 167 | U16 mPort; |
@@ -299,7 +286,7 @@ class LLIOServerSocket : public LLIOPipe | |||
299 | public: | 286 | public: |
300 | typedef LLSocket::ptr_t socket_t; | 287 | typedef LLSocket::ptr_t socket_t; |
301 | typedef boost::shared_ptr<LLChainIOFactory> factory_t; | 288 | typedef boost::shared_ptr<LLChainIOFactory> factory_t; |
302 | LLIOServerSocket(apr_pool_t* pool, socket_t listener, factory_t reactor); | 289 | LLIOServerSocket(socket_t listener, factory_t reactor); |
303 | virtual ~LLIOServerSocket(); | 290 | virtual ~LLIOServerSocket(); |
304 | 291 | ||
305 | /** | 292 | /** |
@@ -331,7 +318,6 @@ protected: | |||
331 | //@} | 318 | //@} |
332 | 319 | ||
333 | protected: | 320 | protected: |
334 | apr_pool_t* mPool; | ||
335 | socket_t mListenSocket; | 321 | socket_t mListenSocket; |
336 | factory_t mReactor; | 322 | factory_t mReactor; |
337 | bool mInitialized; | 323 | bool mInitialized; |
@@ -365,8 +351,7 @@ public: | |||
365 | */ | 351 | */ |
366 | LLIODataSocket( | 352 | LLIODataSocket( |
367 | U16 suggested_port, | 353 | U16 suggested_port, |
368 | U16 start_discovery_port, | 354 | U16 start_discovery_port); |
369 | apr_pool_t* pool); | ||
370 | virtual ~LLIODataSocket(); | 355 | virtual ~LLIODataSocket(); |
371 | 356 | ||
372 | protected: | 357 | protected: |
diff --git a/linden/indra/llmessage/llmail.cpp b/linden/indra/llmessage/llmail.cpp index d52ff6c..8850e29 100644 --- a/linden/indra/llmessage/llmail.cpp +++ b/linden/indra/llmessage/llmail.cpp | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "llstring.h" | 56 | #include "llstring.h" |
57 | #include "lluuid.h" | 57 | #include "lluuid.h" |
58 | #include "net.h" | 58 | #include "net.h" |
59 | #include "aiaprpool.h" | ||
59 | 60 | ||
60 | // | 61 | // |
61 | // constants | 62 | // constants |
@@ -63,7 +64,7 @@ | |||
63 | const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; | 64 | const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; |
64 | 65 | ||
65 | static bool gMailEnabled = true; | 66 | static bool gMailEnabled = true; |
66 | static apr_pool_t* gMailPool; | 67 | static AIAPRPool gMailPool; |
67 | static apr_sockaddr_t* gSockAddr; | 68 | static apr_sockaddr_t* gSockAddr; |
68 | static apr_socket_t* gMailSocket; | 69 | static apr_socket_t* gMailSocket; |
69 | 70 | ||
@@ -88,7 +89,7 @@ bool connect_smtp() | |||
88 | gSockAddr->sa.sin.sin_family, | 89 | gSockAddr->sa.sin.sin_family, |
89 | SOCK_STREAM, | 90 | SOCK_STREAM, |
90 | APR_PROTO_TCP, | 91 | APR_PROTO_TCP, |
91 | gMailPool); | 92 | gMailPool()); |
92 | if(ll_apr_warn_status(status)) return false; | 93 | if(ll_apr_warn_status(status)) return false; |
93 | status = apr_socket_connect(gMailSocket, gSockAddr); | 94 | status = apr_socket_connect(gMailSocket, gSockAddr); |
94 | if(ll_apr_warn_status(status)) | 95 | if(ll_apr_warn_status(status)) |
@@ -145,19 +146,19 @@ BOOL LLMail::send( | |||
145 | } | 146 | } |
146 | 147 | ||
147 | // static | 148 | // static |
148 | void LLMail::init(const std::string& hostname, apr_pool_t* pool) | 149 | void LLMail::init(const std::string& hostname) |
149 | { | 150 | { |
150 | gMailSocket = NULL; | 151 | gMailSocket = NULL; |
151 | if(hostname.empty() || !pool) | 152 | if (hostname.empty()) |
152 | { | 153 | { |
153 | gMailPool = NULL; | ||
154 | gSockAddr = NULL; | 154 | gSockAddr = NULL; |
155 | gMailPool.destroy(); | ||
155 | } | 156 | } |
156 | else | 157 | else |
157 | { | 158 | { |
158 | gMailPool = pool; | 159 | gMailPool.create(); |
159 | 160 | ||
160 | // collect all the information into a socaddr sturcture. the | 161 | // Collect all the information into a sockaddr structure. the |
161 | // documentation is a bit unclear, but I either have to | 162 | // documentation is a bit unclear, but I either have to |
162 | // specify APR_UNSPEC or not specify any flags. I am not sure | 163 | // specify APR_UNSPEC or not specify any flags. I am not sure |
163 | // which option is better. | 164 | // which option is better. |
@@ -167,7 +168,7 @@ void LLMail::init(const std::string& hostname, apr_pool_t* pool) | |||
167 | APR_UNSPEC, | 168 | APR_UNSPEC, |
168 | 25, | 169 | 25, |
169 | APR_IPV4_ADDR_OK, | 170 | APR_IPV4_ADDR_OK, |
170 | gMailPool); | 171 | gMailPool()); |
171 | ll_apr_warn_status(status); | 172 | ll_apr_warn_status(status); |
172 | } | 173 | } |
173 | } | 174 | } |
diff --git a/linden/indra/llmessage/llmail.h b/linden/indra/llmessage/llmail.h index 7effb84..7026d93 100644 --- a/linden/indra/llmessage/llmail.h +++ b/linden/indra/llmessage/llmail.h | |||
@@ -33,15 +33,13 @@ | |||
33 | #ifndef LL_LLMAIL_H | 33 | #ifndef LL_LLMAIL_H |
34 | #define LL_LLMAIL_H | 34 | #define LL_LLMAIL_H |
35 | 35 | ||
36 | typedef struct apr_pool_t apr_pool_t; | ||
37 | |||
38 | #include "llsd.h" | 36 | #include "llsd.h" |
39 | 37 | ||
40 | class LLMail | 38 | class LLMail |
41 | { | 39 | { |
42 | public: | 40 | public: |
43 | // if hostname is NULL, then the host is resolved as 'mail' | 41 | // if hostname is NULL, then the host is resolved as 'mail' |
44 | static void init(const std::string& hostname, apr_pool_t* pool); | 42 | static void init(const std::string& hostname); |
45 | 43 | ||
46 | // Allow all email transmission to be disabled/enabled. | 44 | // Allow all email transmission to be disabled/enabled. |
47 | static void enable(bool mail_enabled); | 45 | static void enable(bool mail_enabled); |
diff --git a/linden/indra/llmessage/llpumpio.cpp b/linden/indra/llmessage/llpumpio.cpp index 8ef2b16..6f10c6b 100644 --- a/linden/indra/llmessage/llpumpio.cpp +++ b/linden/indra/llmessage/llpumpio.cpp | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "llmemtype.h" | 43 | #include "llmemtype.h" |
44 | #include "llstl.h" | 44 | #include "llstl.h" |
45 | #include "llstat.h" | 45 | #include "llstat.h" |
46 | #include "llthread.h" | ||
46 | #include "llfasttimer.h" | 47 | #include "llfasttimer.h" |
47 | 48 | ||
48 | // These should not be enabled in production, but they can be | 49 | // These should not be enabled in production, but they can be |
@@ -169,14 +170,12 @@ struct ll_delete_apr_pollset_fd_client_data | |||
169 | /** | 170 | /** |
170 | * LLPumpIO | 171 | * LLPumpIO |
171 | */ | 172 | */ |
172 | LLPumpIO::LLPumpIO(apr_pool_t* pool) : | 173 | LLPumpIO::LLPumpIO(void) : |
173 | mState(LLPumpIO::NORMAL), | 174 | mState(LLPumpIO::NORMAL), |
174 | mRebuildPollset(false), | 175 | mRebuildPollset(false), |
175 | mPollset(NULL), | 176 | mPollset(NULL), |
176 | mPollsetClientID(0), | 177 | mPollsetClientID(0), |
177 | mNextLock(0), | 178 | mNextLock(0), |
178 | mPool(NULL), | ||
179 | mCurrentPool(NULL), | ||
180 | mCurrentPoolReallocCount(0), | 179 | mCurrentPoolReallocCount(0), |
181 | mChainsMutex(NULL), | 180 | mChainsMutex(NULL), |
182 | mCallbackMutex(NULL), | 181 | mCallbackMutex(NULL), |
@@ -185,21 +184,24 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) : | |||
185 | mCurrentChain = mRunningChains.end(); | 184 | mCurrentChain = mRunningChains.end(); |
186 | 185 | ||
187 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | 186 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); |
188 | initialize(pool); | 187 | initialize(); |
189 | } | 188 | } |
190 | 189 | ||
191 | LLPumpIO::~LLPumpIO() | 190 | LLPumpIO::~LLPumpIO() |
192 | { | 191 | { |
193 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | 192 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); |
194 | cleanup(); | 193 | #if LL_THREADS_APR |
195 | } | 194 | if (mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); |
196 | 195 | if (mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); | |
197 | bool LLPumpIO::prime(apr_pool_t* pool) | 196 | #endif |
198 | { | 197 | mChainsMutex = NULL; |
199 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | 198 | mCallbackMutex = NULL; |
200 | cleanup(); | 199 | if(mPollset) |
201 | initialize(pool); | 200 | { |
202 | return ((pool == NULL) ? false : true); | 201 | // lldebugs << "cleaning up pollset" << llendl; |
202 | apr_pollset_destroy(mPollset); | ||
203 | mPollset = NULL; | ||
204 | } | ||
203 | } | 205 | } |
204 | 206 | ||
205 | bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) | 207 | bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) |
@@ -359,8 +361,7 @@ bool LLPumpIO::setConditional(LLIOPipe* pipe, const apr_pollfd_t* poll) | |||
359 | { | 361 | { |
360 | // each fd needs a pool to work with, so if one was | 362 | // each fd needs a pool to work with, so if one was |
361 | // not specified, use this pool. | 363 | // not specified, use this pool. |
362 | // *FIX: Should it always be this pool? | 364 | value.second.p = (*mCurrentChain).mDescriptorsPool->operator()(); |
363 | value.second.p = mPool; | ||
364 | } | 365 | } |
365 | value.second.client_data = new S32(++mPollsetClientID); | 366 | value.second.client_data = new S32(++mPollsetClientID); |
366 | (*mCurrentChain).mDescriptors.push_back(value); | 367 | (*mCurrentChain).mDescriptors.push_back(value); |
@@ -827,39 +828,15 @@ void LLPumpIO::control(LLPumpIO::EControl op) | |||
827 | } | 828 | } |
828 | } | 829 | } |
829 | 830 | ||
830 | void LLPumpIO::initialize(apr_pool_t* pool) | 831 | void LLPumpIO::initialize(void) |
831 | { | 832 | { |
832 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | 833 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); |
833 | if(!pool) return; | 834 | mPool.create(); |
834 | #if LL_THREADS_APR | 835 | #if LL_THREADS_APR |
835 | // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. | 836 | // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. |
836 | apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); | 837 | apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); |
837 | apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); | 838 | apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, mPool()); |
838 | #endif | ||
839 | mPool = pool; | ||
840 | } | ||
841 | |||
842 | void LLPumpIO::cleanup() | ||
843 | { | ||
844 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | ||
845 | #if LL_THREADS_APR | ||
846 | if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); | ||
847 | if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); | ||
848 | #endif | 839 | #endif |
849 | mChainsMutex = NULL; | ||
850 | mCallbackMutex = NULL; | ||
851 | if(mPollset) | ||
852 | { | ||
853 | // lldebugs << "cleaning up pollset" << llendl; | ||
854 | apr_pollset_destroy(mPollset); | ||
855 | mPollset = NULL; | ||
856 | } | ||
857 | if(mCurrentPool) | ||
858 | { | ||
859 | apr_pool_destroy(mCurrentPool); | ||
860 | mCurrentPool = NULL; | ||
861 | } | ||
862 | mPool = NULL; | ||
863 | } | 840 | } |
864 | 841 | ||
865 | void LLPumpIO::rebuildPollset() | 842 | void LLPumpIO::rebuildPollset() |
@@ -887,21 +864,19 @@ void LLPumpIO::rebuildPollset() | |||
887 | if(mCurrentPool | 864 | if(mCurrentPool |
888 | && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) | 865 | && (0 == (++mCurrentPoolReallocCount % POLLSET_POOL_RECYCLE_COUNT))) |
889 | { | 866 | { |
890 | apr_pool_destroy(mCurrentPool); | 867 | mCurrentPool.destroy(); |
891 | mCurrentPool = NULL; | ||
892 | mCurrentPoolReallocCount = 0; | 868 | mCurrentPoolReallocCount = 0; |
893 | } | 869 | } |
894 | if(!mCurrentPool) | 870 | if(!mCurrentPool) |
895 | { | 871 | { |
896 | apr_status_t status = apr_pool_create(&mCurrentPool, mPool); | 872 | mCurrentPool.create(mPool); |
897 | (void)ll_apr_warn_status(status); | ||
898 | } | 873 | } |
899 | 874 | ||
900 | // add all of the file descriptors | 875 | // add all of the file descriptors |
901 | run_it = mRunningChains.begin(); | 876 | run_it = mRunningChains.begin(); |
902 | LLChainInfo::conditionals_t::iterator fd_it; | 877 | LLChainInfo::conditionals_t::iterator fd_it; |
903 | LLChainInfo::conditionals_t::iterator fd_end; | 878 | LLChainInfo::conditionals_t::iterator fd_end; |
904 | apr_pollset_create(&mPollset, size, mCurrentPool, 0); | 879 | apr_pollset_create(&mPollset, size, mCurrentPool(), 0); |
905 | for(; run_it != run_end; ++run_it) | 880 | for(; run_it != run_end; ++run_it) |
906 | { | 881 | { |
907 | fd_it = (*run_it).mDescriptors.begin(); | 882 | fd_it = (*run_it).mDescriptors.begin(); |
@@ -1159,7 +1134,8 @@ bool LLPumpIO::handleChainError( | |||
1159 | LLPumpIO::LLChainInfo::LLChainInfo() : | 1134 | LLPumpIO::LLChainInfo::LLChainInfo() : |
1160 | mInit(false), | 1135 | mInit(false), |
1161 | mLock(0), | 1136 | mLock(0), |
1162 | mEOS(false) | 1137 | mEOS(false), |
1138 | mDescriptorsPool(new AIAPRPool(LLThread::tldata().mRootPool)) | ||
1163 | { | 1139 | { |
1164 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); | 1140 | LLMemType m1(LLMemType::MTYPE_IO_PUMP); |
1165 | mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); | 1141 | mTimer.setTimerExpirySec(DEFAULT_CHAIN_EXPIRY_SECS); |
diff --git a/linden/indra/llmessage/llpumpio.h b/linden/indra/llmessage/llpumpio.h index fc0bfab..2666be0 100644 --- a/linden/indra/llmessage/llpumpio.h +++ b/linden/indra/llmessage/llpumpio.h | |||
@@ -36,11 +36,12 @@ | |||
36 | #define LL_LLPUMPIO_H | 36 | #define LL_LLPUMPIO_H |
37 | 37 | ||
38 | #include <set> | 38 | #include <set> |
39 | #include <boost/shared_ptr.hpp> | ||
39 | #if LL_LINUX // needed for PATH_MAX in APR. | 40 | #if LL_LINUX // needed for PATH_MAX in APR. |
40 | #include <sys/param.h> | 41 | #include <sys/param.h> |
41 | #endif | 42 | #endif |
42 | 43 | ||
43 | #include "apr_pools.h" | 44 | #include "aiaprpool.h" |
44 | #include "llbuffer.h" | 45 | #include "llbuffer.h" |
45 | #include "llframetimer.h" | 46 | #include "llframetimer.h" |
46 | #include "lliopipe.h" | 47 | #include "lliopipe.h" |
@@ -64,9 +65,8 @@ extern const F32 NEVER_CHAIN_EXPIRY_SECS; | |||
64 | * <code>pump()</code> on a thread used for IO and call | 65 | * <code>pump()</code> on a thread used for IO and call |
65 | * <code>respond()</code> on a thread that is expected to do higher | 66 | * <code>respond()</code> on a thread that is expected to do higher |
66 | * level processing. You can call almost any other method from any | 67 | * level processing. You can call almost any other method from any |
67 | * thread - see notes for each method for details. In order for the | 68 | * thread - see notes for each method for details. |
68 | * threading abstraction to work, you need to call <code>prime()</code> | 69 | * |
69 | * with a valid apr pool. | ||
70 | * A pump instance manages much of the state for the pipe, including | 70 | * A pump instance manages much of the state for the pipe, including |
71 | * the list of pipes in the chain, the channel for each element in the | 71 | * the list of pipes in the chain, the channel for each element in the |
72 | * chain, the buffer, and if any pipe has marked the stream or process | 72 | * chain, the buffer, and if any pipe has marked the stream or process |
@@ -85,7 +85,7 @@ public: | |||
85 | /** | 85 | /** |
86 | * @brief Constructor. | 86 | * @brief Constructor. |
87 | */ | 87 | */ |
88 | LLPumpIO(apr_pool_t* pool); | 88 | LLPumpIO(void); |
89 | 89 | ||
90 | /** | 90 | /** |
91 | * @brief Destructor. | 91 | * @brief Destructor. |
@@ -93,17 +93,6 @@ public: | |||
93 | ~LLPumpIO(); | 93 | ~LLPumpIO(); |
94 | 94 | ||
95 | /** | 95 | /** |
96 | * @brief Prepare this pump for usage. | ||
97 | * | ||
98 | * If you fail to call this method prior to use, the pump will | ||
99 | * try to work, but will not come with any thread locking | ||
100 | * mechanisms. | ||
101 | * @param pool The apr pool to use. | ||
102 | * @return Returns true if the pump is primed. | ||
103 | */ | ||
104 | bool prime(apr_pool_t* pool); | ||
105 | |||
106 | /** | ||
107 | * @brief Typedef for having a chain of pipes. | 96 | * @brief Typedef for having a chain of pipes. |
108 | */ | 97 | */ |
109 | typedef std::vector<LLIOPipe::ptr_t> chain_t; | 98 | typedef std::vector<LLIOPipe::ptr_t> chain_t; |
@@ -374,6 +363,7 @@ protected: | |||
374 | typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; | 363 | typedef std::pair<LLIOPipe::ptr_t, apr_pollfd_t> pipe_conditional_t; |
375 | typedef std::vector<pipe_conditional_t> conditionals_t; | 364 | typedef std::vector<pipe_conditional_t> conditionals_t; |
376 | conditionals_t mDescriptors; | 365 | conditionals_t mDescriptors; |
366 | boost::shared_ptr<AIAPRPool> mDescriptorsPool; | ||
377 | }; | 367 | }; |
378 | 368 | ||
379 | // All the running chains & info | 369 | // All the running chains & info |
@@ -392,9 +382,9 @@ protected: | |||
392 | callbacks_t mPendingCallbacks; | 382 | callbacks_t mPendingCallbacks; |
393 | callbacks_t mCallbacks; | 383 | callbacks_t mCallbacks; |
394 | 384 | ||
395 | // memory allocator for pollsets & mutexes. | 385 | // Memory pool for pollsets & mutexes. |
396 | apr_pool_t* mPool; | 386 | AIAPRPool mPool; |
397 | apr_pool_t* mCurrentPool; | 387 | AIAPRPool mCurrentPool; |
398 | S32 mCurrentPoolReallocCount; | 388 | S32 mCurrentPoolReallocCount; |
399 | 389 | ||
400 | #if LL_THREADS_APR | 390 | #if LL_THREADS_APR |
@@ -406,8 +396,7 @@ protected: | |||
406 | #endif | 396 | #endif |
407 | 397 | ||
408 | protected: | 398 | protected: |
409 | void initialize(apr_pool_t* pool); | 399 | void initialize(); |
410 | void cleanup(); | ||
411 | 400 | ||
412 | /** | 401 | /** |
413 | * @brief Given the internal state of the chains, rebuild the pollset | 402 | * @brief Given the internal state of the chains, rebuild the pollset |
diff --git a/linden/indra/llmessage/llurlrequest.cpp b/linden/indra/llmessage/llurlrequest.cpp index 46e976f..87f0116 100644 --- a/linden/indra/llmessage/llurlrequest.cpp +++ b/linden/indra/llmessage/llurlrequest.cpp | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "llstring.h" | 45 | #include "llstring.h" |
46 | #include "apr_env.h" | 46 | #include "apr_env.h" |
47 | #include "llapr.h" | 47 | #include "llapr.h" |
48 | #include "llscopedvolatileaprpool.h" | ||
48 | static const U32 HTTP_STATUS_PIPE_ERROR = 499; | 49 | static const U32 HTTP_STATUS_PIPE_ERROR = 499; |
49 | 50 | ||
50 | /** | 51 | /** |
@@ -161,27 +162,31 @@ void LLURLRequest::setCallback(LLURLRequestComplete* callback) | |||
161 | // is called with use_proxy = FALSE | 162 | // is called with use_proxy = FALSE |
162 | void LLURLRequest::useProxy(bool use_proxy) | 163 | void LLURLRequest::useProxy(bool use_proxy) |
163 | { | 164 | { |
164 | static char *env_proxy; | 165 | static std::string env_proxy; |
165 | 166 | ||
166 | if (use_proxy && (env_proxy == NULL)) | 167 | if (use_proxy && env_proxy.empty()) |
167 | { | 168 | { |
168 | apr_status_t status; | 169 | char* env_proxy_str; |
169 | LLAPRPool pool; | 170 | LLScopedVolatileAPRPool scoped_pool; |
170 | status = apr_env_get(&env_proxy, "ALL_PROXY", pool.getAPRPool()); | 171 | apr_status_t status = apr_env_get(&env_proxy_str, "ALL_PROXY", scoped_pool); |
171 | if (status != APR_SUCCESS) | 172 | if (status != APR_SUCCESS) |
172 | { | 173 | { |
173 | status = apr_env_get(&env_proxy, "http_proxy", pool.getAPRPool()); | 174 | status = apr_env_get(&env_proxy_str, "http_proxy", scoped_pool); |
174 | } | 175 | } |
175 | if (status != APR_SUCCESS) | 176 | if (status != APR_SUCCESS) |
176 | { | 177 | { |
177 | use_proxy = FALSE; | 178 | use_proxy = false; |
178 | } | 179 | } |
180 | else | ||
181 | { | ||
182 | // env_proxy_str is stored in the scoped_pool, so we have to make a copy. | ||
183 | env_proxy = env_proxy_str; | ||
184 | } | ||
179 | } | 185 | } |
180 | 186 | ||
187 | lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = \"" << env_proxy << "\"" << llendl; | ||
181 | 188 | ||
182 | lldebugs << "use_proxy = " << (use_proxy?'Y':'N') << ", env_proxy = " << (env_proxy ? env_proxy : "(null)") << llendl; | 189 | if (use_proxy) |
183 | |||
184 | if (env_proxy && use_proxy) | ||
185 | { | 190 | { |
186 | mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); | 191 | mDetail->mCurlRequest->setoptString(CURLOPT_PROXY, env_proxy); |
187 | } | 192 | } |
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 7e8aff1..53036bc 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp | |||
@@ -103,8 +103,10 @@ std::string get_shared_secret(); | |||
103 | class LLMessagePollInfo | 103 | class LLMessagePollInfo |
104 | { | 104 | { |
105 | public: | 105 | public: |
106 | LLMessagePollInfo(void) : mPool(LLThread::tldata().mRootPool) { } | ||
106 | apr_socket_t *mAPRSocketp; | 107 | apr_socket_t *mAPRSocketp; |
107 | apr_pollfd_t mPollFD; | 108 | apr_pollfd_t mPollFD; |
109 | AIAPRPool mPool; | ||
108 | }; | 110 | }; |
109 | 111 | ||
110 | namespace | 112 | namespace |
@@ -291,20 +293,13 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, | |||
291 | } | 293 | } |
292 | // LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl; | 294 | // LL_DEBUGS("Messaging") << << "*** port: " << mPort << llendl; |
293 | 295 | ||
294 | // | 296 | mPollInfop = new LLMessagePollInfo; |
295 | // Create the data structure that we can poll on | 297 | |
296 | // | ||
297 | if (!gAPRPoolp) | ||
298 | { | ||
299 | LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl; | ||
300 | ll_init_apr(); | ||
301 | } | ||
302 | apr_socket_t *aprSocketp = NULL; | 298 | apr_socket_t *aprSocketp = NULL; |
303 | apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp); | 299 | apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, mPollInfop->mPool()); |
304 | 300 | ||
305 | mPollInfop = new LLMessagePollInfo; | ||
306 | mPollInfop->mAPRSocketp = aprSocketp; | 301 | mPollInfop->mAPRSocketp = aprSocketp; |
307 | mPollInfop->mPollFD.p = gAPRPoolp; | 302 | mPollInfop->mPollFD.p = mPollInfop->mPool(); |
308 | mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; | 303 | mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET; |
309 | mPollInfop->mPollFD.reqevents = APR_POLLIN; | 304 | mPollInfop->mPollFD.reqevents = APR_POLLIN; |
310 | mPollInfop->mPollFD.rtnevents = 0; | 305 | mPollInfop->mPollFD.rtnevents = 0; |
diff --git a/linden/indra/llplugin/llplugininstance.cpp b/linden/indra/llplugin/llplugininstance.cpp index b822b9e..3a1395c 100755 --- a/linden/indra/llplugin/llplugininstance.cpp +++ b/linden/indra/llplugin/llplugininstance.cpp | |||
@@ -36,8 +36,7 @@ | |||
36 | #include "linden_common.h" | 36 | #include "linden_common.h" |
37 | 37 | ||
38 | #include "llplugininstance.h" | 38 | #include "llplugininstance.h" |
39 | 39 | #include "aiaprpool.h" | |
40 | #include "llapr.h" | ||
41 | 40 | ||
42 | /** Virtual destructor. */ | 41 | /** Virtual destructor. */ |
43 | LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() | 42 | LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() |
@@ -86,7 +85,7 @@ int LLPluginInstance::load(std::string &plugin_file) | |||
86 | 85 | ||
87 | int result = apr_dso_load(&mDSOHandle, | 86 | int result = apr_dso_load(&mDSOHandle, |
88 | plugin_file.c_str(), | 87 | plugin_file.c_str(), |
89 | gAPRPoolp); | 88 | AIAPRRootPool::get()()); |
90 | if(result != APR_SUCCESS) | 89 | if(result != APR_SUCCESS) |
91 | { | 90 | { |
92 | char buf[1024]; | 91 | char buf[1024]; |
diff --git a/linden/indra/llplugin/llpluginmessagepipe.cpp b/linden/indra/llplugin/llpluginmessagepipe.cpp index 8168b32..ebac3c5 100755 --- a/linden/indra/llplugin/llpluginmessagepipe.cpp +++ b/linden/indra/llplugin/llpluginmessagepipe.cpp | |||
@@ -99,8 +99,6 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): | 101 | LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): |
102 | mInputMutex(gAPRPoolp), | ||
103 | mOutputMutex(gAPRPoolp), | ||
104 | mOwner(owner), | 102 | mOwner(owner), |
105 | mSocket(socket) | 103 | mSocket(socket) |
106 | { | 104 | { |
diff --git a/linden/indra/llplugin/llpluginprocesschild.cpp b/linden/indra/llplugin/llpluginprocesschild.cpp index 8dbf2b3..d223823 100755 --- a/linden/indra/llplugin/llpluginprocesschild.cpp +++ b/linden/indra/llplugin/llpluginprocesschild.cpp | |||
@@ -47,7 +47,7 @@ LLPluginProcessChild::LLPluginProcessChild() | |||
47 | { | 47 | { |
48 | mState = STATE_UNINITIALIZED; | 48 | mState = STATE_UNINITIALIZED; |
49 | mInstance = NULL; | 49 | mInstance = NULL; |
50 | mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); | 50 | mSocket = LLSocket::create(LLSocket::STREAM_TCP); |
51 | mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz | 51 | mSleepTime = PLUGIN_IDLE_SECONDS; // default: send idle messages at 100Hz |
52 | mCPUElapsed = 0.0f; | 52 | mCPUElapsed = 0.0f; |
53 | mBlockingRequest = false; | 53 | mBlockingRequest = false; |
diff --git a/linden/indra/llplugin/llpluginprocessparent.cpp b/linden/indra/llplugin/llpluginprocessparent.cpp index 8fd18ef..2cb6b28 100755 --- a/linden/indra/llplugin/llpluginprocessparent.cpp +++ b/linden/indra/llplugin/llpluginprocessparent.cpp | |||
@@ -49,6 +49,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner() | |||
49 | 49 | ||
50 | bool LLPluginProcessParent::sUseReadThread = false; | 50 | bool LLPluginProcessParent::sUseReadThread = false; |
51 | apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; | 51 | apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; |
52 | AIAPRPool LLPluginProcessParent::sPollSetPool; | ||
52 | bool LLPluginProcessParent::sPollsetNeedsRebuild = false; | 53 | bool LLPluginProcessParent::sPollsetNeedsRebuild = false; |
53 | LLMutex *LLPluginProcessParent::sInstancesMutex; | 54 | LLMutex *LLPluginProcessParent::sInstancesMutex; |
54 | std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; | 55 | std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; |
@@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread | |||
59 | { | 60 | { |
60 | public: | 61 | public: |
61 | LLPluginProcessParentPollThread() : | 62 | LLPluginProcessParentPollThread() : |
62 | LLThread("LLPluginProcessParentPollThread", gAPRPoolp) | 63 | LLThread("LLPluginProcessParentPollThread") |
63 | { | 64 | { |
64 | } | 65 | } |
65 | protected: | 66 | protected: |
@@ -84,12 +85,11 @@ protected: | |||
84 | 85 | ||
85 | }; | 86 | }; |
86 | 87 | ||
87 | LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): | 88 | LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) |
88 | mIncomingQueueMutex(gAPRPoolp) | ||
89 | { | 89 | { |
90 | if(!sInstancesMutex) | 90 | if(!sInstancesMutex) |
91 | { | 91 | { |
92 | sInstancesMutex = new LLMutex(gAPRPoolp); | 92 | sInstancesMutex = new LLMutex; |
93 | } | 93 | } |
94 | 94 | ||
95 | mOwner = owner; | 95 | mOwner = owner; |
@@ -102,6 +102,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): | |||
102 | mBlocked = false; | 102 | mBlocked = false; |
103 | mPolledInput = false; | 103 | mPolledInput = false; |
104 | mPollFD.client_data = NULL; | 104 | mPollFD.client_data = NULL; |
105 | mPollFDPool.create(); | ||
105 | 106 | ||
106 | mPluginLaunchTimeout = 60.0f; | 107 | mPluginLaunchTimeout = 60.0f; |
107 | mPluginLockupTimeout = 15.0f; | 108 | mPluginLockupTimeout = 15.0f; |
@@ -177,44 +178,28 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std | |||
177 | bool LLPluginProcessParent::accept() | 178 | bool LLPluginProcessParent::accept() |
178 | { | 179 | { |
179 | bool result = false; | 180 | bool result = false; |
180 | |||
181 | apr_status_t status = APR_EGENERAL; | 181 | apr_status_t status = APR_EGENERAL; |
182 | apr_socket_t *new_socket = NULL; | ||
183 | |||
184 | status = apr_socket_accept( | ||
185 | &new_socket, | ||
186 | mListenSocket->getSocket(), | ||
187 | gAPRPoolp); | ||
188 | 182 | ||
183 | mSocket = LLSocket::create(status, mListenSocket); | ||
189 | 184 | ||
190 | if(status == APR_SUCCESS) | 185 | if(status == APR_SUCCESS) |
191 | { | 186 | { |
192 | // llinfos << "SUCCESS" << llendl; | 187 | // llinfos << "SUCCESS" << llendl; |
193 | // Success. Create a message pipe on the new socket | 188 | // Success. Create a message pipe on the new socket |
194 | |||
195 | // we MUST create a new pool for the LLSocket, since it will take ownership of it and delete it in its destructor! | ||
196 | apr_pool_t* new_pool = NULL; | ||
197 | status = apr_pool_create(&new_pool, gAPRPoolp); | ||
198 | |||
199 | mSocket = LLSocket::create(new_socket, new_pool); | ||
200 | new LLPluginMessagePipe(this, mSocket); | 189 | new LLPluginMessagePipe(this, mSocket); |
201 | 190 | ||
202 | result = true; | 191 | result = true; |
203 | } | 192 | } |
204 | else if(APR_STATUS_IS_EAGAIN(status)) | ||
205 | { | ||
206 | // llinfos << "EAGAIN" << llendl; | ||
207 | |||
208 | // No incoming connections. This is not an error. | ||
209 | status = APR_SUCCESS; | ||
210 | } | ||
211 | else | 193 | else |
212 | { | 194 | { |
213 | // llinfos << "Error:" << llendl; | 195 | mSocket.reset(); |
214 | ll_apr_warn_status(status); | 196 | // EAGAIN means "No incoming connections". This is not an error. |
215 | 197 | if (!APR_STATUS_IS_EAGAIN(status)) | |
216 | // Some other error. | 198 | { |
217 | errorState(); | 199 | // Some other error. |
200 | ll_apr_warn_status(status); | ||
201 | errorState(); | ||
202 | } | ||
218 | } | 203 | } |
219 | 204 | ||
220 | return result; | 205 | return result; |
@@ -283,7 +268,7 @@ void LLPluginProcessParent::idle(void) | |||
283 | 268 | ||
284 | apr_status_t status = APR_SUCCESS; | 269 | apr_status_t status = APR_SUCCESS; |
285 | apr_sockaddr_t* addr = NULL; | 270 | apr_sockaddr_t* addr = NULL; |
286 | mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); | 271 | mListenSocket = LLSocket::create(LLSocket::STREAM_TCP); |
287 | mBoundPort = 0; | 272 | mBoundPort = 0; |
288 | 273 | ||
289 | // This code is based on parts of LLSocket::create() in lliosocket.cpp. | 274 | // This code is based on parts of LLSocket::create() in lliosocket.cpp. |
@@ -294,7 +279,7 @@ void LLPluginProcessParent::idle(void) | |||
294 | APR_INET, | 279 | APR_INET, |
295 | 0, // port 0 = ephemeral ("find me a port") | 280 | 0, // port 0 = ephemeral ("find me a port") |
296 | 0, | 281 | 0, |
297 | gAPRPoolp); | 282 | AIAPRRootPool::get()()); |
298 | 283 | ||
299 | if(ll_apr_warn_status(status)) | 284 | if(ll_apr_warn_status(status)) |
300 | { | 285 | { |
@@ -617,7 +602,8 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe) | |||
617 | if(message_pipe != NULL) | 602 | if(message_pipe != NULL) |
618 | { | 603 | { |
619 | // Set up the apr_pollfd_t | 604 | // Set up the apr_pollfd_t |
620 | mPollFD.p = gAPRPoolp; | 605 | |
606 | mPollFD.p = mPollFDPool(); | ||
621 | mPollFD.desc_type = APR_POLL_SOCKET; | 607 | mPollFD.desc_type = APR_POLL_SOCKET; |
622 | mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; | 608 | mPollFD.reqevents = APR_POLLIN|APR_POLLERR|APR_POLLHUP; |
623 | mPollFD.rtnevents = 0; | 609 | mPollFD.rtnevents = 0; |
@@ -664,6 +650,7 @@ void LLPluginProcessParent::updatePollset() | |||
664 | // delete the existing pollset. | 650 | // delete the existing pollset. |
665 | apr_pollset_destroy(sPollSet); | 651 | apr_pollset_destroy(sPollSet); |
666 | sPollSet = NULL; | 652 | sPollSet = NULL; |
653 | sPollSetPool.destroy(); | ||
667 | } | 654 | } |
668 | 655 | ||
669 | std::list<LLPluginProcessParent*>::iterator iter; | 656 | std::list<LLPluginProcessParent*>::iterator iter; |
@@ -686,12 +673,14 @@ void LLPluginProcessParent::updatePollset() | |||
686 | { | 673 | { |
687 | #ifdef APR_POLLSET_NOCOPY | 674 | #ifdef APR_POLLSET_NOCOPY |
688 | // The pollset doesn't exist yet. Create it now. | 675 | // The pollset doesn't exist yet. Create it now. |
689 | apr_status_t status = apr_pollset_create(&sPollSet, count, gAPRPoolp, APR_POLLSET_NOCOPY); | 676 | sPollSetPool.create(); |
677 | apr_status_t status = apr_pollset_create(&sPollSet, count, sPollSetPool(), APR_POLLSET_NOCOPY); | ||
690 | if(status != APR_SUCCESS) | 678 | if(status != APR_SUCCESS) |
691 | { | 679 | { |
692 | #endif // APR_POLLSET_NOCOPY | 680 | #endif // APR_POLLSET_NOCOPY |
693 | LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; | 681 | LL_WARNS("PluginPoll") << "Couldn't create pollset. Falling back to non-pollset mode." << LL_ENDL; |
694 | sPollSet = NULL; | 682 | sPollSet = NULL; |
683 | sPollSetPool.destroy(); | ||
695 | #ifdef APR_POLLSET_NOCOPY | 684 | #ifdef APR_POLLSET_NOCOPY |
696 | } | 685 | } |
697 | else | 686 | else |
diff --git a/linden/indra/llplugin/llpluginprocessparent.h b/linden/indra/llplugin/llpluginprocessparent.h index 95f5f70..bba3643 100755 --- a/linden/indra/llplugin/llpluginprocessparent.h +++ b/linden/indra/llplugin/llpluginprocessparent.h | |||
@@ -186,7 +186,9 @@ private: | |||
186 | 186 | ||
187 | static bool sUseReadThread; | 187 | static bool sUseReadThread; |
188 | apr_pollfd_t mPollFD; | 188 | apr_pollfd_t mPollFD; |
189 | AIAPRPool mPollFDPool; | ||
189 | static apr_pollset_t *sPollSet; | 190 | static apr_pollset_t *sPollSet; |
191 | static AIAPRPool sPollSetPool; | ||
190 | static bool sPollsetNeedsRebuild; | 192 | static bool sPollsetNeedsRebuild; |
191 | static LLMutex *sInstancesMutex; | 193 | static LLMutex *sInstancesMutex; |
192 | static std::list<LLPluginProcessParent*> sInstances; | 194 | static std::list<LLPluginProcessParent*> sInstances; |
diff --git a/linden/indra/llplugin/llpluginsharedmemory.cpp b/linden/indra/llplugin/llpluginsharedmemory.cpp index e8a411a..883d7b6 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.cpp +++ b/linden/indra/llplugin/llpluginsharedmemory.cpp | |||
@@ -201,7 +201,8 @@ bool LLPluginSharedMemory::create(size_t size) | |||
201 | mName += createName(); | 201 | mName += createName(); |
202 | mSize = size; | 202 | mSize = size; |
203 | 203 | ||
204 | apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), gAPRPoolp ); | 204 | mPool.create(); |
205 | apr_status_t status = apr_shm_create( &(mImpl->mAprSharedMemory), mSize, mName.c_str(), mPool()); | ||
205 | 206 | ||
206 | if(ll_apr_warn_status(status)) | 207 | if(ll_apr_warn_status(status)) |
207 | { | 208 | { |
@@ -224,7 +225,7 @@ bool LLPluginSharedMemory::destroy(void) | |||
224 | } | 225 | } |
225 | mImpl->mAprSharedMemory = NULL; | 226 | mImpl->mAprSharedMemory = NULL; |
226 | } | 227 | } |
227 | 228 | mPool.destroy(); | |
228 | return true; | 229 | return true; |
229 | } | 230 | } |
230 | 231 | ||
@@ -233,7 +234,8 @@ bool LLPluginSharedMemory::attach(const std::string &name, size_t size) | |||
233 | mName = name; | 234 | mName = name; |
234 | mSize = size; | 235 | mSize = size; |
235 | 236 | ||
236 | apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), gAPRPoolp ); | 237 | mPool.create(); |
238 | apr_status_t status = apr_shm_attach( &(mImpl->mAprSharedMemory), mName.c_str(), mPool() ); | ||
237 | 239 | ||
238 | if(ll_apr_warn_status(status)) | 240 | if(ll_apr_warn_status(status)) |
239 | { | 241 | { |
@@ -255,6 +257,7 @@ bool LLPluginSharedMemory::detach(void) | |||
255 | } | 257 | } |
256 | mImpl->mAprSharedMemory = NULL; | 258 | mImpl->mAprSharedMemory = NULL; |
257 | } | 259 | } |
260 | mPool.destroy(); | ||
258 | 261 | ||
259 | return true; | 262 | return true; |
260 | } | 263 | } |
diff --git a/linden/indra/llplugin/llpluginsharedmemory.h b/linden/indra/llplugin/llpluginsharedmemory.h index 081d311..669a3e4 100755 --- a/linden/indra/llplugin/llpluginsharedmemory.h +++ b/linden/indra/llplugin/llpluginsharedmemory.h | |||
@@ -35,6 +35,8 @@ | |||
35 | #ifndef LL_LLPLUGINSHAREDMEMORY_H | 35 | #ifndef LL_LLPLUGINSHAREDMEMORY_H |
36 | #define LL_LLPLUGINSHAREDMEMORY_H | 36 | #define LL_LLPLUGINSHAREDMEMORY_H |
37 | 37 | ||
38 | #include "aiaprpool.h" | ||
39 | |||
38 | class LLPluginSharedMemoryPlatformImpl; | 40 | class LLPluginSharedMemoryPlatformImpl; |
39 | 41 | ||
40 | /** | 42 | /** |
@@ -115,6 +117,7 @@ private: | |||
115 | bool close(void); | 117 | bool close(void); |
116 | bool unlink(void); | 118 | bool unlink(void); |
117 | 119 | ||
120 | AIAPRPool mPool; | ||
118 | std::string mName; | 121 | std::string mName; |
119 | size_t mSize; | 122 | size_t mSize; |
120 | void *mMappedAddress; | 123 | void *mMappedAddress; |
diff --git a/linden/indra/llplugin/slplugin/slplugin.cpp b/linden/indra/llplugin/slplugin/slplugin.cpp index 64c087b..cca8ead 100755 --- a/linden/indra/llplugin/slplugin/slplugin.cpp +++ b/linden/indra/llplugin/slplugin/slplugin.cpp | |||
@@ -183,8 +183,6 @@ int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdL | |||
183 | int main(int argc, char **argv) | 183 | int main(int argc, char **argv) |
184 | #endif | 184 | #endif |
185 | { | 185 | { |
186 | ll_init_apr(); | ||
187 | |||
188 | // Set up llerror logging | 186 | // Set up llerror logging |
189 | { | 187 | { |
190 | LLError::initForApplication("."); | 188 | LLError::initForApplication("."); |
@@ -400,8 +398,6 @@ int main(int argc, char **argv) | |||
400 | 398 | ||
401 | delete plugin; | 399 | delete plugin; |
402 | 400 | ||
403 | ll_cleanup_apr(); | ||
404 | |||
405 | return 0; | 401 | return 0; |
406 | } | 402 | } |
407 | 403 | ||
diff --git a/linden/indra/llvfs/llvfs.cpp b/linden/indra/llvfs/llvfs.cpp index dea8c9c..654dfa1 100644 --- a/linden/indra/llvfs/llvfs.cpp +++ b/linden/indra/llvfs/llvfs.cpp | |||
@@ -237,7 +237,7 @@ const S32 LLVFSFileBlock::SERIAL_SIZE = 34; | |||
237 | LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) | 237 | LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) |
238 | : mRemoveAfterCrash(remove_after_crash) | 238 | : mRemoveAfterCrash(remove_after_crash) |
239 | { | 239 | { |
240 | mDataMutex = new LLMutex(0); | 240 | mDataMutex = new LLMutex; |
241 | 241 | ||
242 | S32 i; | 242 | S32 i; |
243 | for (i = 0; i < VFSLOCK_COUNT; i++) | 243 | for (i = 0; i < VFSLOCK_COUNT; i++) |
diff --git a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp index c4c4181..cc3836e 100644 --- a/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp +++ b/linden/indra/media_plugins/webkit/linux_volume_catcher.cpp | |||
@@ -58,7 +58,7 @@ extern "C" { | |||
58 | #include <pulse/subscribe.h> | 58 | #include <pulse/subscribe.h> |
59 | #include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. | 59 | #include <pulse/glib-mainloop.h> // There's no special reason why we want the *glib* PA mainloop, but the generic polling implementation seems broken. |
60 | 60 | ||
61 | #include "apr_pools.h" | 61 | #include "aiaprpool.h" |
62 | #include "apr_dso.h" | 62 | #include "apr_dso.h" |
63 | } | 63 | } |
64 | 64 | ||
@@ -74,7 +74,7 @@ extern "C" { | |||
74 | #undef LL_PA_SYM | 74 | #undef LL_PA_SYM |
75 | 75 | ||
76 | static bool sSymsGrabbed = false; | 76 | static bool sSymsGrabbed = false; |
77 | static apr_pool_t *sSymPADSOMemoryPool = NULL; | 77 | static AIAPRPool sSymPADSOMemoryPool; |
78 | static apr_dso_handle_t *sSymPADSOHandleG = NULL; | 78 | static apr_dso_handle_t *sSymPADSOHandleG = NULL; |
79 | 79 | ||
80 | bool grab_pa_syms(std::string pulse_dso_name) | 80 | bool grab_pa_syms(std::string pulse_dso_name) |
@@ -93,11 +93,11 @@ bool grab_pa_syms(std::string pulse_dso_name) | |||
93 | #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) | 93 | #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll##PASYM, sSymPADSOHandle, #PASYM); if (rv != APR_SUCCESS) {INFOMSG("Failed to grab symbol: %s", #PASYM); if (REQUIRED) sym_error = true;} else DEBUGMSG("grabbed symbol: %s from %p", #PASYM, (void*)ll##PASYM);}while(0) |
94 | 94 | ||
95 | //attempt to load the shared library | 95 | //attempt to load the shared library |
96 | apr_pool_create(&sSymPADSOMemoryPool, NULL); | 96 | sSymPADSOMemoryPool.create(); |
97 | 97 | ||
98 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, | 98 | if ( APR_SUCCESS == (rv = apr_dso_load(&sSymPADSOHandle, |
99 | pulse_dso_name.c_str(), | 99 | pulse_dso_name.c_str(), |
100 | sSymPADSOMemoryPool) )) | 100 | sSymPADSOMemoryPool()) )) |
101 | { | 101 | { |
102 | INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); | 102 | INFOMSG("Found DSO: %s", pulse_dso_name.c_str()); |
103 | 103 | ||
@@ -140,11 +140,7 @@ void ungrab_pa_syms() | |||
140 | sSymPADSOHandleG = NULL; | 140 | sSymPADSOHandleG = NULL; |
141 | } | 141 | } |
142 | 142 | ||
143 | if ( sSymPADSOMemoryPool ) | 143 | sSymPADSOMemoryPool.destroy(); |
144 | { | ||
145 | apr_pool_destroy(sSymPADSOMemoryPool); | ||
146 | sSymPADSOMemoryPool = NULL; | ||
147 | } | ||
148 | 144 | ||
149 | // NULL-out all of the symbols we'd grabbed | 145 | // NULL-out all of the symbols we'd grabbed |
150 | #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) | 146 | #define LL_PA_SYM(REQUIRED, PASYM, RTN, ...) do{ll##PASYM = NULL;}while(0) |
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 8aea221..aaae4d2 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp | |||
@@ -920,7 +920,7 @@ bool LLAppViewer::mainLoop() | |||
920 | //------------------------------------------- | 920 | //------------------------------------------- |
921 | 921 | ||
922 | // Create IO Pump to use for HTTP Requests. | 922 | // Create IO Pump to use for HTTP Requests. |
923 | gServicePump = new LLPumpIO(gAPRPoolp); | 923 | gServicePump = new LLPumpIO; |
924 | LLHTTPClient::setPump(*gServicePump); | 924 | LLHTTPClient::setPump(*gServicePump); |
925 | LLCurl::setCAFile(gDirUtilp->getCAFile()); | 925 | LLCurl::setCAFile(gDirUtilp->getCAFile()); |
926 | 926 | ||
diff --git a/linden/indra/newview/llappviewerlinux.cpp b/linden/indra/newview/llappviewerlinux.cpp index 307f925..88ddf7e 100644 --- a/linden/indra/newview/llappviewerlinux.cpp +++ b/linden/indra/newview/llappviewerlinux.cpp | |||
@@ -129,6 +129,7 @@ int main( int argc, char **argv ) | |||
129 | } | 129 | } |
130 | delete viewer_app_ptr; | 130 | delete viewer_app_ptr; |
131 | viewer_app_ptr = NULL; | 131 | viewer_app_ptr = NULL; |
132 | |||
132 | return 0; | 133 | return 0; |
133 | } | 134 | } |
134 | 135 | ||
diff --git a/linden/indra/newview/llappviewermacosx.cpp b/linden/indra/newview/llappviewermacosx.cpp index 91de066..d81b6e3 100644 --- a/linden/indra/newview/llappviewermacosx.cpp +++ b/linden/indra/newview/llappviewermacosx.cpp | |||
@@ -119,6 +119,7 @@ int main( int argc, char **argv ) | |||
119 | } | 119 | } |
120 | delete viewer_app_ptr; | 120 | delete viewer_app_ptr; |
121 | viewer_app_ptr = NULL; | 121 | viewer_app_ptr = NULL; |
122 | |||
122 | return 0; | 123 | return 0; |
123 | } | 124 | } |
124 | 125 | ||
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index a1a9a39..2b032a5 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp | |||
@@ -736,9 +736,6 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted) | |||
736 | 736 | ||
737 | LLTextureCache::LLTextureCache(bool threaded) | 737 | LLTextureCache::LLTextureCache(bool threaded) |
738 | : LLWorkerThread("TextureCache", threaded), | 738 | : LLWorkerThread("TextureCache", threaded), |
739 | mWorkersMutex(NULL), | ||
740 | mHeaderMutex(NULL), | ||
741 | mListMutex(NULL), | ||
742 | mHeaderAPRFile(NULL), | 739 | mHeaderAPRFile(NULL), |
743 | mReadOnly(FALSE), | 740 | mReadOnly(FALSE), |
744 | mTexturesSizeTotal(0), | 741 | mTexturesSizeTotal(0), |
@@ -1541,7 +1538,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort) | |||
1541 | } | 1538 | } |
1542 | } | 1539 | } |
1543 | 1540 | ||
1544 | unlockWorkers(); | 1541 | unlockWorkers(); |
1545 | 1542 | ||
1546 | if (delete_worker) worker->scheduleDelete(); | 1543 | if (delete_worker) worker->scheduleDelete(); |
1547 | 1544 | ||
diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h index c859b9a..56b4c4f 100644 --- a/linden/indra/newview/lltexturecache.h +++ b/linden/indra/newview/lltexturecache.h | |||
@@ -139,9 +139,6 @@ protected: | |||
139 | std::string getTextureFileName(const LLUUID& id); | 139 | std::string getTextureFileName(const LLUUID& id); |
140 | void addCompleted(Responder* responder, bool success); | 140 | void addCompleted(Responder* responder, bool success); |
141 | 141 | ||
142 | protected: | ||
143 | //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; } | ||
144 | |||
145 | private: | 142 | private: |
146 | void setDirNames(ELLPath location); | 143 | void setDirNames(ELLPath location); |
147 | void readHeaderCache(); | 144 | void readHeaderCache(); |
diff --git a/linden/indra/newview/lltexturefetch.cpp b/linden/indra/newview/lltexturefetch.cpp index f93a574..072af25 100644 --- a/linden/indra/newview/lltexturefetch.cpp +++ b/linden/indra/newview/lltexturefetch.cpp | |||
@@ -428,7 +428,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, | |||
428 | mRetryAttempt(0), | 428 | mRetryAttempt(0), |
429 | mActiveCount(0), | 429 | mActiveCount(0), |
430 | mGetStatus(0), | 430 | mGetStatus(0), |
431 | mWorkMutex(NULL), | ||
432 | mFirstPacket(0), | 431 | mFirstPacket(0), |
433 | mLastPacket(-1), | 432 | mLastPacket(-1), |
434 | mTotalPackets(0), | 433 | mTotalPackets(0), |
@@ -1540,8 +1539,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image | |||
1540 | mDebugPause(FALSE), | 1539 | mDebugPause(FALSE), |
1541 | mPacketCount(0), | 1540 | mPacketCount(0), |
1542 | mBadPacketCount(0), | 1541 | mBadPacketCount(0), |
1543 | mQueueMutex(getAPRPool()), | ||
1544 | mNetworkQueueMutex(getAPRPool()), | ||
1545 | mTextureCache(cache), | 1542 | mTextureCache(cache), |
1546 | mImageDecodeThread(imagedecodethread), | 1543 | mImageDecodeThread(imagedecodethread), |
1547 | mTextureBandwidth(0), | 1544 | mTextureBandwidth(0), |
diff --git a/linden/indra/newview/llviewerprecompiledheaders.h b/linden/indra/newview/llviewerprecompiledheaders.h index 9bc6574..a0b99bf 100644 --- a/linden/indra/newview/llviewerprecompiledheaders.h +++ b/linden/indra/newview/llviewerprecompiledheaders.h | |||
@@ -165,7 +165,7 @@ | |||
165 | #include "llinstantmessage.h" | 165 | #include "llinstantmessage.h" |
166 | #include "llinvite.h" | 166 | #include "llinvite.h" |
167 | //#include "llloginflags.h" | 167 | //#include "llloginflags.h" |
168 | #include "llmail.h" | 168 | //#include "llmail.h" |
169 | #include "llmessagethrottle.h" | 169 | #include "llmessagethrottle.h" |
170 | #include "llnamevalue.h" | 170 | #include "llnamevalue.h" |
171 | #include "llpacketack.h" | 171 | #include "llpacketack.h" |
diff --git a/linden/indra/newview/llvoiceclient.cpp b/linden/indra/newview/llvoiceclient.cpp index d67b9e3..7b1ed95 100644 --- a/linden/indra/newview/llvoiceclient.cpp +++ b/linden/indra/newview/llvoiceclient.cpp | |||
@@ -1795,7 +1795,7 @@ void LLVoiceClient::stateMachine() | |||
1795 | 1795 | ||
1796 | if(!mSocket) | 1796 | if(!mSocket) |
1797 | { | 1797 | { |
1798 | mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP); | 1798 | mSocket = LLSocket::create(LLSocket::STREAM_TCP); |
1799 | } | 1799 | } |
1800 | 1800 | ||
1801 | mConnected = mSocket->blockingConnect(mDaemonHost); | 1801 | mConnected = mSocket->blockingConnect(mDaemonHost); |
diff --git a/linden/indra/newview/llwatchdog.cpp b/linden/indra/newview/llwatchdog.cpp index 330bc8a..9af050c 100644 --- a/linden/indra/newview/llwatchdog.cpp +++ b/linden/indra/newview/llwatchdog.cpp | |||
@@ -184,8 +184,8 @@ void LLWatchdog::init(killer_event_callback func) | |||
184 | mKillerCallback = func; | 184 | mKillerCallback = func; |
185 | if(!mSuspectsAccessMutex && !mTimer) | 185 | if(!mSuspectsAccessMutex && !mTimer) |
186 | { | 186 | { |
187 | mSuspectsAccessMutex = new LLMutex(NULL); | 187 | mSuspectsAccessMutex = new LLMutex; |
188 | mTimer = new LLWatchdogTimerThread(); | 188 | mTimer = new LLWatchdogTimerThread; |
189 | mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); | 189 | mTimer->setSleepTime(WATCHDOG_SLEEP_TIME_USEC / 1000); |
190 | mLastClockCount = LLTimer::getTotalTime(); | 190 | mLastClockCount = LLTimer::getTotalTime(); |
191 | 191 | ||
diff --git a/linden/indra/test/lltemplatemessagebuilder_tut.cpp b/linden/indra/test/lltemplatemessagebuilder_tut.cpp index 5b33d02..9fecc2f 100644 --- a/linden/indra/test/lltemplatemessagebuilder_tut.cpp +++ b/linden/indra/test/lltemplatemessagebuilder_tut.cpp | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "linden_common.h" | 35 | #include "linden_common.h" |
36 | #include "lltut.h" | 36 | #include "lltut.h" |
37 | 37 | ||
38 | #include "llapr.h" | ||
39 | #include "llmessagetemplate.h" | 38 | #include "llmessagetemplate.h" |
40 | #include "llquaternion.h" | 39 | #include "llquaternion.h" |
41 | #include "lltemplatemessagebuilder.h" | 40 | #include "lltemplatemessagebuilder.h" |
@@ -59,7 +58,6 @@ namespace tut | |||
59 | static bool init = false; | 58 | static bool init = false; |
60 | if(! init) | 59 | if(! init) |
61 | { | 60 | { |
62 | ll_init_apr(); | ||
63 | const F32 circuit_heartbeat_interval=5; | 61 | const F32 circuit_heartbeat_interval=5; |
64 | const F32 circuit_timeout=100; | 62 | const F32 circuit_timeout=100; |
65 | 63 | ||
diff --git a/linden/indra/test/message_tut.cpp b/linden/indra/test/message_tut.cpp index 3fede26..694db52 100644 --- a/linden/indra/test/message_tut.cpp +++ b/linden/indra/test/message_tut.cpp | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "linden_common.h" | 35 | #include "linden_common.h" |
36 | #include "lltut.h" | 36 | #include "lltut.h" |
37 | 37 | ||
38 | #include "llapr.h" | ||
39 | #include "llmessageconfig.h" | 38 | #include "llmessageconfig.h" |
40 | #include "llsdserialize.h" | 39 | #include "llsdserialize.h" |
41 | #include "llversionserver.h" | 40 | #include "llversionserver.h" |
@@ -68,7 +67,6 @@ namespace tut | |||
68 | static bool init = false; | 67 | static bool init = false; |
69 | if(!init) | 68 | if(!init) |
70 | { | 69 | { |
71 | ll_init_apr(); | ||
72 | //init_prehash_data(); | 70 | //init_prehash_data(); |
73 | init = true; | 71 | init = true; |
74 | } | 72 | } |
diff --git a/linden/indra/test/test.cpp b/linden/indra/test/test.cpp index ba81c6e..b699f74 100644 --- a/linden/indra/test/test.cpp +++ b/linden/indra/test/test.cpp | |||
@@ -43,8 +43,8 @@ | |||
43 | #include "linden_common.h" | 43 | #include "linden_common.h" |
44 | #include "llerrorcontrol.h" | 44 | #include "llerrorcontrol.h" |
45 | #include "lltut.h" | 45 | #include "lltut.h" |
46 | #include "aiaprpool.h" | ||
46 | 47 | ||
47 | #include "apr_pools.h" | ||
48 | #include "apr_getopt.h" | 48 | #include "apr_getopt.h" |
49 | 49 | ||
50 | // the CTYPE_WORKAROUND is needed for linux dev stations that don't | 50 | // the CTYPE_WORKAROUND is needed for linux dev stations that don't |
@@ -248,17 +248,12 @@ int main(int argc, char **argv) | |||
248 | ctype_workaround(); | 248 | ctype_workaround(); |
249 | #endif | 249 | #endif |
250 | 250 | ||
251 | apr_initialize(); | 251 | LLAPRPool pool; |
252 | apr_pool_t* pool = NULL; | 252 | pool.create(); |
253 | if(APR_SUCCESS != apr_pool_create(&pool, NULL)) | ||
254 | { | ||
255 | std::cerr << "Unable to initialize pool" << std::endl; | ||
256 | return 1; | ||
257 | } | ||
258 | apr_getopt_t* os = NULL; | 253 | apr_getopt_t* os = NULL; |
259 | if(APR_SUCCESS != apr_getopt_init(&os, pool, argc, argv)) | 254 | if(APR_SUCCESS != apr_getopt_init(&os, pool(), argc, argv)) |
260 | { | 255 | { |
261 | std::cerr << "Unable to pool" << std::endl; | 256 | std::cerr << "Unable to initialize the arguments for parsing by apr_getopt()." << std::endl; |
262 | return 1; | 257 | return 1; |
263 | } | 258 | } |
264 | 259 | ||
@@ -360,6 +355,5 @@ int main(int argc, char **argv) | |||
360 | s.close(); | 355 | s.close(); |
361 | } | 356 | } |
362 | 357 | ||
363 | apr_terminate(); | ||
364 | return 0; | 358 | return 0; |
365 | } | 359 | } |