summaryrefslogtreecommitdiff
path: root/indra/llcommon/workqueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/workqueue.cpp')
-rw-r--r--indra/llcommon/workqueue.cpp46
1 files changed, 41 insertions, 5 deletions
diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp
index 0407d6c3e9..4f19ab2cc2 100644
--- a/indra/llcommon/workqueue.cpp
+++ b/indra/llcommon/workqueue.cpp
@@ -38,7 +38,8 @@ LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)
{
// Register for "LLApp" events so we can implicitly close() on viewer shutdown
std::string listener_name = "WorkQueue:" + getKey();
- LLEventPumps::instance().obtain("LLApp").listen(
+ LLEventPumps* pump = LLEventPumps::getInstance();
+ pump->obtain("LLApp").listen(
listener_name,
[this](const LLSD& stat)
{
@@ -54,14 +55,25 @@ LL::WorkQueueBase::WorkQueueBase(const std::string& name, bool auto_shutdown)
// Store the listener name so we can unregister in the destructor
mListenerName = listener_name;
+ mPumpHandle = pump->getHandle();
}
}
LL::WorkQueueBase::~WorkQueueBase()
{
- if (!mListenerName.empty() && !LLEventPumps::wasDeleted())
+ if (!mListenerName.empty() && !mPumpHandle.isDead())
{
- LLEventPumps::instance().obtain("LLApp").stopListening(mListenerName);
+ // Due to shutdown order issues, use handle, not a singleton
+ // and ignore fiber issue.
+ try
+ {
+ LLEventPumps* pump = mPumpHandle.get();
+ pump->obtain("LLApp").stopListening(mListenerName);
+ }
+ catch (const boost::fibers::lock_error&)
+ {
+ // Likely mutex is down, ignore
+ }
}
}
@@ -281,12 +293,36 @@ bool LL::WorkQueue::done()
bool LL::WorkQueue::post(const Work& callable)
{
- return mQueue.pushIfOpen(callable);
+ try
+ {
+ return mQueue.pushIfOpen(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::post" << LL_ENDL;
+ return false;
+ }
}
bool LL::WorkQueue::tryPost(const Work& callable)
{
- return mQueue.tryPush(callable);
+ try
+ {
+ return mQueue.tryPush(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::tryPost" << LL_ENDL;
+ return false;
+ }
+}
+
+bool LL::WorkQueue::postToMainLoop(const Work& work)
+{
+ auto queue = getInstance("mainloop");
+ return queue && queue->tryPost(work);
}
LL::WorkQueue::Work LL::WorkQueue::pop_()