aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/doc/contributions.txt1
-rw-r--r--linden/indra/llcommon/CMakeLists.txt3
-rw-r--r--linden/indra/llcommon/aiaprpool.cpp198
-rw-r--r--linden/indra/llcommon/aiaprpool.h236
-rw-r--r--linden/indra/llcommon/llapp.cpp5
-rw-r--r--linden/indra/llcommon/llapr.cpp299
-rw-r--r--linden/indra/llcommon/llapr.h74
-rw-r--r--linden/indra/llcommon/llcommon.cpp13
-rw-r--r--linden/indra/llcommon/llcommon.h2
-rw-r--r--linden/indra/llcommon/llerror.cpp3
-rw-r--r--linden/indra/llcommon/llfixedbuffer.cpp3
-rw-r--r--linden/indra/llcommon/llscopedvolatileaprpool.h58
-rw-r--r--linden/indra/llcommon/llthread.cpp117
-rw-r--r--linden/indra/llcommon/llthread.h88
-rw-r--r--linden/indra/llcommon/llworkerthread.cpp3
-rw-r--r--linden/indra/llcommon/llworkerthread.h2
-rwxr-xr-xlinden/indra/llcrashlogger/llcrashlogger.cpp3
-rw-r--r--linden/indra/llimage/llimage.cpp2
-rw-r--r--linden/indra/llimage/llimagej2c.cpp15
-rw-r--r--linden/indra/llimage/llimageworker.cpp7
-rw-r--r--linden/indra/llimage/llimageworker.h2
-rw-r--r--linden/indra/llmath/llvolumemgr.cpp4
-rw-r--r--linden/indra/llmessage/llares.cpp17
-rw-r--r--linden/indra/llmessage/llcurl.cpp2
-rw-r--r--linden/indra/llmessage/lliohttpserver.cpp10
-rw-r--r--linden/indra/llmessage/lliohttpserver.h2
-rw-r--r--linden/indra/llmessage/lliosocket.cpp99
-rw-r--r--linden/indra/llmessage/lliosocket.h33
-rw-r--r--linden/indra/llmessage/llmail.cpp17
-rw-r--r--linden/indra/llmessage/llmail.h4
-rw-r--r--linden/indra/llmessage/llpumpio.cpp74
-rw-r--r--linden/indra/llmessage/llpumpio.h31
-rw-r--r--linden/indra/llmessage/llurlrequest.cpp25
-rw-r--r--linden/indra/llmessage/message.cpp17
-rwxr-xr-xlinden/indra/llplugin/llplugininstance.cpp5
-rwxr-xr-xlinden/indra/llplugin/llpluginmessagepipe.cpp2
-rwxr-xr-xlinden/indra/llplugin/llpluginprocesschild.cpp2
-rwxr-xr-xlinden/indra/llplugin/llpluginprocessparent.cpp55
-rwxr-xr-xlinden/indra/llplugin/llpluginprocessparent.h2
-rwxr-xr-xlinden/indra/llplugin/llpluginsharedmemory.cpp9
-rwxr-xr-xlinden/indra/llplugin/llpluginsharedmemory.h3
-rwxr-xr-xlinden/indra/llplugin/slplugin/slplugin.cpp4
-rw-r--r--linden/indra/llvfs/llvfs.cpp2
-rw-r--r--linden/indra/media_plugins/webkit/linux_volume_catcher.cpp14
-rw-r--r--linden/indra/newview/llappviewer.cpp2
-rw-r--r--linden/indra/newview/llappviewerlinux.cpp1
-rw-r--r--linden/indra/newview/llappviewermacosx.cpp1
-rw-r--r--linden/indra/newview/lltexturecache.cpp5
-rw-r--r--linden/indra/newview/lltexturecache.h3
-rw-r--r--linden/indra/newview/lltexturefetch.cpp3
-rw-r--r--linden/indra/newview/llviewerprecompiledheaders.h2
-rw-r--r--linden/indra/newview/llvoiceclient.cpp2
-rw-r--r--linden/indra/newview/llwatchdog.cpp4
-rw-r--r--linden/indra/test/lltemplatemessagebuilder_tut.cpp2
-rw-r--r--linden/indra/test/message_tut.cpp2
-rw-r--r--linden/indra/test/test.cpp16
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
15set(llcommon_SOURCE_FILES 15set(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
74set(llcommon_HEADER_FILES 75set(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.
43void 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.
75void 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
95bool AIAPRPool::parent_is_being_destructed(void)
96{
97 return mParent && (!mParent->mPool || mParent->parent_is_being_destructed());
98}
99
100AIAPRInitialization::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
112bool AIAPRRootPool::sCountInitialized = false;
113apr_uint32_t volatile AIAPRRootPool::sCount;
114
115extern apr_thread_mutex_t* gLogMutexp;
116extern apr_thread_mutex_t* gCallStacksLogMutexp;
117
118AIAPRRootPool::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
140AIAPRRootPool::~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
172AIAPRRootPool& AIAPRRootPool::get(void)
173{
174 static AIAPRRootPool global_APRpool(0); // This is what used to be gAPRPoolp.
175 return global_APRpool;
176}
177
178void 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
48extern 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 */
56class LL_COMMON_API AIAPRPool
57{
58protected:
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
63public:
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
74protected:
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
84public:
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
134private:
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
151class AIAPRInitialization
152{
153public:
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 */
163class LL_COMMON_API AIAPRRootPool : public AIAPRInitialization, public AIAPRPool
164{
165private:
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
174private:
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
179public:
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
194private:
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//
211class LL_COMMON_API AIVolatileAPRPool : protected AIAPRPool
212{
213public:
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
228private:
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
131LLApp::LLApp(LLErrorThread *error_thread) : 126LLApp::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"
38apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
39apr_thread_mutex_t *gLogMutexp = NULL;
40apr_thread_mutex_t *gCallStacksLogMutexp = NULL;
41
42const S32 FULL_VOLATILE_APR_POOL = 1024 ; //number of references to LLVolatileAPRPool
43
44void 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
62void 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//
94LLAPRPool::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
104LLAPRPool::~LLAPRPool()
105{
106 releaseAPRPool() ;
107}
108
109void 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
129void 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
143apr_pool_t* LLAPRPool::getAPRPool()
144{
145 if(!mPool)
146 {
147 createAPRPool() ;
148 }
149
150 return mPool ;
151}
152LLVolatileAPRPool::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
159apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool()
160{
161 mNumTotalRef++ ;
162 mNumActiveRef++ ;
163 return getAPRPool() ;
164}
165
166void 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
198BOOL 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.
205static void* gIsMainThread;
206bool is_main_thread() { return gIsMainThread == LLVolatileAPRPool::getLocalAPRFilePool(); }
207#endif
208
209// The thread private handle to access the LocalAPRFilePool.
210apr_threadkey_t* LLVolatileAPRPool::sLocalAPRFilePoolKey;
211
212// This should be called exactly once, before the first call to createLocalAPRFilePool.
213// static
214void 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
229void 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
238void LLVolatileAPRPool::destroyLocalAPRFilePool(void* thread_local_data)
239{
240 delete reinterpret_cast<LLVolatileAPRPool*>(thread_local_data);
241}
242
243// static
244LLVolatileAPRPool* 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//
311LLAPRFile::LLAPRFile() 98LLAPRFile::LLAPRFile()
312 : mFile(NULL), 99 : mFile(NULL),
313 mCurrentFilePoolp(NULL) 100 mVolatileFilePoolp(NULL),
101 mRegularFilePoolp(NULL)
314{ 102{
315} 103}
316 104
317LLAPRFile::LLAPRFile(const std::string& filename, apr_int32_t flags, access_t access_type) 105LLAPRFile::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()
347apr_status_t LLAPRFile::open(std::string const& filename, apr_int32_t flags, access_t access_type, S32* sizep) 142apr_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.
444class LLScopedVolatileAPRFilePool {
445private:
446 LLVolatileAPRPool* mPool;
447 apr_pool_t* apr_pool;
448public:
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
455S32 LLAPRFile::seek(apr_file_t* file_handle, apr_seek_where_t where, S32 offset) 242S32 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)
487S32 LLAPRFile::readEx(const std::string& filename, void *buf, S32 offset, S32 nbytes) 274S32 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
51extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp; 51class AIAPRPool;
52 52class AIVolatileAPRPool;
53/**
54 * @brief initialize the common apr constructs -- apr itself, the
55 * global pool, and a mutex.
56 */
57void LL_COMMON_API ll_init_apr();
58
59/**
60 * @brief Cleanup those common apr constructs.
61 */
62void 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//
68class LL_COMMON_API LLAPRPool
69{
70public:
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
77protected:
78 void releaseAPRPool() ;
79 void createAPRPool() ;
80
81protected:
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//
94class LL_COMMON_API LLVolatileAPRPool : protected LLAPRPool
95{
96public:
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
112private:
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
206private: 141private:
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
210public: 146public:
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
261void LL_COMMON_API ll_apr_assert_status(apr_status_t status); 197void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
262 198
263extern "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
38BOOL LLCommon::sAprInitialized = FALSE;
39
40//static
41void LLCommon::initClass() 38void 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
43public: 43public:
44 static void initClass(); 44 static void initClass();
45 static void cleanupClass(); 45 static void cleanupClass();
46private:
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
874apr_thread_mutex_t* gLogMutexp;
875apr_thread_mutex_t* gCallStacksLogMutexp;
876
874namespace { 877namespace {
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
35LLFixedBuffer::LLFixedBuffer(const U32 max_lines) 35LLFixedBuffer::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//
46class LLScopedVolatileAPRPool
47{
48private:
49 AIVolatileAPRPool& mPool;
50 apr_pool_t* mScopedAPRpool;
51public:
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
90LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : 90LLThread::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
165void LLThread::start() 149void 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.
254static apr_os_thread_t main_thread_id;
255bool is_main_thread() { return apr_os_thread_equal(main_thread_id, apr_os_thread_current()); }
256#endif
269 257
270LLMutex::LLMutex(apr_pool_t *poolp) : 258// The thread private handle to access the AIThreadLocalData instance.
271 mAPRMutexp(NULL) 259apr_threadkey_t* AIThreadLocalData::sThreadLocalDataKey;
260
261//static
262void 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
286LLMutex::~LLMutex() 284// This is called once for every thread when the thread is destructed.
285//static
286void 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; 292void 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
299bool LLMutex::isLocked() 303//static
304AIThreadLocalData& 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
317bool 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
311LLCondition::LLCondition(apr_pool_t *poolp) : 329LLCondition::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
319LLCondition::~LLCondition() 334LLCondition::~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
42class LLThread; 43class LLThread;
43class LLMutex; 44class LLMutex;
44class LLCondition; 45class LLCondition;
45 46
47class LL_COMMON_API AIThreadLocalData
48{
49private:
50 static apr_threadkey_t* sThreadLocalDataKey;
51
52public:
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
46class LL_COMMON_API LLThread 63class LL_COMMON_API LLThread
47{ 64{
48public: 65public:
@@ -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
87private: 105private:
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
128class LL_COMMON_API LLMutex 147class LL_COMMON_API LLMutexBase
129{ 148{
130public: 149public:
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
141protected: 157protected:
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
162class LL_COMMON_API LLMutex : public LLMutexBase
163{
164public:
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
176protected:
177 AIAPRPool mPool;
178};
179
180#if APR_HAS_THREADS
181// No need to use a root pool in this case.
182typedef LLMutex LLMutexRootPool;
183#else // APR_HAS_THREADS
184class LL_COMMON_API LLMutexRootPool : public LLMutexBase
185{
186public:
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
202protected:
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).
148class LL_COMMON_API LLCondition : public LLMutex 208class LL_COMMON_API LLCondition : public LLMutex
149{ 209{
150public: 210public:
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:
162class LL_COMMON_API LLMutexLock 222class LL_COMMON_API LLMutexLock
163{ 223{
164public: 224public:
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 }
174private: 234private:
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 @@
43LLWorkerThread::LLWorkerThread(const std::string& name, bool threaded) : 43LLWorkerThread::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
49LLWorkerThread::~LLWorkerThread() 49LLWorkerThread::~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
196private: 196private:
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
58void LLImage::initClass(const bool& useDSO) 58void 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)();
46CreateLLImageJ2CFunction j2cimpl_create_func; 46CreateLLImageJ2CFunction j2cimpl_create_func;
47DestroyLLImageJ2CFunction j2cimpl_destroy_func; 47DestroyLLImageJ2CFunction j2cimpl_destroy_func;
48EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func; 48EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func;
49apr_pool_t *j2cimpl_dso_memory_pool; 49AIAPRPool j2cimpl_dso_memory_pool;
50apr_dso_handle_t *j2cimpl_dso_handle; 50apr_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()
163void LLImageJ2C::closeDSO() 158void 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 @@
41LLImageDecodeThread::LLImageDecodeThread(bool threaded) 41LLImageDecodeThread::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
49S32 LLImageDecodeThread::update(U32 max_time_ms) 48S32 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)
71LLImageDecodeThread::handle_t LLImageDecodeThread::decodeImage(LLImageFormatted* image, 70LLImageDecodeThread::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
82S32 LLImageDecodeThread::tut_size() 81S32 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
61LLVolumeMgr::~LLVolumeMgr() 61LLVolumeMgr::~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
464bool LLAres::process(U64 timeout) 465bool 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
951LLHTTPNode& LLIOHTTPServer::create( 951LLHTTPNode& 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
57public: 57public:
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
107LLSocket::ptr_t LLSocket::create(apr_pool_t* pool, EType type, U16 port) 108LLSocket::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
205LLSocket::ptr_t LLSocket::create(apr_socket_t* socket, apr_pool_t* pool) 186LLSocket::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
220bool LLSocket::blockingConnect(const LLHost& host) 208bool 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
243LLSocket::LLSocket(apr_socket_t* socket, apr_pool_t* pool) : 231LLSocket::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
252LLSocket::~LLSocket() 238LLSocket::~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
267void LLSocket::setOptions() 249void LLSocket::setOptions()
@@ -522,10 +504,8 @@ LLIOPipe::EStatus LLIOSocketWriter::process_impl(
522/// 504///
523 505
524LLIOServerSocket::LLIOServerSocket( 506LLIOServerSocket::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
637LLIODataSocket::LLIODataSocket( 611LLIODataSocket::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
299public: 286public:
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
333protected: 320protected:
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
372protected: 357protected:
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 @@
63const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096; 64const size_t LL_MAX_KNOWN_GOOD_MAIL_SIZE = 4096;
64 65
65static bool gMailEnabled = true; 66static bool gMailEnabled = true;
66static apr_pool_t* gMailPool; 67static AIAPRPool gMailPool;
67static apr_sockaddr_t* gSockAddr; 68static apr_sockaddr_t* gSockAddr;
68static apr_socket_t* gMailSocket; 69static 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
148void LLMail::init(const std::string& hostname, apr_pool_t* pool) 149void 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
36typedef struct apr_pool_t apr_pool_t;
37
38#include "llsd.h" 36#include "llsd.h"
39 37
40class LLMail 38class LLMail
41{ 39{
42public: 40public:
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 */
172LLPumpIO::LLPumpIO(apr_pool_t* pool) : 173LLPumpIO::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
191LLPumpIO::~LLPumpIO() 190LLPumpIO::~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);
197bool 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
205bool LLPumpIO::addChain(const chain_t& chain, F32 timeout) 207bool 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
830void LLPumpIO::initialize(apr_pool_t* pool) 831void 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
842void 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
865void LLPumpIO::rebuildPollset() 842void 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(
1159LLPumpIO::LLChainInfo::LLChainInfo() : 1134LLPumpIO::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
408protected: 398protected:
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"
48static const U32 HTTP_STATUS_PIPE_ERROR = 499; 49static 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
162void LLURLRequest::useProxy(bool use_proxy) 163void 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();
103class LLMessagePollInfo 103class LLMessagePollInfo
104{ 104{
105public: 105public:
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
110namespace 112namespace
@@ -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. */
43LLPluginInstanceMessageListener::~LLPluginInstanceMessageListener() 42LLPluginInstanceMessageListener::~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
101LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): 101LLPluginMessagePipe::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
50bool LLPluginProcessParent::sUseReadThread = false; 50bool LLPluginProcessParent::sUseReadThread = false;
51apr_pollset_t *LLPluginProcessParent::sPollSet = NULL; 51apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
52AIAPRPool LLPluginProcessParent::sPollSetPool;
52bool LLPluginProcessParent::sPollsetNeedsRebuild = false; 53bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
53LLMutex *LLPluginProcessParent::sInstancesMutex; 54LLMutex *LLPluginProcessParent::sInstancesMutex;
54std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances; 55std::list<LLPluginProcessParent*> LLPluginProcessParent::sInstances;
@@ -59,7 +60,7 @@ class LLPluginProcessParentPollThread: public LLThread
59{ 60{
60public: 61public:
61 LLPluginProcessParentPollThread() : 62 LLPluginProcessParentPollThread() :
62 LLThread("LLPluginProcessParentPollThread", gAPRPoolp) 63 LLThread("LLPluginProcessParentPollThread")
63 { 64 {
64 } 65 }
65protected: 66protected:
@@ -84,12 +85,11 @@ protected:
84 85
85}; 86};
86 87
87LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): 88LLPluginProcessParent::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
177bool LLPluginProcessParent::accept() 178bool 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
38class LLPluginSharedMemoryPlatformImpl; 40class 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
183int main(int argc, char **argv) 183int 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;
237LLVFS::LLVFS(const std::string& index_filename, const std::string& data_filename, const BOOL read_only, const U32 presize, const BOOL remove_after_crash) 237LLVFS::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
76static bool sSymsGrabbed = false; 76static bool sSymsGrabbed = false;
77static apr_pool_t *sSymPADSOMemoryPool = NULL; 77static AIAPRPool sSymPADSOMemoryPool;
78static apr_dso_handle_t *sSymPADSOHandleG = NULL; 78static apr_dso_handle_t *sSymPADSOHandleG = NULL;
79 79
80bool grab_pa_syms(std::string pulse_dso_name) 80bool 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
737LLTextureCache::LLTextureCache(bool threaded) 737LLTextureCache::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
142protected:
143 //void setFileAPRPool(apr_pool_t* pool) { mFileAPRPool = pool ; }
144
145private: 142private:
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}