From 09b29a7fdec3cad2ee03b3a5de48dbb8d54e7952 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 27 Feb 2019 17:43:31 -0800 Subject: Began work for adding a test covering LLCoprocedureManager --- .../llmessage/tests/llcoproceduremanager_test.cpp | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 indra/llmessage/tests/llcoproceduremanager_test.cpp (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp new file mode 100644 index 0000000000..8c4937fd84 --- /dev/null +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -0,0 +1,90 @@ +/** + * @file llcoproceduremanager_test.cpp + * @author Brad + * @date 2019-02 + * @brief LLCoprocedureManager unit test + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llsdserialize.h" + +#include "../llcoproceduremanager.h" + +#include "../test/lltut.h" + + +#if LL_WINDOWS +// disable unreachable code warnings +#pragma warning(disable: 4702) +#endif + +LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int, unsigned int) +{ + +} + +void LLCoreHttpUtil::HttpCoroutineAdapter::cancelSuspendedOperation() +{ + +} + +LLCoreHttpUtil::HttpCoroutineAdapter::~HttpCoroutineAdapter() +{ + +} + +LLCore::HttpRequest::HttpRequest() +{ + +} + +LLCore::HttpRequest::~HttpRequest() +{ + +} + +namespace tut +{ + struct coproceduremanager_test + { + coproceduremanager_test() + { + } + }; + typedef test_group coproceduremanager_t; + typedef coproceduremanager_t::object coproceduremanager_object_t; + tut::coproceduremanager_t tut_coproceduremanager("LLCoprocedureManager"); + + + template<> template<> + void coproceduremanager_object_t::test<1>() + { + int foo = 0; + LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure( "PoolName", "ProcName", + [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { + foo = 1; + }); + ensure_equals("coprocedure failed to update foo", foo, 1); + } +} -- cgit v1.3 From 66abe4ccab7b60e9056ee03b9536b9980599d5f0 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 4 Mar 2019 13:00:52 -0800 Subject: Attempt to close LLEventCoro's LLBoundListener connection when promise has been fulfilled. --- indra/llcommon/lleventcoro.cpp | 13 ++++++++----- indra/llmessage/tests/llcoproceduremanager_test.cpp | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 367ddf485d..aa9f4b7840 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -134,12 +134,15 @@ LLBoundListener postAndSuspendSetup(const std::string& callerName, // return the consuming attribute for some other coroutine, most likely // the main routine. bool consuming(LLCoros::get_consuming()); + + std::shared_ptr connection_ptr = std::make_shared(); + // make a callback that will assign a value to the future, and listen on // the specified LLEventPump with that callback - LLBoundListener connection( - replyPump.getPump().listen(listenerName, - [&promise, consuming, listenerName](const LLSD& result) + *connection_ptr = replyPump.getPump().listen(listenerName, + [&promise, consuming, listenerName, connection_ptr](const LLSD& result) { + connection_ptr->disconnect(); try { promise.set_value(result); @@ -150,7 +153,7 @@ LLBoundListener postAndSuspendSetup(const std::string& callerName, << listenerName << "' " << ex.what() << LL_ENDL; } return consuming; - })); + }); // skip the "post" part if requestPump is default-constructed if (requestPump) { @@ -169,7 +172,7 @@ LLBoundListener postAndSuspendSetup(const std::string& callerName, LL_DEBUGS("lleventcoro") << callerName << ": coroutine " << listenerName << " about to wait on LLEventPump " << replyPump.getPump().getName() << LL_ENDL; - return connection; + return *connection_ptr; } } // anonymous diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 8c4937fd84..8ba9a84356 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -4,7 +4,7 @@ * @date 2019-02 * @brief LLCoprocedureManager unit test * - * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * $LicenseInfo:firstyear=2019&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. * -- cgit v1.3 From 6992ad457c04a2f9b4dee96c19d1e0df3c870dbc Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Tue, 5 Mar 2019 17:09:38 -0800 Subject: Lint fixes on new test file. --- .../llmessage/tests/llcoproceduremanager_test.cpp | 43 ++++++++++------------ 1 file changed, 19 insertions(+), 24 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 8ba9a84356..e503798d88 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -41,50 +41,45 @@ LLCoreHttpUtil::HttpCoroutineAdapter::HttpCoroutineAdapter(std::string const&, unsigned int, unsigned int) { - } void LLCoreHttpUtil::HttpCoroutineAdapter::cancelSuspendedOperation() { - } LLCoreHttpUtil::HttpCoroutineAdapter::~HttpCoroutineAdapter() { - } LLCore::HttpRequest::HttpRequest() { - } LLCore::HttpRequest::~HttpRequest() { - } namespace tut { - struct coproceduremanager_test - { - coproceduremanager_test() - { - } - }; - typedef test_group coproceduremanager_t; - typedef coproceduremanager_t::object coproceduremanager_object_t; - tut::coproceduremanager_t tut_coproceduremanager("LLCoprocedureManager"); + struct coproceduremanager_test + { + coproceduremanager_test() + { + } + }; + typedef test_group coproceduremanager_t; + typedef coproceduremanager_t::object coproceduremanager_object_t; + tut::coproceduremanager_t tut_coproceduremanager("LLCoprocedureManager"); - - template<> template<> - void coproceduremanager_object_t::test<1>() - { + + template<> template<> + void coproceduremanager_object_t::test<1>() + { int foo = 0; - LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure( "PoolName", "ProcName", - [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { + LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", + [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { foo = 1; - }); - ensure_equals("coprocedure failed to update foo", foo, 1); - } -} + }); + ensure_equals("coprocedure failed to update foo", foo, 1); + } +} // namespace tut -- cgit v1.3 From 997bdfc88682de36f02931a22d3baa23f00b6ddb Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 11 Mar 2019 17:42:39 -0700 Subject: First draft of boost::fibers::unbuffered_channel based implementation of LLCoprocedureManager --- indra/llmessage/llcoproceduremanager.cpp | 301 ++++++++++----------- indra/llmessage/llcoproceduremanager.h | 4 +- .../llmessage/tests/llcoproceduremanager_test.cpp | 81 ++++++ 3 files changed, 234 insertions(+), 152 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 4c85dd999a..9501181509 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -25,23 +25,23 @@ * $/LicenseInfo$ */ -#include "linden_common.h" +#include "linden_common.h" #include "llcoproceduremanager.h" #include "llexception.h" #include "stringize.h" #include +#include //========================================================================= // Map of pool sizes for known pools -// *TODO$: When C++11 this can be initialized here as follows: -// = {{"AIS", 25}, {"Upload", 1}} -static std::map DefaultPoolSizes = - boost::assign::map_list_of - (std::string("Upload"), 1) - (std::string("AIS"), 1); - // *TODO: Rider for the moment keep AIS calls serialized otherwise the COF will tend to get out of sync. +static const std::map DefaultPoolSizes = +{ + {"Upload", 1}, + {"AIS", 1}, + // *TODO: Rider for the moment keep AIS calls serialized otherwise the COF will tend to get out of sync. +}; -#define DEFAULT_POOL_SIZE 5 +static const U32 DEFAULT_POOL_SIZE = 5; //========================================================================= class LLCoprocedurePool: private boost::noncopyable @@ -50,7 +50,7 @@ public: typedef LLCoprocedureManager::CoProcedure_t CoProcedure_t; LLCoprocedurePool(const std::string &name, size_t size); - virtual ~LLCoprocedurePool(); + ~LLCoprocedurePool(); /// Places the coprocedure on the queue for processing. /// @@ -63,18 +63,18 @@ public: /// Cancel a coprocedure. If the coprocedure is already being actively executed /// this method calls cancelSuspendedOperation() on the associated HttpAdapter /// If it has not yet been dequeued it is simply removed from the queue. - bool cancelCoprocedure(const LLUUID &id); + //bool cancelCoprocedure(const LLUUID &id); /// Requests a shutdown of the upload manager. Passing 'true' will perform /// an immediate kill on the upload coroutine. - void shutdown(bool hardShutdown = false); + //void shutdown(bool hardShutdown = false); - /// Returns the number of coprocedures in the queue awaiting processing. - /// - inline size_t countPending() const - { - return mPendingCoprocs.size(); - } +// /// Returns the number of coprocedures in the queue awaiting processing. +// /// +// inline size_t countPending() const +// { +// return mPendingCoprocs.size(); +// } /// Returns the number of coprocedures actively being processed. /// @@ -83,13 +83,15 @@ public: return mActiveCoprocs.size(); } - /// Returns the total number of coprocedures either queued or in active processing. - /// - inline size_t count() const - { - return countPending() + countActive(); - } +// /// Returns the total number of coprocedures either queued or in active processing. +// /// +// inline size_t count() const +// { +// return countPending() + countActive(); +// } + void close(); + private: struct QueuedCoproc { @@ -108,15 +110,15 @@ private: // we use a deque here rather than std::queue since we want to be able to // iterate through the queue and potentially erase an entry from the middle. - typedef std::deque CoprocQueue_t; + // TODO - make this queue be backed by an unbuffered_channel + typedef boost::fibers::unbuffered_channel CoprocQueue_t; typedef std::map ActiveCoproc_t; std::string mPoolName; size_t mPoolSize; CoprocQueue_t mPendingCoprocs; ActiveCoproc_t mActiveCoprocs; - bool mShutdown; - LLEventStream mWakeupTrigger; + //bool mShutdown; typedef std::map CoroAdapterMap_t; LLCore::HttpRequest::policy_t mHTTPPolicy; @@ -143,8 +145,7 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std:: std::string keyName = "PoolSize" + poolName; int size = 0; - if (poolName.empty()) - LL_ERRS("CoprocedureManager") << "Poolname must not be empty" << LL_ENDL; + LL_ERRS_IF(poolName.empty(), "CoprocedureManager") << "Poolname must not be empty" << LL_ENDL; if (mPropertyQueryFn && !mPropertyQueryFn.empty()) { @@ -152,24 +153,26 @@ LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std:: } if (size == 0) - { // if not found grab the know default... if there is no known + { + // if not found grab the know default... if there is no known // default use a reasonable number like 5. - std::map::iterator it = DefaultPoolSizes.find(poolName); - if (it == DefaultPoolSizes.end()) - size = DEFAULT_POOL_SIZE; - else - size = (*it).second; + auto it = DefaultPoolSizes.find(poolName); + size = (it != DefaultPoolSizes.end()) ? it->second : DEFAULT_POOL_SIZE; if (mPropertyDefineFn && !mPropertyDefineFn.empty()) + { mPropertyDefineFn(keyName, size, "Coroutine Pool size for " + poolName); + } + LL_WARNS() << "LLCoprocedureManager: No setting for \"" << keyName << "\" setting pool size to default of " << size << LL_ENDL; } poolPtr_t pool(new LLCoprocedurePool(poolName, size)); - mPoolMap.insert(poolMap_t::value_type(poolName, pool)); + LL_ERRS_IF(!pool, "CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL; + + bool inserted = mPoolMap.emplace(poolName, pool).second; + LL_ERRS_IF(!inserted, "CoprocedureManager") << "Unable to add pool named \"" << poolName << "\" to map. FATAL!" << LL_ENDL; - if (!pool) - LL_ERRS("CoprocedureManager") << "Unable to create pool named \"" << poolName << "\" FATAL!" << LL_ENDL; return pool; } @@ -178,30 +181,24 @@ LLUUID LLCoprocedureManager::enqueueCoprocedure(const std::string &pool, const s { // Attempt to find the pool and enqueue the procedure. If the pool does // not exist, create it. - poolPtr_t targetPool; poolMap_t::iterator it = mPoolMap.find(pool); - if (it == mPoolMap.end()) - { - targetPool = initializePool(pool); - } - else - { - targetPool = (*it).second; - } + poolPtr_t targetPool = (it != mPoolMap.end()) ? it->second : initializePool(pool); return targetPool->enqueueCoprocedure(name, proc); } -void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id) -{ - for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) - { - if ((*it).second->cancelCoprocedure(id)) - return; - } - LL_INFOS() << "Coprocedure not found." << LL_ENDL; -} +//void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id) +//{ +// for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) +// { +// if (it->second->cancelCoprocedure(id)) +// { +// return; +// } +// } +// LL_INFOS() << "Coprocedure not found." << LL_ENDL; +//} /*==========================================================================*| void LLCoprocedureManager::shutdown(bool hardShutdown) @@ -220,32 +217,32 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd mPropertyDefineFn = updatefn; } -//------------------------------------------------------------------------- -size_t LLCoprocedureManager::countPending() const -{ - size_t count = 0; - for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) - { - count += (*it).second->countPending(); - } - return count; -} - -size_t LLCoprocedureManager::countPending(const std::string &pool) const -{ - poolMap_t::const_iterator it = mPoolMap.find(pool); - - if (it == mPoolMap.end()) - return 0; - return (*it).second->countPending(); -} +////------------------------------------------------------------------------- +//size_t LLCoprocedureManager::countPending() const +//{ +// size_t count = 0; +// for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) +// { +// count += (*it).second->countPending(); +// } +// return count; +//} +// +//size_t LLCoprocedureManager::countPending(const std::string &pool) const +//{ +// poolMap_t::const_iterator it = mPoolMap.find(pool); +// +// if (it == mPoolMap.end()) +// return 0; +// return (*it).second->countPending(); +//} size_t LLCoprocedureManager::countActive() const { size_t count = 0; for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) { - count += (*it).second->countActive(); + count += it->second->countActive(); } return count; } @@ -255,27 +252,38 @@ size_t LLCoprocedureManager::countActive(const std::string &pool) const poolMap_t::const_iterator it = mPoolMap.find(pool); if (it == mPoolMap.end()) + { return 0; - return (*it).second->countActive(); + } + return it->second->countActive(); } -size_t LLCoprocedureManager::count() const +//size_t LLCoprocedureManager::count() const +//{ +// size_t count = 0; +// for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) +// { +// count += (*it).second->count(); +// } +// return count; +//} +// +//size_t LLCoprocedureManager::count(const std::string &pool) const +//{ +// poolMap_t::const_iterator it = mPoolMap.find(pool); +// +// if (it == mPoolMap.end()) +// return 0; +// return (*it).second->count(); +//} + +void LLCoprocedureManager::close(const std::string &pool) { - size_t count = 0; - for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) + poolMap_t::iterator it = mPoolMap.find(pool); + if (it != mPoolMap.end()) { - count += (*it).second->count(); + it->second->close(); } - return count; -} - -size_t LLCoprocedureManager::count(const std::string &pool) const -{ - poolMap_t::const_iterator it = mPoolMap.find(pool); - - if (it == mPoolMap.end()) - return 0; - return (*it).second->count(); } //========================================================================= @@ -283,8 +291,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): mPoolName(poolName), mPoolSize(size), mPendingCoprocs(), - mShutdown(false), - mWakeupTrigger("CoprocedurePool" + poolName, true), + //mShutdown(false), mCoroMapping(), mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID) { @@ -299,8 +306,6 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): } LL_INFOS() << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items." << LL_ENDL; - - mWakeupTrigger.post(LLSD()); } LLCoprocedurePool::~LLCoprocedurePool() @@ -339,76 +344,70 @@ LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoproced { LLUUID id(LLUUID::generateNewID()); - mPendingCoprocs.push_back(QueuedCoproc::ptr_t(new QueuedCoproc(name, id, proc))); + mPendingCoprocs.push(QueuedCoproc::ptr_t(new QueuedCoproc(name, id, proc))); LL_INFOS() << "Coprocedure(" << name << ") enqueued with id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; - mWakeupTrigger.post(LLSD()); - return id; } -bool LLCoprocedurePool::cancelCoprocedure(const LLUUID &id) -{ - // first check the active coroutines. If there, remove it and return. - ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(id); - if (itActive != mActiveCoprocs.end()) - { - LL_INFOS() << "Found and canceling active coprocedure with id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; - (*itActive).second->cancelSuspendedOperation(); - mActiveCoprocs.erase(itActive); - return true; - } - - for (CoprocQueue_t::iterator it = mPendingCoprocs.begin(); it != mPendingCoprocs.end(); ++it) - { - if ((*it)->mId == id) - { - LL_INFOS() << "Found and removing queued coroutine(" << (*it)->mName << ") with Id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; - mPendingCoprocs.erase(it); - return true; - } - } - - LL_INFOS() << "Coprocedure with Id=" << id.asString() << " was not found in pool \"" << mPoolName << "\"" << LL_ENDL; - return false; -} +//bool LLCoprocedurePool::cancelCoprocedure(const LLUUID &id) +//{ +// // first check the active coroutines. If there, remove it and return. +// ActiveCoproc_t::iterator itActive = mActiveCoprocs.find(id); +// if (itActive != mActiveCoprocs.end()) +// { +// LL_INFOS() << "Found and canceling active coprocedure with id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; +// (*itActive).second->cancelSuspendedOperation(); +// mActiveCoprocs.erase(itActive); +// return true; +// } +// +//// for (auto it: mPendingCoprocs) +//// { +//// if ((*it)->mId == id) +//// { +//// LL_INFOS() << "Found and removing queued coroutine(" << (*it)->mName << ") with Id=" << id.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; +//// mPendingCoprocs.erase(it); +//// return true; +//// } +//// } +// +// LL_INFOS() << "Coprocedure with Id=" << id.asString() << " was not found in pool \"" << mPoolName << "\"" << LL_ENDL; +// return false; +//} //------------------------------------------------------------------------- void LLCoprocedurePool::coprocedureInvokerCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t httpAdapter) { LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - while (!mShutdown) + QueuedCoproc::ptr_t coproc; + while (mPendingCoprocs.pop(coproc) != boost::fibers::channel_op_status::closed) { - llcoro::suspendUntilEventOn(mWakeupTrigger); - if (mShutdown) - break; - - while (!mPendingCoprocs.empty()) - { - QueuedCoproc::ptr_t coproc = mPendingCoprocs.front(); - mPendingCoprocs.pop_front(); - ActiveCoproc_t::iterator itActive = mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter)).first; - - LL_INFOS() << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; - - try - { - coproc->mProc(httpAdapter, coproc->mId); - } - catch (...) - { - LOG_UNHANDLED_EXCEPTION(STRINGIZE("Coprocedure('" << coproc->mName - << "', id=" << coproc->mId.asString() - << ") in pool '" << mPoolName << "'")); - // must NOT omit this or we deplete the pool - mActiveCoprocs.erase(itActive); - throw; - } - - LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL; + ActiveCoproc_t::iterator itActive = mActiveCoprocs.insert(ActiveCoproc_t::value_type(coproc->mId, httpAdapter)).first; + LL_INFOS() << "Dequeued and invoking coprocedure(" << coproc->mName << ") with id=" << coproc->mId.asString() << " in pool \"" << mPoolName << "\"" << LL_ENDL; + + try + { + coproc->mProc(httpAdapter, coproc->mId); + } + catch (...) + { + LOG_UNHANDLED_EXCEPTION(STRINGIZE("Coprocedure('" << coproc->mName + << "', id=" << coproc->mId.asString() + << ") in pool '" << mPoolName << "'")); + // must NOT omit this or we deplete the pool mActiveCoprocs.erase(itActive); + throw; } + + LL_INFOS() << "Finished coprocedure(" << coproc->mName << ")" << " in pool \"" << mPoolName << "\"" << LL_ENDL; + + mActiveCoprocs.erase(itActive); } } + +void LLCoprocedurePool::close() { + mPendingCoprocs.close(); +} diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index ba6f97355c..93d699a714 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -57,7 +57,7 @@ public: /// Cancel a coprocedure. If the coprocedure is already being actively executed /// this method calls cancelYieldingOperation() on the associated HttpAdapter /// If it has not yet been dequeued it is simply removed from the queue. - void cancelCoprocedure(const LLUUID &id); + //void cancelCoprocedure(const LLUUID &id); /*==========================================================================*| /// Requests a shutdown of the upload manager. Passing 'true' will perform @@ -82,6 +82,8 @@ public: size_t count() const; size_t count(const std::string &pool) const; + void close(const std::string &pool); + private: typedef boost::shared_ptr poolPtr_t; diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index e503798d88..17535abd1e 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -31,6 +31,12 @@ #include "../llcoproceduremanager.h" +#include + +#include +#include +#include + #include "../test/lltut.h" @@ -81,5 +87,80 @@ namespace tut foo = 1; }); ensure_equals("coprocedure failed to update foo", foo, 1); + + LLCoprocedureManager::instance().close("PoolName"); + } + + template<> template<> + void coproceduremanager_object_t::test<2>() + { + const size_t capacity = 2; + boost::fibers::buffered_channel> chan(capacity); + + boost::fibers::fiber worker([&chan]() { + chan.value_pop()(); + }); + + chan.push([]() { + LL_INFOS("Test") << "test 1" << LL_ENDL; + }); + + worker.join(); + } + + template<> template<> + void coproceduremanager_object_t::test<3>() + { + boost::fibers::unbuffered_channel> chan; + + boost::fibers::fiber worker([&chan]() { + chan.value_pop()(); + }); + + chan.push([]() { + LL_INFOS("Test") << "test 1" << LL_ENDL; + }); + + worker.join(); + } + + template<> template<> + void coproceduremanager_object_t::test<4>() + { + boost::fibers::buffered_channel> chan(4); + + boost::fibers::fiber worker([&chan]() { + std::function f; + + // using namespace std::chrono_literals; + // const auto timeout = 5s; + // boost::fibers::channel_op_status status; + while (chan.pop(f) != boost::fibers::channel_op_status::closed) + { + LL_INFOS("CoWorker") << "got coproc" << LL_ENDL; + f(); + } + LL_INFOS("CoWorker") << "got closed" << LL_ENDL; + }); + + int counter = 0; + + for (int i = 0; i < 5; ++i) + { + LL_INFOS("CoMain") << "pushing coproc " << i << LL_ENDL; + chan.push([&counter]() { + LL_INFOS("CoProc") << "in coproc" << LL_ENDL; + ++counter; + }); + } + + LL_INFOS("CoMain") << "closing channel" << LL_ENDL; + chan.close(); + + LL_INFOS("CoMain") << "joining worker" << LL_ENDL; + worker.join(); + + LL_INFOS("CoMain") << "checking count" << LL_ENDL; + ensure_equals("coprocedure failed to update counter", counter, 5); } } // namespace tut -- cgit v1.3 From 16453005bb8373d7228262bf79c5882f311380e9 Mon Sep 17 00:00:00 2001 From: Anchor Date: Thu, 6 Jun 2019 01:51:38 -0700 Subject: [DRTVWR-476] - update cef, fix merge --- autobuild.xml | 12 ++++++------ indra/llcommon/llfasttimer.h | 6 ++++++ indra/llmessage/llcoproceduremanager.cpp | 2 ++ indra/llmessage/tests/llcoproceduremanager_test.cpp | 2 ++ 4 files changed, 16 insertions(+), 6 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/autobuild.xml b/autobuild.xml index e1e3fc74a4..c4b5469477 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -580,9 +580,9 @@ archive hash - c0456d23b8dce071eb20f07c4f4b97c2 + c1cd0a6a08f71f357a01fba55e0a6b16 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/34195/285056/dullahan-1.1.1080_3.3325.1750.gaabe4c4-darwin64-525430.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/38605/326402/dullahan-1.1.1320_3.3626.1895.g7001d56-darwin64-527866.tar.bz2 name darwin64 @@ -592,9 +592,9 @@ archive hash - 53eefec74510d5de118855aba3f908b6 + c0129834f8995f9c354def141cf0e12b url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/34194/285057/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows-525430.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/38602/326395/dullahan-1.1.1320_3.3626.1895.g7001d56-windows-527866.tar.bz2 name windows @@ -604,9 +604,9 @@ archive hash - 7422f84b21b5c3c262bc0f7bcea125bf + 0e2206a105b1e48ee89951d310b21025 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/34196/285066/dullahan-1.1.1080_3.3325.1750.gaabe4c4-windows64-525430.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/38601/326388/dullahan-1.1.1320_3.3626.1895.g7001d56-windows64-527866.tar.bz2 name windows64 diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index d463fc9d65..5628a05b00 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -31,6 +31,10 @@ #include "lltrace.h" #include "lltreeiterators.h" +#if LL_WINDOWS +#include +#endif + #define LL_FAST_TIMER_ON 1 #define LL_FASTTIMER_USE_RDTSC 1 @@ -85,6 +89,8 @@ public: // return __rdtsc(); //} + + // shift off lower 8 bits for lower resolution but longer term timing // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing #if LL_FASTTIMER_USE_RDTSC diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 579ab097e0..fa8e9c3ebf 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -25,6 +25,8 @@ * $/LicenseInfo$ */ +#include "llwin32headers.h" + #include "linden_common.h" #include "llcoproceduremanager.h" diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 17535abd1e..9b0ef93b13 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -26,6 +26,8 @@ * $/LicenseInfo$ */ +#include "llwin32headers.h" + #include "linden_common.h" #include "llsdserialize.h" -- cgit v1.3 From ebe1ffcbf7e7cfd5b5bb49cb771c61d0afd8b10e Mon Sep 17 00:00:00 2001 From: Anchor Date: Mon, 1 Jul 2019 15:30:09 -0700 Subject: [DRTVWR-476] - temp fix to a test --- indra/llmessage/tests/llcoproceduremanager_test.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 9b0ef93b13..534aea2218 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -88,7 +88,9 @@ namespace tut [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { foo = 1; }); - ensure_equals("coprocedure failed to update foo", foo, 1); + + // TODO: fix me. timing issues.the above coproc gets executed after a frame + //ensure_equals("coprocedure failed to update foo", foo, 1); LLCoprocedureManager::instance().close("PoolName"); } -- cgit v1.3 From 44768b1b02063523798d8d72f0eb4b18f9b69b7b Mon Sep 17 00:00:00 2001 From: Anchor Date: Tue, 2 Jul 2019 21:22:10 -0700 Subject: [DRTVWR-476] - temp fix to test. comment it out. access violation in release --- indra/llmessage/tests/llcoproceduremanager_test.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 534aea2218..f2de547452 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -83,16 +83,19 @@ namespace tut template<> template<> void coproceduremanager_object_t::test<1>() { + // TODO: fix me. timing issues.the coproc gets executed after a frame, access violation in release + + /* int foo = 0; LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { foo = 1; }); - // TODO: fix me. timing issues.the above coproc gets executed after a frame - //ensure_equals("coprocedure failed to update foo", foo, 1); + ensure_equals("coprocedure failed to update foo", foo, 1); LLCoprocedureManager::instance().close("PoolName"); + */ } template<> template<> -- cgit v1.3 From 6f879178d6c8ec7c6a9d4fdb3f42664dea595a0a Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 19 Sep 2019 16:36:41 -0400 Subject: DRTVWR-476: Re-enable an llcoproceduremanager_test case. Use new Sync class to make the driving logic wait for the coprocedure to run. --- indra/llmessage/tests/llcoproceduremanager_test.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index f2de547452..734b986f80 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -40,6 +40,7 @@ #include #include "../test/lltut.h" +#include "../test/sync.h" #if LL_WINDOWS @@ -83,19 +84,18 @@ namespace tut template<> template<> void coproceduremanager_object_t::test<1>() { - // TODO: fix me. timing issues.the coproc gets executed after a frame, access violation in release - - /* + Sync sync; int foo = 0; LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", - [&foo] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { + [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { + sync.bump(); foo = 1; }); - ensure_equals("coprocedure failed to update foo", foo, 1); + sync.yield(); + ensure_equals("coprocedure failed to update foo", foo, 1); LLCoprocedureManager::instance().close("PoolName"); - */ } template<> template<> -- cgit v1.3 From fc2437fb5d349a094c1c64631ba6a5fd5675ddcc Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 15 Nov 2019 08:17:04 -0500 Subject: DRTVWR-476: Introduce LLCoprocedureManager::close(). Use in tests. The new close(void) method simply acquires the logic from ~LLCoprocedureManager() (which now calls close()). It's useful, even if only in test programs, to be able to shut down all existing LLCoprocedurePools without having to name them individually -- and without having to destroy the LLCoprocedureManager singleton instance. Deleting an LLSingleton should be done only once per process, whereas test programs want to reset the LLCoprocedureManager after each test. --- indra/llmessage/llcoproceduremanager.cpp | 13 +++++++++---- indra/llmessage/llcoproceduremanager.h | 1 + indra/llmessage/tests/llcoproceduremanager_test.cpp | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) (limited to 'indra/llmessage/tests/llcoproceduremanager_test.cpp') diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 712cab5b19..c1e53ea278 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -134,10 +134,7 @@ LLCoprocedureManager::LLCoprocedureManager() LLCoprocedureManager::~LLCoprocedureManager() { - for(auto & poolEntry : mPoolMap) - { - poolEntry.second->close(); - } + close(); } LLCoprocedureManager::poolPtr_t LLCoprocedureManager::initializePool(const std::string &poolName) @@ -255,6 +252,14 @@ size_t LLCoprocedureManager::count(const std::string &pool) const return it->second->count(); } +void LLCoprocedureManager::close() +{ + for(auto & poolEntry : mPoolMap) + { + poolEntry.second->close(); + } +} + void LLCoprocedureManager::close(const std::string &pool) { poolMap_t::iterator it = mPoolMap.find(pool); diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index c9b853fc4c..70204ba02b 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -77,6 +77,7 @@ public: size_t count() const; size_t count(const std::string &pool) const; + void close(); void close(const std::string &pool); private: diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 734b986f80..9db13a37b5 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -75,6 +75,11 @@ namespace tut coproceduremanager_test() { } + + ~coproceduremanager_test() + { + LLCoprocedureManager::instance().close(); + } }; typedef test_group coproceduremanager_t; typedef coproceduremanager_t::object coproceduremanager_object_t; -- cgit v1.3