From 70a0b52039a75c2c482224c9b4a6c133cac0ae76 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Sat, 23 Nov 2019 22:16:39 -0500 Subject: DRTVWR-494: Show copy-paste-friendly env vars and test command. Moderately often I want to copy the (long) integration test program path from build output and rerun the test program by hand. But typically we need environment variables set as well so it can find its dynamic libraries. This has resulted in my copying parts of several lines of build output, then pasting to a command prompt, then hand-tweaking the pasted text so it makes sense as a command. Streamline run_build_test.py output so less hand-tweaking is needed. --- indra/cmake/run_build_test.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py index 210e43b232..ec5d33f902 100755 --- a/indra/cmake/run_build_test.py +++ b/indra/cmake/run_build_test.py @@ -87,7 +87,6 @@ def main(command, arguments=[], libpath=[], vars={}): # might not exist; instead of KeyError, just use an empty string. dirs = os.environ.get(var, "").split(os.pathsep) # Append the sequence in libpath - log.info("%s += %r" % (var, libpath)) for dir in libpath: # append system paths at the end if dir in ('/lib', '/usr/lib'): @@ -105,16 +104,21 @@ def main(command, arguments=[], libpath=[], vars={}): # Now rebuild the path string. This way we use a minimum of separators # -- and we avoid adding a pointless separator when libpath is empty. os.environ[var] = os.pathsep.join(clean_dirs) - log.info("%s = %r" % (var, os.environ[var])) + # This output format is intended to make it straightforward to copy + # the variable settings and the command itself from the build output + # and paste the whole thing at a command prompt to rerun it manually. + log.info("%s='%s' \\" % (var, os.environ[var])) # Now handle arbitrary environment variables. The tricky part is ensuring # that all the keys and values we try to pass are actually strings. if vars: - log.info("Setting: %s" % ("\n".join(["%s=%s" % (key, value) for key, value in vars.iteritems()]))) + for key, value in vars.items(): + # As noted a few lines above, facilitate copy-paste rerunning. + log.info("%s='%s' \\" % (key, value)) os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()])) # Run the child process. command_list = [command] command_list.extend(arguments) - log.info("Running: %s" % " ".join(command_list)) + log.info(" ".join((("'%s'" % w) if ' ' in w else w) for w in command_list)) # Make sure we see all relevant output *before* child-process output. sys.stdout.flush() try: @@ -305,8 +309,11 @@ def get_windows_table(): return _windows_table -log=logging.getLogger(__name__) -logging.basicConfig() +# Use this instead of logging.basicConfig() because the latter prefixes +# every line of output with INFO:__main__:... +log=logging.getLogger() +log.setLevel(logging.INFO) +log.addHandler(logging.StreamHandler()) if __name__ == "__main__": import argparse -- cgit v1.3 From e849dfb9fa467f0c3e5a3352ec35ba212b9df22f Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 22 Oct 2018 14:58:23 -0400 Subject: DRTVWR-476: Update Copy3rdPartyLibs.cmake for VS 2017 version. Also, on Windows, put build output into build-vc$AUTOBUILD_VSVER-$AUTOBUILD_ADDRSIZE instead of hard-coding build-vc120-$AUTOBUILD_ADDRSIZE. --- autobuild.xml | 2 +- build.sh | 2 +- indra/cmake/Copy3rdPartyLibs.cmake | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index cbd7413034..bd92cee6a3 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3769,7 +3769,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors windows build_directory - build-vc120-$AUTOBUILD_ADDRSIZE + build-vc${AUTOBUILD_VSVER|120}-$AUTOBUILD_ADDRSIZE configurations RelWithDebInfo diff --git a/build.sh b/build.sh index e35028ad6e..545c913f92 100755 --- a/build.sh +++ b/build.sh @@ -28,7 +28,7 @@ build_dir_Linux() build_dir_CYGWIN() { - echo build-vc120-${AUTOBUILD_ADDRSIZE} + echo build-vc${AUTOBUILD_VSVER:-120}-${AUTOBUILD_ADDRSIZE} } viewer_channel_suffix() diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c73a1fdb47..a8b353ff33 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -73,7 +73,6 @@ if(WINDOWS) #******************************* # Copy MS C runtime dlls, required for packaging. - # *TODO - Adapt this to support VC9 if (MSVC80) list(APPEND LMSVC_VER 80) list(APPEND LMSVC_VERDOT 8.0) @@ -82,6 +81,9 @@ if(WINDOWS) elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 list(APPEND LMSVC_VER 120) list(APPEND LMSVC_VERDOT 12.0) + elseif (MSVC_VERSION EQUAL 1915) # Visual Studio 2017 + list(APPEND LMSVC_VER 150) + list(APPEND LMSVC_VERDOT 15.0) else (MSVC80) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") endif (MSVC80) -- cgit v1.3 From e335fde00d76b3bb3335253a766f7fc847ff5704 Mon Sep 17 00:00:00 2001 From: Anchor Date: Tue, 16 Apr 2019 19:34:06 -0700 Subject: [DRTVWR-476] - fix msvc version --- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index a8b353ff33..e121328d64 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -81,7 +81,7 @@ if(WINDOWS) elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 list(APPEND LMSVC_VER 120) list(APPEND LMSVC_VERDOT 12.0) - elseif (MSVC_VERSION EQUAL 1915) # Visual Studio 2017 + elseif (MSVC_VERSION EQUAL 1916) # Visual Studio 2017 list(APPEND LMSVC_VER 150) list(APPEND LMSVC_VERDOT 15.0) else (MSVC80) -- cgit v1.3 From 66981fab0b3c8dcc3a031d50710a2b24ec6b0603 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 10 May 2018 21:46:07 -0400 Subject: SL-793: Use Boost.Fiber instead of the "dcoroutine" library. Longtime fans will remember that the "dcoroutine" library is a Google Summer of Code project by Giovanni P. Deretta. He originally called it "Boost.Coroutine," and we originally added it to our 3p-boost autobuild package as such. But when the official Boost.Coroutine library came along (with a very different API), and we still needed the API of the GSoC project, we renamed the unofficial one "dcoroutine" to allow coexistence. The "dcoroutine" library had an internal low-level API more or less analogous to Boost.Context. We later introduced an implementation of that internal API based on Boost.Context, a step towards eliminating the GSoC code in favor of official, supported Boost code. However, recent versions of Boost.Context no longer support the API on which we built the shim for "dcoroutine." We started down the path of reimplementing that shim using the current Boost.Context API -- then realized that it's time to bite the bullet and replace the "dcoroutine" API with the Boost.Fiber API, which we've been itching to do for literally years now. Naturally, most of the heavy lifting is in llcoros.{h,cpp} and lleventcoro.{h,cpp} -- which is good: the LLCoros layer abstracts away most of the differences between "dcoroutine" and Boost.Fiber. The one feature Boost.Fiber does not provide is the ability to forcibly terminate some other fiber. Accordingly, disable LLCoros::kill() and LLCoprocedureManager::shutdown(). The only known shutdown() call was in LLCoprocedurePool's destructor. We also took the opportunity to remove postAndSuspend2() and its associated machinery: FutureListener2, LLErrorEvent, errorException(), errorLog(), LLCoroEventPumps. All that dual-LLEventPump stuff was introduced at a time when the Responder pattern was king, and we assumed we'd want to listen on one LLEventPump with the success handler and on another with the error handler. We have never actually used that in practice. Remove associated tests, of course. There is one other semantic difference that necessitates patching a number of tests: with "dcoroutine," fulfilling a future IMMEDIATELY resumes the waiting coroutine. With Boost.Fiber, fulfilling a future merely marks the fiber as ready to resume next time the scheduler gets around to it. To observe the test side effects, we've inserted a number of llcoro::suspend() calls -- also in the main loop. For a long time we retained a single unit test exercising the raw "dcoroutine" API. Remove that. Eliminate llcoro_get_id.{h,cpp}, which provided llcoro::get_id(), which was a hack to emulate fiber-local variables. Since Boost.Fiber has an actual API for that, remove the hack. In fact, use (new alias) LLCoros::local_ptr for LLSingleton's dependency tracking in place of llcoro::get_id(). In CMake land, replace BOOST_COROUTINE_LIBRARY with BOOST_FIBER_LIBRARY. We don't actually use the Boost.Coroutine for anything (though there exist plausible use cases). --- indra/cmake/Boost.cmake | 20 +- indra/cmake/LLAddBuildTest.cmake | 4 +- indra/cmake/LLAppearance.cmake | 2 +- indra/cmake/LLCommon.cmake | 4 +- indra/cmake/LLCoreHttp.cmake | 2 +- indra/linux_crash_logger/CMakeLists.txt | 2 +- indra/llcommon/CMakeLists.txt | 6 +- indra/llcommon/llcoro_get_id.cpp | 32 -- indra/llcommon/llcoro_get_id.h | 30 -- indra/llcommon/llcoros.cpp | 297 +++------- indra/llcommon/llcoros.h | 184 ++----- indra/llcommon/lleventcoro.cpp | 268 +++------ indra/llcommon/lleventcoro.h | 204 +------ indra/llcommon/llsingleton.cpp | 41 +- indra/llcommon/tests/lleventcoro_test.cpp | 598 ++------------------- indra/llmessage/CMakeLists.txt | 8 +- indra/llmessage/llcoproceduremanager.cpp | 6 + indra/llmessage/llcoproceduremanager.h | 2 + indra/llprimitive/CMakeLists.txt | 2 +- indra/llui/CMakeLists.txt | 2 +- indra/mac_crash_logger/CMakeLists.txt | 2 +- indra/newview/CMakeLists.txt | 4 +- indra/newview/llappviewer.cpp | 2 + indra/test/CMakeLists.txt | 2 +- indra/viewer_components/login/CMakeLists.txt | 4 +- .../viewer_components/login/tests/lllogin_test.cpp | 5 + indra/win_crash_logger/CMakeLists.txt | 2 +- 27 files changed, 331 insertions(+), 1404 deletions(-) delete mode 100644 indra/llcommon/llcoro_get_id.cpp delete mode 100644 indra/llcommon/llcoro_get_id.h (limited to 'indra/cmake') diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index 180a84dbcf..e05e3ca0e5 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -8,7 +8,7 @@ if (USESYSTEMLIBS) include(FindBoost) set(BOOST_CONTEXT_LIBRARY boost_context-mt) - set(BOOST_COROUTINE_LIBRARY boost_coroutine-mt) + set(BOOST_FIBER_LIBRARY boost_fiber-mt) set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt) set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt) set(BOOST_REGEX_LIBRARY boost_regex-mt) @@ -49,9 +49,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized libboost_context-mt debug libboost_context-mt-gd) - set(BOOST_COROUTINE_LIBRARY - optimized libboost_coroutine-mt - debug libboost_coroutine-mt-gd) + set(BOOST_FIBER_LIBRARY + optimized libboost_fiber-mt + debug libboost_fiber-mt-gd) set(BOOST_FILESYSTEM_LIBRARY optimized libboost_filesystem-mt debug libboost_filesystem-mt-gd) @@ -75,9 +75,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) - set(BOOST_COROUTINE_LIBRARY - optimized boost_coroutine-mt - debug boost_coroutine-mt-d) + set(BOOST_FIBER_LIBRARY + optimized boost_fiber-mt + debug boost_fiber-mt-d) set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) @@ -100,9 +100,9 @@ else (USESYSTEMLIBS) set(BOOST_CONTEXT_LIBRARY optimized boost_context-mt debug boost_context-mt-d) - set(BOOST_COROUTINE_LIBRARY - optimized boost_coroutine-mt - debug boost_coroutine-mt-d) + set(BOOST_FIBER_LIBRARY + optimized boost_fiber-mt + debug boost_fiber-mt-d) set(BOOST_FILESYSTEM_LIBRARY optimized boost_filesystem-mt debug boost_filesystem-mt-d) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index b3f42c1a5e..ee6396e473 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -53,7 +53,7 @@ INCLUDE(GoogleMock) ${GOOGLEMOCK_INCLUDE_DIRS} ) SET(alltest_LIBRARIES - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${GOOGLEMOCK_LIBRARIES} @@ -201,7 +201,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST SET(libraries ${library_dependencies} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${GOOGLEMOCK_LIBRARIES} diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake index ae265d07e3..675330ec72 100644 --- a/indra/cmake/LLAppearance.cmake +++ b/indra/cmake/LLAppearance.cmake @@ -18,7 +18,7 @@ endif (BUILD_HEADLESS) set(LLAPPEARANCE_LIBRARIES llappearance llmessage llcorehttp - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 3e29297c58..8900419f9b 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -19,7 +19,7 @@ if (LINUX) # specify all libraries that llcommon uses. # llcommon uses `clock_gettime' which is provided by librt on linux. set(LLCOMMON_LIBRARIES llcommon - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} @@ -27,7 +27,7 @@ if (LINUX) ) else (LINUX) set(LLCOMMON_LIBRARIES llcommon - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ) diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake index 379ae207de..613453ab5d 100644 --- a/indra/cmake/LLCoreHttp.cmake +++ b/indra/cmake/LLCoreHttp.cmake @@ -12,6 +12,6 @@ set(LLCOREHTTP_INCLUDE_DIRS ) set(LLCOREHTTP_LIBRARIES llcorehttp - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY}) diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt index 315aed8d11..d789c850a0 100644 --- a/indra/linux_crash_logger/CMakeLists.txt +++ b/indra/linux_crash_logger/CMakeLists.txt @@ -69,7 +69,7 @@ target_link_libraries(linux-crash-logger ${LLMATH_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${UI_LIBRARIES} ${DB_LIBRARIES} diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 55c44446b4..2f263cd830 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -44,7 +44,6 @@ set(llcommon_SOURCE_FILES llcleanup.cpp llcommon.cpp llcommonutils.cpp - llcoro_get_id.cpp llcoros.cpp llcrc.cpp llcriticaldamp.cpp @@ -146,7 +145,6 @@ set(llcommon_HEADER_FILES llcleanup.h llcommon.h llcommonutils.h - llcoro_get_id.h llcoros.h llcrc.h llcriticaldamp.h @@ -293,7 +291,7 @@ target_link_libraries( ${JSONCPP_LIBRARIES} ${ZLIB_LIBRARIES} ${WINDOWS_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} @@ -322,7 +320,7 @@ if (LL_TESTS) ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES} ${GOOGLEMOCK_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_THREAD_LIBRARY} ${BOOST_SYSTEM_LIBRARY}) diff --git a/indra/llcommon/llcoro_get_id.cpp b/indra/llcommon/llcoro_get_id.cpp deleted file mode 100644 index 24ed1fe0c9..0000000000 --- a/indra/llcommon/llcoro_get_id.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * @file llcoro_get_id.cpp - * @author Nat Goodspeed - * @date 2016-09-03 - * @brief Implementation for llcoro_get_id. - * - * $LicenseInfo:firstyear=2016&license=viewerlgpl$ - * Copyright (c) 2016, Linden Research, Inc. - * $/LicenseInfo$ - */ - -// Precompiled header -#include "linden_common.h" -// associated header -#include "llcoro_get_id.h" -// STL headers -// std headers -// external library headers -// other Linden headers -#include "llcoros.h" - -namespace llcoro -{ - -id get_id() -{ - // An instance of Current can convert to LLCoros::CoroData*, which can - // implicitly convert to void*, which is an llcoro::id. - return LLCoros::Current(); -} - -} // llcoro diff --git a/indra/llcommon/llcoro_get_id.h b/indra/llcommon/llcoro_get_id.h deleted file mode 100644 index 4c1dca6f19..0000000000 --- a/indra/llcommon/llcoro_get_id.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @file llcoro_get_id.h - * @author Nat Goodspeed - * @date 2016-09-03 - * @brief Supplement the functionality in llcoro.h. - * - * This is broken out as a separate header file to resolve - * circularity: LLCoros isa LLSingleton, yet LLSingleton machinery - * requires llcoro::get_id(). - * - * Be very suspicious of anyone else #including this header. - * - * $LicenseInfo:firstyear=2016&license=viewerlgpl$ - * Copyright (c) 2016, Linden Research, Inc. - * $/LicenseInfo$ - */ - -#if ! defined(LL_LLCORO_GET_ID_H) -#define LL_LLCORO_GET_ID_H - -namespace llcoro -{ - -/// Get an opaque, distinct token for the running coroutine (or main). -typedef void* id; -id get_id(); - -} // llcoro - -#endif /* ! defined(LL_LLCORO_GET_ID_H) */ diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index cc775775bf..f5ffd96cec 100644 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -34,6 +34,17 @@ // std headers // external library headers #include +#include +#ifndef BOOST_DISABLE_ASSERTS +#define UNDO_BOOST_DISABLE_ASSERTS +// with Boost 1.65.1, needed for Mac with this specific header +#define BOOST_DISABLE_ASSERTS +#endif +#include +#ifdef UNDO_BOOST_DISABLE_ASSERTS +#undef UNDO_BOOST_DISABLE_ASSERTS +#undef BOOST_DISABLE_ASSERTS +#endif // other Linden headers #include "lltimer.h" #include "llevents.h" @@ -45,176 +56,69 @@ #include #endif -namespace { -void no_op() {} -} // anonymous namespace -// Do nothing, when we need nothing done. This is a static member of LLCoros -// because CoroData is a private nested class. -void LLCoros::no_cleanup(CoroData*) {} - -// CoroData for the currently-running coroutine. Use a thread_specific_ptr -// because each thread potentially has its own distinct pool of coroutines. -LLCoros::Current::Current() +const LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) const { - // Use a function-static instance so this thread_specific_ptr is - // instantiated on demand. Since we happen to know it's consumed by - // LLSingleton, this is likely to happen before the runtime has finished - // initializing module-static data. For the same reason, we can't package - // this pointer in an LLSingleton. - - // This thread_specific_ptr does NOT own the CoroData object! That's owned - // by LLCoros::mCoros. It merely identifies it. For this reason we - // instantiate it with a no-op cleanup function. - static boost::thread_specific_ptr sCurrent(LLCoros::no_cleanup); - - // If this is the first time we're accessing sCurrent for the running - // thread, its get() will be NULL. This could be a problem, in that - // llcoro::get_id() would return the same (NULL) token value for the "main - // coroutine" in every thread, whereas what we really want is a distinct - // value for every distinct stack in the process. So if get() is NULL, - // give it a heap CoroData: this ensures that llcoro::get_id() will return - // distinct values. - // This tactic is "leaky": sCurrent explicitly does not destroy any - // CoroData to which it points, and we do NOT enter these "main coroutine" - // CoroData instances in the LLCoros::mCoros map. They are dummy entries, - // and they will leak at process shutdown: one CoroData per thread. - if (! sCurrent.get()) + CoroData* current = mCurrent.get(); + // For the main() coroutine, the one NOT explicitly launched by launch(), + // we never explicitly set mCurrent. Use a static CoroData instance with + // canonical values. + if (! current) { // It's tempting to provide a distinct name for each thread's "main // coroutine." But as getName() has always returned the empty string - // to mean "not in a coroutine," empty string should suffice here -- - // and truthfully the additional (thread-safe!) machinery to ensure - // uniqueness just doesn't feel worth the trouble. - // We use a no-op callable and a minimal stack size because, although - // CoroData's constructor in fact initializes its mCoro with a - // coroutine with that stack size, no one ever actually enters it by - // calling mCoro(). - sCurrent.reset(new CoroData(0, // no prev - "", // not a named coroutine - no_op, // no-op callable - 1024)); // stacksize moot + // to mean "not in a coroutine," empty string should suffice here. + static CoroData sMain(""); + // We need not reset() the local_ptr to this read-only data: reuse the + // same instance for every thread's main coroutine. + current = &sMain; } - - mCurrent = &sCurrent; + return *current; } -//static LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller) { - CoroData* current = Current(); - // With the dummy CoroData set in LLCoros::Current::Current(), this - // pointer should never be NULL. - llassert_always(current); - return *current; + // reuse const implementation, just cast away const-ness of result + return const_cast(const_cast(this)->get_CoroData(caller)); } //static -LLCoros::coro::self& LLCoros::get_self() +LLCoros::coro::id LLCoros::get_self() { - CoroData& current = get_CoroData("get_self()"); - if (! current.mSelf) - { - LL_ERRS("LLCoros") << "Calling get_self() from non-coroutine context!" << LL_ENDL; - } - return *current.mSelf; + return boost::this_fiber::get_id(); } //static void LLCoros::set_consuming(bool consuming) { - get_CoroData("set_consuming()").mConsuming = consuming; + CoroData& data(LLCoros::instance().get_CoroData("set_consuming()")); + // DO NOT call this on the main() coroutine. + llassert_always(! data.mName.empty()); + data.mConsuming = consuming; } //static bool LLCoros::get_consuming() { - return get_CoroData("get_consuming()").mConsuming; -} - -llcoro::Suspending::Suspending() -{ - LLCoros::Current current; - // Remember currently-running coroutine: we're about to suspend it. - mSuspended = current; - // Revert Current to the value it had at the moment we last switched - // into this coroutine. - current.reset(mSuspended->mPrev); -} - -llcoro::Suspending::~Suspending() -{ - LLCoros::Current current; - // Okay, we're back, update our mPrev - mSuspended->mPrev = current; - // and reinstate our Current. - current.reset(mSuspended); + return LLCoros::instance().get_CoroData("get_consuming()").mConsuming; } LLCoros::LLCoros(): // MAINT-2724: default coroutine stack size too small on Windows. // Previously we used // boost::context::guarded_stack_allocator::default_stacksize(); - // empirically this is 64KB on Windows and Linux. Try quadrupling. + // empirically this is insufficient. #if ADDRESS_SIZE == 64 mStackSize(512*1024) #else mStackSize(256*1024) #endif { - // Register our cleanup() method for "mainloop" ticks - LLEventPumps::instance().obtain("mainloop").listen( - "LLCoros", boost::bind(&LLCoros::cleanup, this, _1)); -} - -bool LLCoros::cleanup(const LLSD&) -{ - static std::string previousName; - static int previousCount = 0; - // Walk the mCoros map, checking and removing completed coroutines. - for (CoroMap::iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; ) - { - // Has this coroutine exited (normal return, exception, exit() call) - // since last tick? - if (mi->second->mCoro.exited()) - { - if (previousName != mi->first) - { - previousName = mi->first; - previousCount = 1; - } - else - { - ++previousCount; - } - - if ((previousCount < 5) || !(previousCount % 50)) - { - if (previousCount < 5) - LL_DEBUGS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << LL_ENDL; - else - LL_DEBUGS("LLCoros") << "LLCoros: cleaning up coroutine " << mi->first << "("<< previousCount << ")" << LL_ENDL; - - } - // The erase() call will invalidate its passed iterator value -- - // so increment mi FIRST -- but pass its original value to - // erase(). This is what postincrement is all about. - mCoros.erase(mi++); - } - else - { - // Still live, just skip this entry as if incrementing at the top - // of the loop as usual. - ++mi; - } - } - return false; } std::string LLCoros::generateDistinctName(const std::string& prefix) const { - static std::string previousName; - static int previousCount = 0; + static int unique = 0; // Allowing empty name would make getName()'s not-found return ambiguous. if (prefix.empty()) @@ -225,37 +129,15 @@ std::string LLCoros::generateDistinctName(const std::string& prefix) const // If the specified name isn't already in the map, just use that. std::string name(prefix); - // Find the lowest numeric suffix that doesn't collide with an existing - // entry. Start with 2 just to make it more intuitive for any interested - // parties: e.g. "joe", "joe2", "joe3"... - for (int i = 2; ; name = STRINGIZE(prefix << i++)) + // Until we find an unused name, append a numeric suffix for uniqueness. + while (mCoros.find(name) != mCoros.end()) { - if (mCoros.find(name) == mCoros.end()) - { - if (previousName != name) - { - previousName = name; - previousCount = 1; - } - else - { - ++previousCount; - } - - if ((previousCount < 5) || !(previousCount % 50)) - { - if (previousCount < 5) - LL_DEBUGS("LLCoros") << "LLCoros: launching coroutine " << name << LL_ENDL; - else - LL_DEBUGS("LLCoros") << "LLCoros: launching coroutine " << name << "(" << previousCount << ")" << LL_ENDL; - - } - - return name; - } + name = STRINGIZE(prefix << unique++); } + return name; } +/*==========================================================================*| bool LLCoros::kill(const std::string& name) { CoroMap::iterator found = mCoros.find(name); @@ -269,10 +151,11 @@ bool LLCoros::kill(const std::string& name) mCoros.erase(found); return true; } +|*==========================================================================*/ std::string LLCoros::getName() const { - return Current()->mName; + return get_CoroData("getName()").mName; } void LLCoros::setStackSize(S32 stacksize) @@ -300,6 +183,27 @@ void LLCoros::printActiveCoroutines() } } +std::string LLCoros::launch(const std::string& prefix, const callable_t& callable) +{ + std::string name(generateDistinctName(prefix)); + // 'dispatch' means: enter the new fiber immediately, returning here only + // when the fiber yields for whatever reason. + // std::allocator_arg is a flag to indicate that the following argument is + // a StackAllocator. + // protected_fixedsize_stack sets a guard page past the end of the new + // stack so that stack underflow will result in an access violation + // instead of weird, subtle, possibly undiagnosed memory stomps. + boost::fibers::fiber newCoro(boost::fibers::launch::dispatch, + std::allocator_arg, + boost::fibers::protected_fixedsize_stack(mStackSize), + [this, &name, &callable](){ toplevel(name, callable); }); + // You have two choices with a fiber instance: you can join() it or you + // can detach() it. If you try to destroy the instance before doing + // either, the program silently terminates. We don't need this handle. + newCoro.detach(); + return name; +} + #if LL_WINDOWS static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific @@ -340,10 +244,14 @@ void LLCoros::winlevel(const callable_t& callable) // Top-level wrapper around caller's coroutine callable. This function accepts // the coroutine library's implicit coro::self& parameter and saves it, but // does not pass it down to the caller's callable. -void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& callable) +void LLCoros::toplevel(const std::string& name, const callable_t& callable) { - // capture the 'self' param in CoroData - data->mSelf = &self; + CoroData* corodata = new CoroData(name); + // Store it in our pointer map. Oddly, must cast away const-ness of key. + mCoros.insert(const_cast(name), corodata); + // also set it as current + mCurrent.reset(corodata); + // run the code the caller actually wants in the coroutine try { @@ -358,70 +266,41 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla // Any uncaught exception derived from LLContinueError will be caught // here and logged. This coroutine will terminate but the rest of the // viewer will carry on. - LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); + LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << corodata->mName)); } catch (...) { // Any OTHER kind of uncaught exception will cause the viewer to // crash, hopefully informatively. - CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName)); + CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << corodata->mName)); } - // This cleanup isn't perfectly symmetrical with the way we initially set - // data->mPrev, but this is our last chance to reset Current. - Current().reset(data->mPrev); } -/***************************************************************************** -* MUST BE LAST -*****************************************************************************/ -// Turn off MSVC optimizations for just LLCoros::launch() -- see -// DEV-32777. But MSVC doesn't support push/pop for optimization flags as it -// does for warning suppression, and we really don't want to force -// optimization ON for other code even in Debug or RelWithDebInfo builds. - -#if LL_MSVC -// work around broken optimizations -#pragma warning(disable: 4748) -#pragma warning(disable: 4355) // 'this' used in initializer list: yes, intentionally -#pragma optimize("", off) -#endif // LL_MSVC - -LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name, - const callable_t& callable, S32 stacksize): - mPrev(prev), +LLCoros::CoroData::CoroData(const std::string& name): mName(name), - // Wrap the caller's callable in our toplevel() function so we can manage - // Current appropriately at startup and shutdown of each coroutine. - mCoro(boost::bind(toplevel, _1, this, callable), stacksize), // don't consume events unless specifically directed mConsuming(false), - mSelf(0), mCreationTime(LLTimer::getTotalSeconds()) { } -std::string LLCoros::launch(const std::string& prefix, const callable_t& callable) +void LLCoros::delete_CoroData(CoroData* cdptr) { - std::string name(generateDistinctName(prefix)); - Current current; - // pass the current value of Current as previous context - CoroData* newCoro = new(std::nothrow) CoroData(current, name, callable, mStackSize); - if (newCoro == NULL) + // This custom cleanup function is necessarily static. Find and bind the + // LLCoros instance. + LLCoros& self(LLCoros::instance()); + // We set mCurrent on entry to a new fiber, expecting that the + // corresponding entry has already been stored in mCoros. It is an + // error if we do not find that entry. + CoroMap::iterator found = self.mCoros.find(cdptr->mName); + if (found == self.mCoros.end()) { - // Out of memory? - printActiveCoroutines(); - LL_ERRS("LLCoros") << "Failed to start coroutine: " << name << " Stacksize: " << mStackSize << " Total coroutines: " << mCoros.size() << LL_ENDL; + LL_ERRS("LLCoros") << "Coroutine '" << cdptr->mName << "' terminated " + << "without being stored in LLCoros::mCoros" + << LL_ENDL; } - // Store it in our pointer map - mCoros.insert(name, newCoro); - // also set it as current - current.reset(newCoro); - /* Run the coroutine until its first wait, then return here */ - (newCoro->mCoro)(std::nothrow); - return name; -} -#if LL_MSVC -// reenable optimizations -#pragma optimize("", on) -#endif // LL_MSVC + // Oh good, we found the mCoros entry. Erase it. Because it's a ptr_map, + // that will implicitly delete this CoroData. + self.mCoros.erase(found); +} diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index c551413811..678633497d 100644 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -29,22 +29,13 @@ #if ! defined(LL_LLCOROS_H) #define LL_LLCOROS_H -#include -#include +#include +#include +#include #include "llsingleton.h" #include #include -#include -#include #include -#include -#include "llcoro_get_id.h" // for friend declaration - -// forward-declare helper class -namespace llcoro -{ -class Suspending; -} /** * Registry of named Boost.Coroutine instances @@ -76,19 +67,20 @@ class Suspending; * name prefix; from your prefix it generates a distinct name, registers the * new coroutine and returns the actual name. * - * The name can be used to kill off the coroutine prematurely, if needed. It - * can also provide diagnostic info: we can look up the name of the + * The name + * can provide diagnostic info: we can look up the name of the * currently-running coroutine. - * - * Finally, the next frame ("mainloop" event) after the coroutine terminates, - * LLCoros will notice its demise and destroy it. */ class LL_COMMON_API LLCoros: public LLSingleton { LLSINGLETON(LLCoros); public: - /// Canonical boost::dcoroutines::coroutine signature we use - typedef boost::dcoroutines::coroutine coro; + /// The viewer's use of the term "coroutine" became deeply embedded before + /// the industry term "fiber" emerged to distinguish userland threads from + /// simpler, more transient kinds of coroutines. Semantically they've + /// always been fibers. But at this point in history, we're pretty much + /// stuck with the term "coroutine." + typedef boost::fibers::fiber coro; /// Canonical callable type typedef boost::function callable_t; @@ -119,10 +111,10 @@ public: * DEV-32777 comments for an explanation. * * Pass a nullary callable. It works to directly pass a nullary free - * function (or static method); for all other cases use boost::bind(). Of - * course, for a non-static class method, the first parameter must be the - * class instance. Any other parameters should be passed via the bind() - * expression. + * function (or static method); for other cases use a lambda expression, + * std::bind() or boost::bind(). Of course, for a non-static class method, + * the first parameter must be the class instance. Any other parameters + * should be passed via the enclosing expression. * * launch() tweaks the suggested name so it won't collide with any * existing coroutine instance, creates the coroutine instance, registers @@ -138,7 +130,7 @@ public: * one prematurely. Returns @c true if the specified name was found and * still running at the time. */ - bool kill(const std::string& name); +// bool kill(const std::string& name); /** * From within a coroutine, look up the (tweaked) name string by which @@ -148,14 +140,18 @@ public: */ std::string getName() const; - /// for delayed initialization + /** + * For delayed initialization. To be clear, this will only affect + * coroutines launched @em after this point. The underlying facility + * provides no way to alter the stack size of any running coroutine. + */ void setStackSize(S32 stacksize); /// for delayed initialization void printActiveCoroutines(); - /// get the current coro::self& for those who really really care - static coro::self& get_self(); + /// get the current coro::id for those who really really care + static coro::id get_self(); /** * Most coroutines, most of the time, don't "consume" the events for which @@ -190,141 +186,57 @@ public: }; /** - * Please do NOT directly use boost::dcoroutines::future! It is essential - * to maintain the "current" coroutine at every context switch. This - * Future wraps the essential boost::dcoroutines::future functionality - * with that maintenance. + * Aliases for promise and future. An older underlying future implementation + * required us to wrap future; that's no longer needed. However -- if it's + * important to restore kill() functionality, we might need to provide a + * proxy, so continue using the aliases. */ template - class Future; + using Promise = boost::fibers::promise; + template + using Future = boost::fibers::future; + template + static Future getFuture(Promise& promise) { return promise.get_future(); } + + /// for data local to each running coroutine + template + using local_ptr = boost::fibers::fiber_specific_ptr; private: - friend class llcoro::Suspending; - friend llcoro::id llcoro::get_id(); std::string generateDistinctName(const std::string& prefix) const; - bool cleanup(const LLSD&); + void toplevel(const std::string& name, const callable_t& callable); struct CoroData; - static void no_cleanup(CoroData*); #if LL_WINDOWS static void winlevel(const callable_t& callable); #endif - static void toplevel(coro::self& self, CoroData* data, const callable_t& callable); - static CoroData& get_CoroData(const std::string& caller); + CoroData& get_CoroData(const std::string& caller); + const CoroData& get_CoroData(const std::string& caller) const; S32 mStackSize; // coroutine-local storage, as it were: one per coro we track struct CoroData { - CoroData(CoroData* prev, const std::string& name, - const callable_t& callable, S32 stacksize); + CoroData(const std::string& name); - // The boost::dcoroutines library supports asymmetric coroutines. Every - // time we context switch out of a coroutine, we pass control to the - // previously-active one (or to the non-coroutine stack owned by the - // thread). So our management of the "current" coroutine must be able to - // restore the previous value when we're about to switch away. - CoroData* mPrev; // tweaked name of the current coroutine const std::string mName; - // the actual coroutine instance - LLCoros::coro mCoro; // set_consuming() state bool mConsuming; - // When the dcoroutine library calls a top-level callable, it implicitly - // passes coro::self& as the first parameter. All our consumer code used - // to explicitly pass coro::self& down through all levels of call stack, - // because at the leaf level we need it for context-switching. But since - // coroutines are based on cooperative switching, we can cause the - // top-level entry point to stash a pointer to the currently-running - // coroutine, and manage it appropriately as we switch out and back in. - // That eliminates the need to pass it as an explicit parameter down - // through every level, which is unfortunately viral in nature. Finding it - // implicitly rather than explicitly allows minor maintenance in which a - // leaf-level function adds a new async I/O call that suspends the calling - // coroutine, WITHOUT having to propagate coro::self& through every - // function signature down to that point -- and of course through every - // other caller of every such function. - LLCoros::coro::self* mSelf; F64 mCreationTime; // since epoch }; typedef boost::ptr_map CoroMap; CoroMap mCoros; - // Identify the current coroutine's CoroData. Use a little helper class so - // a caller can either use a temporary instance, or instantiate a named - // variable and access it multiple times. - class Current - { - public: - Current(); - - operator LLCoros::CoroData*() { return get(); } - LLCoros::CoroData* operator->() { return get(); } - LLCoros::CoroData* get() { return mCurrent->get(); } - void reset(LLCoros::CoroData* ptr) { mCurrent->reset(ptr); } - - private: - boost::thread_specific_ptr* mCurrent; - }; -}; - -namespace llcoro -{ + // Identify the current coroutine's CoroData. This local_ptr isn't static + // because it's a member of an LLSingleton, and we rely on it being + // cleaned up in proper dependency order. + // As each coroutine terminates, use our custom cleanup function to remove + // the corresponding entry from mCoros. + local_ptr mCurrent{delete_CoroData}; -/// Instantiate one of these in a block surrounding any leaf point when -/// control literally switches away from this coroutine. -class Suspending: boost::noncopyable -{ -public: - Suspending(); - ~Suspending(); - -private: - LLCoros::CoroData* mSuspended; -}; - -} // namespace llcoro - -template -class LLCoros::Future -{ - typedef boost::dcoroutines::future dfuture; - -public: - Future(): - mFuture(get_self()) - {} - - typedef typename boost::dcoroutines::make_callback_result::type callback_t; - - callback_t make_callback() - { - return boost::dcoroutines::make_callback(mFuture); - } - -#ifndef LL_LINUX - explicit -#endif - operator bool() const - { - return bool(mFuture); - } - - bool operator!() const - { - return ! mFuture; - } - - T get() - { - // instantiate Suspending to manage the "current" coroutine - llcoro::Suspending suspended; - return *mFuture; - } - -private: - dfuture mFuture; + // Cleanup function for each fiber's instance of mCurrent. + static void delete_CoroData(CoroData* cdptr); }; #endif /* ! defined(LL_LLCOROS_H) */ diff --git a/indra/llcommon/lleventcoro.cpp b/indra/llcommon/lleventcoro.cpp index 43e41f250d..47d99f0050 100644 --- a/indra/llcommon/lleventcoro.cpp +++ b/indra/llcommon/lleventcoro.cpp @@ -31,18 +31,15 @@ // associated header #include "lleventcoro.h" // STL headers -#include +#include // std headers // external library headers +#include // other Linden headers #include "llsdserialize.h" #include "llsdutil.h" #include "llerror.h" #include "llcoros.h" -#include "llmake.h" -#include "llexception.h" - -#include "lleventfilter.h" namespace { @@ -105,65 +102,47 @@ void storeToLLSDPath(LLSD& dest, const LLSD& path, const LLSD& value) llsd::drill(dest, path) = value; } -/// For LLCoros::Future::make_callback(), the callback has a signature -/// like void callback(LLSD), which isn't a valid LLEventPump listener: such -/// listeners must return bool. -template -class FutureListener -{ -public: - // FutureListener is instantiated on the coroutine stack: the stack, in - // other words, that wants to suspend. - FutureListener(const LISTENER& listener): - mListener(listener), - // Capture the suspending coroutine's flag as a consuming or - // non-consuming listener. - mConsume(LLCoros::get_consuming()) - {} - - // operator()() is called on the main stack: the stack on which the - // expected event is fired. - bool operator()(const LLSD& event) - { - mListener(event); - // tell upstream LLEventPump whether listener consumed - return mConsume; - } - -protected: - LISTENER mListener; - bool mConsume; -}; - } // anonymous void llcoro::suspend() { - // By viewer convention, we post an event on the "mainloop" LLEventPump - // each iteration of the main event-handling loop. So waiting for a single - // event on "mainloop" gives us a one-frame suspend. - suspendUntilEventOn("mainloop"); + boost::this_fiber::yield(); } void llcoro::suspendUntilTimeout(float seconds) { - LLEventTimeout timeout; - - timeout.eventAfter(seconds, LLSD()); - llcoro::suspendUntilEventOn(timeout); + // The fact that we accept non-integer seconds means we should probably + // use granularity finer than one second. However, given the overhead of + // the rest of our processing, it seems silly to use granularity finer + // than a millisecond. + boost::this_fiber::sleep_for(std::chrono::milliseconds(long(seconds * 1000))); } -LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump, - const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath) +namespace { - // declare the future - LLCoros::Future future; + +LLBoundListener postAndSuspendSetup(const std::string& callerName, + const std::string& listenerName, + LLCoros::Promise& promise, + const LLSD& event, + const LLEventPumpOrPumpName& requestPump, + const LLEventPumpOrPumpName& replyPump, + const LLSD& replyPumpNamePath) +{ + // Get the consuming attribute for THIS coroutine, the one that's about to + // suspend. Don't call get_consuming() in the lambda body: that would + // return the consuming attribute for some other coroutine, most likely + // the main routine. + bool consuming(LLCoros::get_consuming()); // make a callback that will assign a value to the future, and listen on // the specified LLEventPump with that callback - std::string listenerName(listenerNameForCoro()); - LLTempBoundListener connection( + LLBoundListener connection( replyPump.getPump().listen(listenerName, - llmake(future.make_callback()))); + [&promise, consuming](const LLSD& result) + { + promise.set_value(result); + return consuming; + })); // skip the "post" part if requestPump is default-constructed if (requestPump) { @@ -171,7 +150,7 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ // request event. LLSD modevent(event); storeToLLSDPath(modevent, replyPumpNamePath, replyPump.getPump().getName()); - LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName + LL_DEBUGS("lleventcoro") << callerName << ": coroutine " << listenerName << " posting to " << requestPump.getPump().getName() << LL_ENDL; @@ -179,158 +158,73 @@ LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requ // << ": " << modevent << LL_ENDL; requestPump.getPump().post(modevent); } - LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName + LL_DEBUGS("lleventcoro") << callerName << ": coroutine " << listenerName << " about to wait on LLEventPump " << replyPump.getPump().getName() << LL_ENDL; - // calling get() on the future makes us wait for it - LLSD value(future.get()); - LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName - << " resuming with " << value << LL_ENDL; - // returning should disconnect the connection - return value; -} - -LLSD llcoro::suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, - F32 timeoutin, const LLSD &timeoutResult) -{ - /** - * The timeout pump is attached upstream of of the waiting pump and will - * pass the timeout event through it. We CAN NOT attach downstream since - * doing so will cause the suspendPump to fire any waiting events immediately - * and they will be lost. This becomes especially problematic with the - * LLEventTimeout(pump) constructor which will also attempt to fire those - * events using the virtual listen_impl method in the not yet fully constructed - * timeoutPump. - */ - LLEventTimeout timeoutPump; - LLEventPump &suspendPump = suspendPumpOrName.getPump(); - - LLTempBoundListener timeoutListener(timeoutPump.listen(suspendPump.getName(), - boost::bind(&LLEventPump::post, &suspendPump, _1))); - - timeoutPump.eventAfter(timeoutin, timeoutResult); - return llcoro::suspendUntilEventOn(suspendPump); + return connection; } -namespace -{ - -/** - * This helper is specifically for postAndSuspend2(). We use a single future - * object, but we want to listen on two pumps with it. Since we must still - * adapt from the callable constructed by boost::dcoroutines::make_callback() - * (void return) to provide an event listener (bool return), we've adapted - * FutureListener for the purpose. The basic idea is that we construct a - * distinct instance of FutureListener2 -- binding different instance data -- - * for each of the pumps. Then, when a pump delivers an LLSD value to either - * FutureListener2, it can combine that LLSD with its discriminator to feed - * the future object. - * - * DISCRIM is a template argument so we can use llmake() rather than - * having to write our own argument-deducing helper function. - */ -template -class FutureListener2: public FutureListener -{ - typedef FutureListener super; - -public: - // instantiated on coroutine stack: the stack about to suspend - FutureListener2(const LISTENER& listener, DISCRIM discriminator): - super(listener), - mDiscrim(discriminator) - {} - - // called on main stack: the stack on which event is fired - bool operator()(const LLSD& event) - { - // our future object is defined to accept LLEventWithID - super::mListener(LLEventWithID(event, mDiscrim)); - // tell LLEventPump whether or not event was consumed - return super::mConsume; - } - -private: - const DISCRIM mDiscrim; -}; - } // anonymous -namespace llcoro +LLSD llcoro::postAndSuspend(const LLSD& event, const LLEventPumpOrPumpName& requestPump, + const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath) { + LLCoros::Promise promise; + std::string listenerName(listenerNameForCoro()); + + // Store connection into an LLTempBoundListener so we implicitly + // disconnect on return from this function. + LLTempBoundListener connection = + postAndSuspendSetup("postAndSuspend()", listenerName, promise, + event, requestPump, replyPump, replyPumpNamePath); -LLEventWithID postAndSuspend2(const LLSD& event, - const LLEventPumpOrPumpName& requestPump, - const LLEventPumpOrPumpName& replyPump0, - const LLEventPumpOrPumpName& replyPump1, - const LLSD& replyPump0NamePath, - const LLSD& replyPump1NamePath) -{ // declare the future - LLCoros::Future future; - // either callback will assign a value to this future; listen on - // each specified LLEventPump with a callback - std::string name(listenerNameForCoro()); - LLTempBoundListener connection0( - replyPump0.getPump().listen( - name + "a", - llmake(future.make_callback(), 0))); - LLTempBoundListener connection1( - replyPump1.getPump().listen( - name + "b", - llmake(future.make_callback(), 1))); - // skip the "post" part if requestPump is default-constructed - if (requestPump) - { - // If either replyPumpNamePath is non-empty, store the corresponding - // replyPump name in the request event. - LLSD modevent(event); - storeToLLSDPath(modevent, replyPump0NamePath, - replyPump0.getPump().getName()); - storeToLLSDPath(modevent, replyPump1NamePath, - replyPump1.getPump().getName()); - LL_DEBUGS("lleventcoro") << "postAndSuspend2(): coroutine " << name - << " posting to " << requestPump.getPump().getName() - << ": " << modevent << LL_ENDL; - requestPump.getPump().post(modevent); - } - LL_DEBUGS("lleventcoro") << "postAndSuspend2(): coroutine " << name - << " about to wait on LLEventPumps " << replyPump0.getPump().getName() - << ", " << replyPump1.getPump().getName() << LL_ENDL; + LLCoros::Future future = LLCoros::getFuture(promise); // calling get() on the future makes us wait for it - LLEventWithID value(future.get()); - LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << name - << " resuming with (" << value.first << ", " << value.second << ")" - << LL_ENDL; - // returning should disconnect both connections + LLSD value(future.get()); + LL_DEBUGS("lleventcoro") << "postAndSuspend(): coroutine " << listenerName + << " resuming with " << value << LL_ENDL; + // returning should disconnect the connection return value; } -LLSD errorException(const LLEventWithID& result, const std::string& desc) +LLSD llcoro::postAndSuspendWithTimeout(const LLSD& event, + const LLEventPumpOrPumpName& requestPump, + const LLEventPumpOrPumpName& replyPump, + const LLSD& replyPumpNamePath, + F32 timeout, const LLSD& timeoutResult) { - // If the result arrived on the error pump (pump 1), instead of - // returning it, deliver it via exception. - if (result.second) + LLCoros::Promise promise; + std::string listenerName(listenerNameForCoro()); + + // Store connection into an LLTempBoundListener so we implicitly + // disconnect on return from this function. + LLTempBoundListener connection = + postAndSuspendSetup("postAndSuspendWithTimeout()", listenerName, promise, + event, requestPump, replyPump, replyPumpNamePath); + + // declare the future + LLCoros::Future future = LLCoros::getFuture(promise); + // wait for specified timeout + boost::fibers::future_status status = + future.wait_for(std::chrono::milliseconds(long(timeout * 1000))); + // if the future is NOT yet ready, return timeoutResult instead + if (status == boost::fibers::future_status::timeout) { - LLTHROW(LLErrorEvent(desc, result.first)); + LL_DEBUGS("lleventcoro") << "postAndSuspendWithTimeout(): coroutine " << listenerName + << " timed out after " << timeout << " seconds," + << " resuming with " << timeoutResult << LL_ENDL; + return timeoutResult; } - // That way, our caller knows a simple return must be from the reply - // pump (pump 0). - return result.first; -} - -LLSD errorLog(const LLEventWithID& result, const std::string& desc) -{ - // If the result arrived on the error pump (pump 1), log it as a fatal - // error. - if (result.second) + else { - LL_ERRS("errorLog") << desc << ":" << std::endl; - LLSDSerialize::toPrettyXML(result.first, LL_CONT); - LL_CONT << LL_ENDL; + llassert_always(status == boost::fibers::future_status::ready); + + // future is now ready, no more waiting + LLSD value(future.get()); + LL_DEBUGS("lleventcoro") << "postAndSuspendWithTimeout(): coroutine " << listenerName + << " resuming with " << value << LL_ENDL; + // returning should disconnect the connection + return value; } - // A simple return must therefore be from the reply pump (pump 0). - return result.first; } - -} // namespace llcoro diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 84827aab4a..c0fe8b094f 100644 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -29,12 +29,8 @@ #if ! defined(LL_LLEVENTCORO_H) #define LL_LLEVENTCORO_H -#include #include -#include // std::pair #include "llevents.h" -#include "llerror.h" -#include "llexception.h" /** * Like LLListenerOrPumpName, this is a class intended for parameter lists: @@ -147,117 +143,29 @@ LLSD suspendUntilEventOn(const LLEventPumpOrPumpName& pump) return postAndSuspend(LLSD(), LLEventPumpOrPumpName(), pump); } +/// Like postAndSuspend(), but if we wait longer than @a timeout seconds, +/// stop waiting and return @a timeoutResult instead. +LLSD postAndSuspendWithTimeout(const LLSD& event, + const LLEventPumpOrPumpName& requestPump, + const LLEventPumpOrPumpName& replyPump, + const LLSD& replyPumpNamePath, + F32 timeout, const LLSD& timeoutResult); + /// Suspend the coroutine until an event is fired on the identified pump /// or the timeout duration has elapsed. If the timeout duration /// elapses the specified LLSD is returned. -LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, F32 timeoutin, const LLSD &timeoutResult); - -} // namespace llcoro - -/// return type for two-pump variant of suspendUntilEventOn() -typedef std::pair LLEventWithID; - -namespace llcoro -{ - -/** - * This function waits for a reply on either of two specified LLEventPumps. - * Otherwise, it closely resembles postAndSuspend(); please see the documentation - * for that function for detailed parameter info. - * - * While we could have implemented the single-pump variant in terms of this - * one, there's enough added complexity here to make it worthwhile to give the - * single-pump variant its own straightforward implementation. Conversely, - * though we could use preprocessor logic to generate n-pump overloads up to - * BOOST_COROUTINE_WAIT_MAX, we don't foresee a use case. This two-pump - * overload exists because certain event APIs are defined in terms of a reply - * LLEventPump and an error LLEventPump. - * - * The LLEventWithID return value provides not only the received event, but - * the index of the pump on which it arrived (0 or 1). - * - * @note - * I'd have preferred to overload the name postAndSuspend() for both signatures. - * But consider the following ambiguous call: - * @code - * postAndSuspend(LLSD(), requestPump, replyPump, "someString"); - * @endcode - * "someString" could be converted to either LLSD (@a replyPumpNamePath for - * the single-pump function) or LLEventOrPumpName (@a replyPump1 for two-pump - * function). - * - * It seems less burdensome to write postAndSuspend2() than to write either - * LLSD("someString") or LLEventOrPumpName("someString"). - */ -LLEventWithID postAndSuspend2(const LLSD& event, - const LLEventPumpOrPumpName& requestPump, - const LLEventPumpOrPumpName& replyPump0, - const LLEventPumpOrPumpName& replyPump1, - const LLSD& replyPump0NamePath=LLSD(), - const LLSD& replyPump1NamePath=LLSD()); - -/** - * Wait for the next event on either of two specified LLEventPumps. - */ inline -LLEventWithID -suspendUntilEventOn(const LLEventPumpOrPumpName& pump0, const LLEventPumpOrPumpName& pump1) +LLSD suspendUntilEventOnWithTimeout(const LLEventPumpOrPumpName& suspendPumpOrName, + F32 timeoutin, const LLSD &timeoutResult) { - // This is now a convenience wrapper for postAndSuspend2(). - return postAndSuspend2(LLSD(), LLEventPumpOrPumpName(), pump0, pump1); + return postAndSuspendWithTimeout(LLSD(), // event + LLEventPumpOrPumpName(), // requestPump + suspendPumpOrName, // replyPump + LLSD(), // replyPumpNamePath + timeoutin, + timeoutResult); } -/** - * Helper for the two-pump variant of suspendUntilEventOn(), e.g.: - * - * @code - * LLSD reply = errorException(suspendUntilEventOn(replyPump, errorPump), - * "error response from login.cgi"); - * @endcode - * - * Examines an LLEventWithID, assuming that the second pump (pump 1) is - * listening for an error indication. If the incoming data arrived on pump 1, - * throw an LLErrorEvent exception. If the incoming data arrived on pump 0, - * just return it. Since a normal return can only be from pump 0, we no longer - * need the LLEventWithID's discriminator int; we can just return the LLSD. - * - * @note I'm not worried about introducing the (fairly generic) name - * errorException() into global namespace, because how many other overloads of - * the same name are going to accept an LLEventWithID parameter? - */ -LLSD errorException(const LLEventWithID& result, const std::string& desc); - -} // namespace llcoro - -/** - * Exception thrown by errorException(). We don't call this LLEventError - * because it's not an error in event processing: rather, this exception - * announces an event that bears error information (for some other API). - */ -class LL_COMMON_API LLErrorEvent: public LLException -{ -public: - LLErrorEvent(const std::string& what, const LLSD& data): - LLException(what), - mData(data) - {} - virtual ~LLErrorEvent() throw() {} - - LLSD getData() const { return mData; } - -private: - LLSD mData; -}; - -namespace llcoro -{ - -/** - * Like errorException(), save that this trips a fatal error using LL_ERRS - * rather than throwing an exception. - */ -LL_COMMON_API LLSD errorLog(const LLEventWithID& result, const std::string& desc); - } // namespace llcoro /** @@ -304,84 +212,4 @@ private: LLEventStream mPump; }; -/** - * Other event APIs require the names of two different LLEventPumps: one for - * success response, the other for error response. Extend LLCoroEventPump - * for the two-pump use case. - */ -class LL_COMMON_API LLCoroEventPumps -{ -public: - LLCoroEventPumps(const std::string& name="coro", - const std::string& suff0="Reply", - const std::string& suff1="Error"): - mPump0(name + suff0, true), // allow tweaking the pump instance name - mPump1(name + suff1, true) - {} - /// request pump 0's name - std::string getName0() const { return mPump0.getName(); } - /// request pump 1's name - std::string getName1() const { return mPump1.getName(); } - /// request both names - std::pair getNames() const - { - return std::pair(mPump0.getName(), mPump1.getName()); - } - - /// request pump 0 - LLEventPump& getPump0() { return mPump0; } - /// request pump 1 - LLEventPump& getPump1() { return mPump1; } - - /// suspendUntilEventOn(either of our two LLEventPumps) - LLEventWithID suspend() - { - return llcoro::suspendUntilEventOn(mPump0, mPump1); - } - - /// errorException(suspend()) - LLSD suspendWithException() - { - return llcoro::errorException(suspend(), std::string("Error event on ") + getName1()); - } - - /// errorLog(suspend()) - LLSD suspendWithLog() - { - return llcoro::errorLog(suspend(), std::string("Error event on ") + getName1()); - } - - LLEventWithID postAndSuspend(const LLSD& event, - const LLEventPumpOrPumpName& requestPump, - const LLSD& replyPump0NamePath=LLSD(), - const LLSD& replyPump1NamePath=LLSD()) - { - return llcoro::postAndSuspend2(event, requestPump, mPump0, mPump1, - replyPump0NamePath, replyPump1NamePath); - } - - LLSD postAndSuspendWithException(const LLSD& event, - const LLEventPumpOrPumpName& requestPump, - const LLSD& replyPump0NamePath=LLSD(), - const LLSD& replyPump1NamePath=LLSD()) - { - return llcoro::errorException(postAndSuspend(event, requestPump, - replyPump0NamePath, replyPump1NamePath), - std::string("Error event on ") + getName1()); - } - - LLSD postAndSuspendWithLog(const LLSD& event, - const LLEventPumpOrPumpName& requestPump, - const LLSD& replyPump0NamePath=LLSD(), - const LLSD& replyPump1NamePath=LLSD()) - { - return llcoro::errorLog(postAndSuspend(event, requestPump, - replyPump0NamePath, replyPump1NamePath), - std::string("Error event on ") + getName1()); - } - -private: - LLEventStream mPump0, mPump1; -}; - #endif /* ! defined(LL_LLEVENTCORO_H) */ diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp index f5f3aec270..356b896163 100644 --- a/indra/llcommon/llsingleton.cpp +++ b/indra/llcommon/llsingleton.cpp @@ -30,10 +30,9 @@ #include "llerror.h" #include "llerrorcontrol.h" // LLError::is_available() #include "lldependencies.h" -#include "llcoro_get_id.h" #include "llexception.h" +#include "llcoros.h" #include -#include #include #include // std::cerr in dire emergency #include @@ -115,19 +114,10 @@ private: // initialized, either in the constructor or in initSingleton(). However, // managing that as a stack depends on having a DISTINCT 'initializing' // stack for every C++ stack in the process! And we have a distinct C++ - // stack for every running coroutine. It would be interesting and cool to - // implement a generic coroutine-local-storage mechanism and use that - // here. The trouble is that LLCoros is itself an LLSingleton, so - // depending on LLCoros functionality could dig us into infinite - // recursion. (Moreover, when we reimplement LLCoros on top of - // Boost.Fiber, that library already provides fiber_specific_ptr -- so - // it's not worth a great deal of time and energy implementing a generic - // equivalent on top of boost::dcoroutine, which is on its way out.) - // Instead, use a map of llcoro::id to select the appropriate - // coro-specific 'initializing' stack. llcoro::get_id() is carefully - // implemented to avoid requiring LLCoros. - typedef boost::unordered_map InitializingMap; - InitializingMap mInitializing; + // stack for every running coroutine. Therefore this stack must be based + // on a coroutine-local pointer. + // This local_ptr isn't static because it's a member of an LLSingleton. + LLCoros::local_ptr mInitializing; public: // Instantiate this to obtain a reference to the coroutine-specific @@ -166,18 +156,23 @@ public: private: list_t& get_initializing_() { - // map::operator[] has find-or-create semantics, exactly what we need - // here. It returns a reference to the selected mapped_type instance. - return mInitializing[llcoro::get_id()]; + LLSingletonBase::list_t* current = mInitializing.get(); + if (! current) + { + // If the running coroutine doesn't already have an initializing + // stack, allocate a new one and save it for future reference. + current = new LLSingletonBase::list_t(); + mInitializing.reset(current); + } + return *current; } + // By the time mInitializing is destroyed, its value for every coroutine + // except the running one must have been reset() to nullptr. So every time + // we pop the list to empty, reset() the running coroutine's local_ptr. void cleanup_initializing_() { - InitializingMap::iterator found = mInitializing.find(llcoro::get_id()); - if (found != mInitializing.end()) - { - mInitializing.erase(found); - } + mInitializing.reset(nullptr); } }; diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index fa02d2bb1a..2e4b6ba823 100644 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -26,50 +26,12 @@ * $/LicenseInfo$ */ -/*****************************************************************************/ -// test<1>() is cloned from a Boost.Coroutine example program whose copyright -// info is reproduced here: -/*---------------------------------------------------------------------------*/ -// Copyright (c) 2006, Giovanni P. Deretta -// -// This code may be used under either of the following two licences: -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. OF SUCH DAMAGE. -// -// Or: -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -/*****************************************************************************/ - #define BOOST_RESULT_OF_USE_TR1 1 -// On some platforms, Boost.Coroutine must #define magic symbols before -// #including platform-API headers. Naturally, that's ineffective unless the -// Boost.Coroutine #include is the *first* #include of the platform header. -// That means that client code must generally #include Boost.Coroutine headers -// before anything else. -#include #include #include #include #include +#include #include "linden_common.h" @@ -80,47 +42,12 @@ #include "llsd.h" #include "llsdutil.h" #include "llevents.h" -#include "tests/wrapllerrs.h" -#include "stringize.h" #include "llcoros.h" #include "lleventcoro.h" #include "../test/debug.h" using namespace llcoro; -/***************************************************************************** -* from the banana.cpp example program borrowed for test<1>() -*****************************************************************************/ -namespace coroutines = boost::dcoroutines; -using coroutines::coroutine; - -template -bool match(Iter first, Iter last, std::string match) { - std::string::iterator i = match.begin(); - for(; (first != last) && (i != match.end()); ++i) { - if (*first != *i) - return false; - ++first; - } - return i == match.end(); -} - -template -BidirectionalIterator -match_substring(BidirectionalIterator begin, - BidirectionalIterator end, - std::string xmatch, - BOOST_DEDUCED_TYPENAME coroutine::self& self) { -//BidirectionalIterator begin_ = begin; - for(; begin != end; ++begin) - if(match(begin, end, xmatch)) { - self.yield(begin); - } - return end; -} - -typedef coroutine match_coroutine_type; - /***************************************************************************** * Test helpers *****************************************************************************/ @@ -150,6 +77,8 @@ public: LLSD::Integer value(event["value"]); LLSD::String replyPumpName(event.has("fail")? "error" : "reply"); LLEventPumps::instance().obtain(event[replyPumpName]).post(value + 1); + // give listener a chance to process + llcoro::suspend(); return false; } @@ -167,51 +96,6 @@ namespace tut typedef coroutine_group::object object; coroutine_group coroutinegrp("coroutine"); - template<> template<> - void object::test<1>() - { - set_test_name("From banana.cpp example program in Boost.Coroutine distro"); - std::string buffer = "banananana"; - std::string match = "nana"; - std::string::iterator begin = buffer.begin(); - std::string::iterator end = buffer.end(); - -#if defined(BOOST_CORO_POSIX_IMPL) -// std::cout << "Using Boost.Coroutine " << BOOST_CORO_POSIX_IMPL << '\n'; -#else -// std::cout << "Using non-Posix Boost.Coroutine implementation" << std::endl; -#endif - - typedef std::string::iterator signature(std::string::iterator, - std::string::iterator, - std::string, - match_coroutine_type::self&); - - coroutine matcher - (boost::bind(static_cast(match_substring), - begin, - end, - match, - _1)); - - std::string::iterator i = matcher(); -/*==========================================================================*| - while(matcher && i != buffer.end()) { - std::cout <<"Match at: "<< std::distance(buffer.begin(), i)<<'\n'; - i = matcher(); - } -|*==========================================================================*/ - size_t matches[] = { 2, 4, 6 }; - for (size_t *mi(boost::begin(matches)), *mend(boost::end(matches)); - mi != mend; ++mi, i = matcher()) - { - ensure("more", matcher); - ensure("found", i != buffer.end()); - ensure_equals("value", std::distance(buffer.begin(), i), *mi); - } - ensure("done", ! matcher); - } - // use static data so we can intersperse coroutine functions with the // tests that engage them ImmediateAPI immediateAPI; @@ -231,7 +115,7 @@ namespace tut which = 0; } - void explicit_wait(boost::shared_ptr::callback_t>& cbp) + void explicit_wait(boost::shared_ptr>& cbp) { BEGIN { @@ -241,44 +125,40 @@ namespace tut // provides a callback-style notification (and prove that it // works). - LLCoros::Future future; - // get the callback from that future - LLCoros::Future::callback_t callback(future.make_callback()); - // Perhaps we would send a request to a remote server and arrange - // for 'callback' to be called on response. Of course that might - // involve an adapter object from the actual callback signature to - // the signature of 'callback' -- in this case, void(std::string). - // For test purposes, instead of handing 'callback' (or the + // for cbp->set_value() to be called on response. + // For test purposes, instead of handing 'callback' (or an // adapter) off to some I/O subsystem, we'll just pass it back to // our caller. - cbp.reset(new LLCoros::Future::callback_t(callback)); + cbp = boost::make_shared>(); + LLCoros::Future future = LLCoros::getFuture(*cbp); - ensure("Not yet", ! future); // calling get() on the future causes us to suspend debug("about to suspend"); stringdata = future.get(); - ensure("Got it", bool(future)); + ensure_equals("Got it", stringdata, "received"); } END } template<> template<> - void object::test<2>() + void object::test<1>() { clear(); set_test_name("explicit_wait"); DEBUG; // Construct the coroutine instance that will run explicit_wait. - boost::shared_ptr::callback_t> respond; - LLCoros::instance().launch("test<2>", + boost::shared_ptr> respond; + LLCoros::instance().launch("test<1>", boost::bind(explicit_wait, boost::ref(respond))); // When the coroutine waits for the future, it returns here. debug("about to respond"); - // Now we're the I/O subsystem delivering a result. This immediately - // transfers control back to the coroutine. - (*respond)("received"); + // Now we're the I/O subsystem delivering a result. This should make + // the coroutine ready. + respond->set_value("received"); + // but give it a chance to wake up + llcoro::suspend(); // ensure the coroutine ran and woke up again with the intended result ensure_equals(stringdata, "received"); } @@ -293,60 +173,20 @@ namespace tut } template<> template<> - void object::test<3>() + void object::test<2>() { clear(); set_test_name("waitForEventOn1"); DEBUG; - LLCoros::instance().launch("test<3>", waitForEventOn1); + LLCoros::instance().launch("test<2>", waitForEventOn1); debug("about to send"); LLEventPumps::instance().obtain("source").post("received"); + // give waitForEventOn1() a chance to run + llcoro::suspend(); debug("back from send"); ensure_equals(result.asString(), "received"); } - void waitForEventOn2() - { - BEGIN - { - LLEventWithID pair = suspendUntilEventOn("reply", "error"); - result = pair.first; - which = pair.second; - debug(STRINGIZE("result = " << result << ", which = " << which)); - } - END - } - - template<> template<> - void object::test<4>() - { - clear(); - set_test_name("waitForEventOn2 reply"); - { - DEBUG; - LLCoros::instance().launch("test<4>", waitForEventOn2); - debug("about to send"); - LLEventPumps::instance().obtain("reply").post("received"); - debug("back from send"); - } - ensure_equals(result.asString(), "received"); - ensure_equals("which pump", which, 0); - } - - template<> template<> - void object::test<5>() - { - clear(); - set_test_name("waitForEventOn2 error"); - DEBUG; - LLCoros::instance().launch("test<5>", waitForEventOn2); - debug("about to send"); - LLEventPumps::instance().obtain("error").post("badness"); - debug("back from send"); - ensure_equals(result.asString(), "badness"); - ensure_equals("which pump", which, 1); - } - void coroPump() { BEGIN @@ -359,175 +199,20 @@ namespace tut } template<> template<> - void object::test<6>() + void object::test<3>() { clear(); set_test_name("coroPump"); DEBUG; - LLCoros::instance().launch("test<6>", coroPump); - debug("about to send"); - LLEventPumps::instance().obtain(replyName).post("received"); - debug("back from send"); - ensure_equals(result.asString(), "received"); - } - - void coroPumps() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - LLEventWithID pair(waiter.suspend()); - result = pair.first; - which = pair.second; - } - END - } - - template<> template<> - void object::test<7>() - { - clear(); - set_test_name("coroPumps reply"); - DEBUG; - LLCoros::instance().launch("test<7>", coroPumps); - debug("about to send"); - LLEventPumps::instance().obtain(replyName).post("received"); - debug("back from send"); - ensure_equals(result.asString(), "received"); - ensure_equals("which pump", which, 0); - } - - template<> template<> - void object::test<8>() - { - clear(); - set_test_name("coroPumps error"); - DEBUG; - LLCoros::instance().launch("test<8>", coroPumps); - debug("about to send"); - LLEventPumps::instance().obtain(errorName).post("badness"); - debug("back from send"); - ensure_equals(result.asString(), "badness"); - ensure_equals("which pump", which, 1); - } - - void coroPumpsNoEx() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - result = waiter.suspendWithException(); - } - END - } - - template<> template<> - void object::test<9>() - { - clear(); - set_test_name("coroPumpsNoEx"); - DEBUG; - LLCoros::instance().launch("test<9>", coroPumpsNoEx); - debug("about to send"); - LLEventPumps::instance().obtain(replyName).post("received"); - debug("back from send"); - ensure_equals(result.asString(), "received"); - } - - void coroPumpsEx() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - try - { - result = waiter.suspendWithException(); - debug("no exception"); - } - catch (const LLErrorEvent& e) - { - debug(STRINGIZE("exception " << e.what())); - errordata = e.getData(); - } - } - END - } - - template<> template<> - void object::test<10>() - { - clear(); - set_test_name("coroPumpsEx"); - DEBUG; - LLCoros::instance().launch("test<10>", coroPumpsEx); - debug("about to send"); - LLEventPumps::instance().obtain(errorName).post("badness"); - debug("back from send"); - ensure("no result", result.isUndefined()); - ensure_equals("got error", errordata.asString(), "badness"); - } - - void coroPumpsNoLog() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - result = waiter.suspendWithLog(); - } - END - } - - template<> template<> - void object::test<11>() - { - clear(); - set_test_name("coroPumpsNoLog"); - DEBUG; - LLCoros::instance().launch("test<11>", coroPumpsNoLog); + LLCoros::instance().launch("test<3>", coroPump); debug("about to send"); LLEventPumps::instance().obtain(replyName).post("received"); + // give coroPump() a chance to run + llcoro::suspend(); debug("back from send"); ensure_equals(result.asString(), "received"); } - void coroPumpsLog() - { - BEGIN - { - LLCoroEventPumps waiter; - replyName = waiter.getName0(); - errorName = waiter.getName1(); - WrapLLErrs capture; - threw = capture.catch_llerrs([&waiter, &debug](){ - result = waiter.suspendWithLog(); - debug("no exception"); - }); - } - END - } - - template<> template<> - void object::test<12>() - { - clear(); - set_test_name("coroPumpsLog"); - DEBUG; - LLCoros::instance().launch("test<12>", coroPumpsLog); - debug("about to send"); - LLEventPumps::instance().obtain(errorName).post("badness"); - debug("back from send"); - ensure("no result", result.isUndefined()); - ensure_contains("got error", threw, "badness"); - } - void postAndWait1() { BEGIN @@ -541,71 +226,17 @@ namespace tut } template<> template<> - void object::test<13>() + void object::test<4>() { clear(); set_test_name("postAndWait1"); DEBUG; - LLCoros::instance().launch("test<13>", postAndWait1); + LLCoros::instance().launch("test<4>", postAndWait1); + // give postAndWait1() a chance to run + llcoro::suspend(); ensure_equals(result.asInteger(), 18); } - void postAndWait2() - { - BEGIN - { - LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18), - immediateAPI.getPump(), - "reply2", - "error2", - "reply", - "error"); - result = pair.first; - which = pair.second; - debug(STRINGIZE("result = " << result << ", which = " << which)); - } - END - } - - template<> template<> - void object::test<14>() - { - clear(); - set_test_name("postAndWait2"); - DEBUG; - LLCoros::instance().launch("test<14>", postAndWait2); - ensure_equals(result.asInteger(), 19); - ensure_equals(which, 0); - } - - void postAndWait2_1() - { - BEGIN - { - LLEventWithID pair = ::postAndSuspend2(LLSDMap("value", 18)("fail", LLSD()), - immediateAPI.getPump(), - "reply2", - "error2", - "reply", - "error"); - result = pair.first; - which = pair.second; - debug(STRINGIZE("result = " << result << ", which = " << which)); - } - END - } - - template<> template<> - void object::test<15>() - { - clear(); - set_test_name("postAndWait2_1"); - DEBUG; - LLCoros::instance().launch("test<15>", postAndWait2_1); - ensure_equals(result.asInteger(), 19); - ensure_equals(which, 1); - } - void coroPumpPost() { BEGIN @@ -618,177 +249,14 @@ namespace tut } template<> template<> - void object::test<16>() + void object::test<5>() { clear(); set_test_name("coroPumpPost"); DEBUG; - LLCoros::instance().launch("test<16>", coroPumpPost); + LLCoros::instance().launch("test<5>", coroPumpPost); + // give coroPumpPost() a chance to run + llcoro::suspend(); ensure_equals(result.asInteger(), 18); } - - void coroPumpsPost() - { - BEGIN - { - LLCoroEventPumps waiter; - LLEventWithID pair(waiter.postAndSuspend(LLSDMap("value", 23), - immediateAPI.getPump(), "reply", "error")); - result = pair.first; - which = pair.second; - } - END - } - - template<> template<> - void object::test<17>() - { - clear(); - set_test_name("coroPumpsPost reply"); - DEBUG; - LLCoros::instance().launch("test<17>", coroPumpsPost); - ensure_equals(result.asInteger(), 24); - ensure_equals("which pump", which, 0); - } - - void coroPumpsPost_1() - { - BEGIN - { - LLCoroEventPumps waiter; - LLEventWithID pair( - waiter.postAndSuspend(LLSDMap("value", 23)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error")); - result = pair.first; - which = pair.second; - } - END - } - - template<> template<> - void object::test<18>() - { - clear(); - set_test_name("coroPumpsPost error"); - DEBUG; - LLCoros::instance().launch("test<18>", coroPumpsPost_1); - ensure_equals(result.asInteger(), 24); - ensure_equals("which pump", which, 1); - } - - void coroPumpsPostNoEx() - { - BEGIN - { - LLCoroEventPumps waiter; - result = waiter.postAndSuspendWithException(LLSDMap("value", 8), - immediateAPI.getPump(), "reply", "error"); - } - END - } - - template<> template<> - void object::test<19>() - { - clear(); - set_test_name("coroPumpsPostNoEx"); - DEBUG; - LLCoros::instance().launch("test<19>", coroPumpsPostNoEx); - ensure_equals(result.asInteger(), 9); - } - - void coroPumpsPostEx() - { - BEGIN - { - LLCoroEventPumps waiter; - try - { - result = waiter.postAndSuspendWithException( - LLSDMap("value", 9)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error"); - debug("no exception"); - } - catch (const LLErrorEvent& e) - { - debug(STRINGIZE("exception " << e.what())); - errordata = e.getData(); - } - } - END - } - - template<> template<> - void object::test<20>() - { - clear(); - set_test_name("coroPumpsPostEx"); - DEBUG; - LLCoros::instance().launch("test<20>", coroPumpsPostEx); - ensure("no result", result.isUndefined()); - ensure_equals("got error", errordata.asInteger(), 10); - } - - void coroPumpsPostNoLog() - { - BEGIN - { - LLCoroEventPumps waiter; - result = waiter.postAndSuspendWithLog(LLSDMap("value", 30), - immediateAPI.getPump(), "reply", "error"); - } - END - } - - template<> template<> - void object::test<21>() - { - clear(); - set_test_name("coroPumpsPostNoLog"); - DEBUG; - LLCoros::instance().launch("test<21>", coroPumpsPostNoLog); - ensure_equals(result.asInteger(), 31); - } - - void coroPumpsPostLog() - { - BEGIN - { - LLCoroEventPumps waiter; - WrapLLErrs capture; - threw = capture.catch_llerrs( - [&waiter, &debug](){ - result = waiter.postAndSuspendWithLog( - LLSDMap("value", 31)("fail", LLSD()), - immediateAPI.getPump(), "reply", "error"); - debug("no exception"); - }); - } - END - } - - template<> template<> - void object::test<22>() - { - clear(); - set_test_name("coroPumpsPostLog"); - DEBUG; - LLCoros::instance().launch("test<22>", coroPumpsPostLog); - ensure("no result", result.isUndefined()); - ensure_contains("got error", threw, "32"); - } } - -/*==========================================================================*| -#include - -namespace tut -{ - template<> template<> - void object::test<23>() - { - set_test_name("stacksize"); - std::cout << "default_stacksize: " << boost::context::guarded_stack_allocator::default_stacksize() << '\n'; - } -} // namespace tut -|*==========================================================================*/ diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index e0922c0667..a2a57ad740 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -217,7 +217,7 @@ target_link_libraries( ${NGHTTP2_LIBRARIES} ${XMLRPCEPI_LIBRARIES} ${LLCOREHTTP_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} rt @@ -235,7 +235,7 @@ target_link_libraries( ${NGHTTP2_LIBRARIES} ${XMLRPCEPI_LIBRARIES} ${LLCOREHTTP_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ) @@ -264,7 +264,7 @@ if (LINUX) ${LLMESSAGE_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${JSONCPP_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} rt ${GOOGLEMOCK_LIBRARIES} @@ -280,7 +280,7 @@ else (LINUX) ${LLMESSAGE_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${JSONCPP_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${GOOGLEMOCK_LIBRARIES} ) diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index 74cdff2b00..4c85dd999a 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -203,6 +203,7 @@ void LLCoprocedureManager::cancelCoprocedure(const LLUUID &id) LL_INFOS() << "Coprocedure not found." << LL_ENDL; } +/*==========================================================================*| void LLCoprocedureManager::shutdown(bool hardShutdown) { for (poolMap_t::const_iterator it = mPoolMap.begin(); it != mPoolMap.end(); ++it) @@ -211,6 +212,7 @@ void LLCoprocedureManager::shutdown(bool hardShutdown) } mPoolMap.clear(); } +|*==========================================================================*/ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn) { @@ -303,10 +305,13 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size): LLCoprocedurePool::~LLCoprocedurePool() { +/*==========================================================================*| shutdown(); +|*==========================================================================*/ } //------------------------------------------------------------------------- +/*==========================================================================*| void LLCoprocedurePool::shutdown(bool hardShutdown) { CoroAdapterMap_t::iterator it; @@ -327,6 +332,7 @@ void LLCoprocedurePool::shutdown(bool hardShutdown) mCoroMapping.clear(); mPendingCoprocs.clear(); } +|*==========================================================================*/ //------------------------------------------------------------------------- LLUUID LLCoprocedurePool::enqueueCoprocedure(const std::string &name, LLCoprocedurePool::CoProcedure_t proc) diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h index 7d0e83180c..ba6f97355c 100644 --- a/indra/llmessage/llcoproceduremanager.h +++ b/indra/llmessage/llcoproceduremanager.h @@ -59,9 +59,11 @@ public: /// If it has not yet been dequeued it is simply removed from the queue. void 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 setPropertyMethods(SettingQuery_t queryfn, SettingUpdate_t updatefn); diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index dd2e806dda..7b6d04b096 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -80,7 +80,7 @@ target_link_libraries(llprimitive ${LLXML_LIBRARIES} ${LLPHYSICSEXTENSIONS_LIBRARIES} ${LLCHARACTER_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ) diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index e44f57fa9f..2d2fa6588f 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -299,7 +299,7 @@ if(LL_TESTS) set(test_libs llui llmessage llcorehttp llcommon ${HUNSPELL_LIBRARY} ${LLCOMMON_LIBRARIES} - ${BOOST_COROUTINE_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${WINDOWS_LIBRARIES}) if(NOT LINUX) LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}") diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt index f6c4dfb59d..95637c9a28 100644 --- a/indra/mac_crash_logger/CMakeLists.txt +++ b/indra/mac_crash_logger/CMakeLists.txt @@ -77,7 +77,7 @@ target_link_libraries(mac-crash-logger ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} ${BOOST_CONTEXT_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ) add_custom_command( diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index dc0d737540..45f4cb269c 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2004,7 +2004,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${viewer_LIBRARIES} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${DBUSGLIB_LIBRARIES} ${OPENGL_LIBRARIES} @@ -2484,7 +2484,7 @@ if (LL_TESTS) ${OPENSSL_LIBRARIES} ${CRYPTO_LIBRARIES} ${LIBRT_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index af70751b37..db2db43ee1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1422,6 +1422,8 @@ bool LLAppViewer::doFrame() // canonical per-frame event mainloop.post(newFrame); + // give listeners a chance to run + llcoro::suspend(); if (!LLApp::isExiting()) { diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 8344cead57..4187076030 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -98,7 +98,7 @@ target_link_libraries(lltest ${WINDOWS_LIBRARIES} ${BOOST_PROGRAM_OPTIONS_LIBRARY} ${BOOST_REGEX_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ${DL_LIBRARY} diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt index 3bedeb7292..23518b791c 100644 --- a/indra/viewer_components/login/CMakeLists.txt +++ b/indra/viewer_components/login/CMakeLists.txt @@ -50,7 +50,7 @@ target_link_libraries(lllogin ${LLMATH_LIBRARIES} ${LLXML_LIBRARIES} ${BOOST_THREAD_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY} ) @@ -62,7 +62,7 @@ if(LL_TESTS) set_source_files_properties( lllogin.cpp PROPERTIES - LL_TEST_ADDITIONAL_LIBRARIES "${LLMESSAGE_LIBRARIES};${LLCOREHTTP_LIBRARIES};${LLCOMMON_LIBRARIES};${BOOST_COROUTINE_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}" + LL_TEST_ADDITIONAL_LIBRARIES "${LLMESSAGE_LIBRARIES};${LLCOREHTTP_LIBRARIES};${LLCOMMON_LIBRARIES};${BOOST_FIBER_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}" ) LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}") diff --git a/indra/viewer_components/login/tests/lllogin_test.cpp b/indra/viewer_components/login/tests/lllogin_test.cpp index e96c495446..774823d735 100644 --- a/indra/viewer_components/login/tests/lllogin_test.cpp +++ b/indra/viewer_components/login/tests/lllogin_test.cpp @@ -44,6 +44,7 @@ //#define DEBUG_ON #include "../../../test/debug.h" #include "llevents.h" +#include "lleventcoro.h" #include "stringize.h" #if LL_WINDOWS @@ -199,6 +200,7 @@ namespace tut credentials["passwd"] = "secret"; login.connect("login.bar.com", credentials); + llcoro::suspend(); ensure_equals("Online state", listener.lastEvent()["state"].asString(), "online"); } @@ -226,6 +228,7 @@ namespace tut credentials["passwd"] = "badpasswd"; login.connect("login.bar.com", credentials); + llcoro::suspend(); ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating"); @@ -265,6 +268,7 @@ namespace tut credentials["passwd"] = "matter"; login.connect("login.bar.com", credentials); + llcoro::suspend(); ensure_equals("Auth state", listener.lastEvent()["change"].asString(), "authenticating"); @@ -300,6 +304,7 @@ namespace tut credentials["cfg_srv_timeout"] = 0.0f; login.connect("login.bar.com", credentials); + llcoro::suspend(); // Get the mainloop eventpump, which needs a pinging in order to drive the // SRV timeout. diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt index 4fba26ab2f..1c3479bf69 100644 --- a/indra/win_crash_logger/CMakeLists.txt +++ b/indra/win_crash_logger/CMakeLists.txt @@ -83,7 +83,7 @@ target_link_libraries(windows-crash-logger ${LLCOREHTTP_LIBRARIES} ${LLCOMMON_LIBRARIES} ${BOOST_CONTEXT_LIBRARY} - ${BOOST_COROUTINE_LIBRARY} + ${BOOST_FIBER_LIBRARY} ${WINDOWS_LIBRARIES} ${DXGUID_LIBRARY} ${GOOGLE_PERFTOOLS_LIBRARIES} -- cgit v1.3 From 65b268ff861e8decadaee9a70b2d5ce78e571cbc Mon Sep 17 00:00:00 2001 From: Anchor Date: Thu, 18 Apr 2019 11:33:23 -0700 Subject: [DRTVWR-476] - fix openjpeg dll path --- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- indra/cmake/OpenJPEG.cmake | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index e121328d64..e2647f6b98 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -37,7 +37,7 @@ if(WINDOWS) set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(release_files - openjpeg.dll + openjp2.dll libapr-1.dll libaprutil-1.dll libapriconv-1.dll diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake index bf0bde2ba7..965384f5e0 100644 --- a/indra/cmake/OpenJPEG.cmake +++ b/indra/cmake/OpenJPEG.cmake @@ -12,8 +12,8 @@ else (USESYSTEMLIBS) if(WINDOWS) # Windows has differently named release and debug openjpeg(d) libs. set(OPENJPEG_LIBRARIES - debug openjpegd - optimized openjpeg) + debug openjp2d + optimized openjp2) else(WINDOWS) set(OPENJPEG_LIBRARIES openjpeg) endif(WINDOWS) -- cgit v1.3 From fc09af763c96d0bf13d721e1f74b8535379df766 Mon Sep 17 00:00:00 2001 From: Anchor Date: Thu, 18 Apr 2019 13:24:14 -0700 Subject: [DRTVWR-476] - update openjpeg --- autobuild.xml | 12 ++++++------ indra/cmake/Copy3rdPartyLibs.cmake | 2 +- indra/cmake/OpenJPEG.cmake | 4 ++-- indra/llimagej2coj/llimagej2coj.cpp | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 0f68acd3e2..49c3069d05 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2652,9 +2652,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 8f0d541312c0b7a55a0f6295be42a395 + 49f2a20ecd50c29a66a162d8bbc5cbe6 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31394/263395/openjpeg-2.3.0.523914-darwin64-523914.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/36010/301207/openjpeg-1.5.1.526451-darwin64-526451.tar.bz2 name darwin64 @@ -2688,9 +2688,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 6bb7c289ab7ca9d973f29115c574e54a + 7ce7dd714c6899ffc4a7473fd578bee0 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31433/263554/openjpeg-2.3.0.523914-windows-523914.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/36015/301223/openjpeg-1.5.1.526451-windows-526451.tar.bz2 name windows @@ -2700,9 +2700,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 891c7e483024f6827d1ed26c91b0b868 + f024340804396106687fe7a863d5952f url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31432/263547/openjpeg-2.3.0.523914-windows64-523914.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/36012/301214/openjpeg-1.5.1.526451-windows64-526451.tar.bz2 name windows64 diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index e2647f6b98..e121328d64 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -37,7 +37,7 @@ if(WINDOWS) set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}") set(release_files - openjp2.dll + openjpeg.dll libapr-1.dll libaprutil-1.dll libapriconv-1.dll diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake index 965384f5e0..bf0bde2ba7 100644 --- a/indra/cmake/OpenJPEG.cmake +++ b/indra/cmake/OpenJPEG.cmake @@ -12,8 +12,8 @@ else (USESYSTEMLIBS) if(WINDOWS) # Windows has differently named release and debug openjpeg(d) libs. set(OPENJPEG_LIBRARIES - debug openjp2d - optimized openjp2) + debug openjpegd + optimized openjpeg) else(WINDOWS) set(OPENJPEG_LIBRARIES openjpeg) endif(WINDOWS) diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 3fe5d56d4f..925da5674b 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -28,7 +28,7 @@ #include "llimagej2coj.h" // this is defined so that we get static linking. -#include "opj_includes.h" +#include "openjpeg.h" #include "lltimer.h" //#include "llmemory.h" -- cgit v1.3 From 0ed3724c95eb8d3c1daf50657d53d68641d576df Mon Sep 17 00:00:00 2001 From: Anchor Date: Tue, 7 May 2019 23:58:04 -0600 Subject: [DRTVWR-476] - add legacy_stdio_definitions --- indra/cmake/LLCommon.cmake | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/cmake') diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 8900419f9b..f56d1811d1 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -33,6 +33,10 @@ else (LINUX) ${BOOST_SYSTEM_LIBRARY} ) endif (LINUX) +if (WINDOWS) + list(APPEND LLCOMMON_LIBRARIES legacy_stdio_definitions) +endif (WINDOWS) + set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") if(LLCOMMON_LINK_SHARED) add_definitions(-DLL_COMMON_LINK_SHARED=1) -- cgit v1.3 From e039f5e29ee02c37d2febc21b492a0d425661897 Mon Sep 17 00:00:00 2001 From: Anchor Date: Wed, 8 May 2019 17:37:05 -0600 Subject: [DRTVWR-476] - legacy_stdio_definitions shld be the last library linked --- indra/cmake/LLAddBuildTest.cmake | 4 ++++ indra/cmake/LLCommon.cmake | 4 ---- indra/newview/CMakeLists.txt | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index ee6396e473..983b0bc3a9 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -208,6 +208,10 @@ FUNCTION(LL_ADD_INTEGRATION_TEST ${PTHREAD_LIBRARY} ) + if (WINDOWS) + list(APPEND libraries legacy_stdio_definitions) + endif (WINDOWS) + # Add test executable build target if(TEST_DEBUG) message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index f56d1811d1..8900419f9b 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -33,10 +33,6 @@ else (LINUX) ${BOOST_SYSTEM_LIBRARY} ) endif (LINUX) -if (WINDOWS) - list(APPEND LLCOMMON_LIBRARIES legacy_stdio_definitions) -endif (WINDOWS) - set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.") if(LLCOMMON_LINK_SHARED) add_definitions(-DLL_COMMON_LINK_SHARED=1) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 45f4cb269c..3ba6767082 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1977,6 +1977,10 @@ endif (WINDOWS) # dumped into the target binary and runtime lookup will find the most # modern version. +if (WINDOWS) + list(APPEND LLAPPEARANCE_LIBRARIES legacy_stdio_definitions) +endif (WINDOWS) + target_link_libraries(${VIEWER_BINARY_NAME} ${PNG_PRELOAD_ARCHIVES} ${ZLIB_PRELOAD_ARCHIVES} -- cgit v1.3 From 761d9aa3bff981d1f322c9fdfe33ac35b30bf338 Mon Sep 17 00:00:00 2001 From: Anchor Date: Wed, 8 May 2019 18:05:49 -0600 Subject: [DRTVWR-476] - test adding at beginiing of list --- indra/cmake/LLAddBuildTest.cmake | 2 +- indra/newview/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 983b0bc3a9..0a20a2c068 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -209,7 +209,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST ) if (WINDOWS) - list(APPEND libraries legacy_stdio_definitions) + list(INSERT libraries 0 legacy_stdio_definitions) endif (WINDOWS) # Add test executable build target diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3ba6767082..2ad969a705 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1978,7 +1978,7 @@ endif (WINDOWS) # modern version. if (WINDOWS) - list(APPEND LLAPPEARANCE_LIBRARIES legacy_stdio_definitions) + list(INSERT PNG_PRELOAD_ARCHIVES 0 legacy_stdio_definitions) endif (WINDOWS) target_link_libraries(${VIEWER_BINARY_NAME} -- cgit v1.3 From b5bb0794f0022517c7aeff9a7775864a56488da6 Mon Sep 17 00:00:00 2001 From: Anchor Date: Wed, 8 May 2019 18:57:33 -0600 Subject: [DRTVWR-476] - fix linking --- indra/CMakeLists.txt | 5 +++++ indra/cmake/LLAddBuildTest.cmake | 5 +---- indra/integration_tests/llimage_libtest/CMakeLists.txt | 1 + indra/integration_tests/llui_libtest/CMakeLists.txt | 1 + indra/llcorehttp/CMakeLists.txt | 1 + indra/llplugin/slplugin/CMakeLists.txt | 1 + indra/newview/CMakeLists.txt | 5 +---- indra/test/CMakeLists.txt | 1 + indra/win_crash_logger/CMakeLists.txt | 2 ++ 9 files changed, 14 insertions(+), 8 deletions(-) (limited to 'indra/cmake') diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 62a8f3f003..53e5d7b6a5 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -15,6 +15,11 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") include(Variables) include(BuildVersion) +set(LEGACY_STDIO_LIBS) +if (WINDOWS) + set(LEGACY_STDIO_LIBS legacy_stdio_definitions) +endif (WINDOWS) + if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Build type. One of: Debug Release RelWithDebInfo" FORCE) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 0a20a2c068..4932e9044f 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -200,6 +200,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST ) SET(libraries + ${LEGACY_STDIO_LIBS} ${library_dependencies} ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} @@ -208,10 +209,6 @@ FUNCTION(LL_ADD_INTEGRATION_TEST ${PTHREAD_LIBRARY} ) - if (WINDOWS) - list(INSERT libraries 0 legacy_stdio_definitions) - endif (WINDOWS) - # Add test executable build target if(TEST_DEBUG) message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})") diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt index d9353f904c..5787d4d600 100644 --- a/indra/integration_tests/llimage_libtest/CMakeLists.txt +++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt @@ -64,6 +64,7 @@ endif (DARWIN) # Libraries on which this application depends on # Sort by high-level to low-level target_link_libraries(llimage_libtest + ${LEGACY_STDIO_LIBS} ${LLCOMMON_LIBRARIES} ${LLVFS_LIBRARIES} ${LLMATH_LIBRARIES} diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt index 34e34c7e47..1cec660eb0 100644 --- a/indra/integration_tests/llui_libtest/CMakeLists.txt +++ b/indra/integration_tests/llui_libtest/CMakeLists.txt @@ -75,6 +75,7 @@ endif (DARWIN) # Libraries on which this library depends, needed for Linux builds # Sort by high-level to low-level target_link_libraries(llui_libtest + ${LEGACY_STDIO_LIBS} llui llinventory llmessage diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt index 9dbc6f447e..9e9685f1cb 100644 --- a/indra/llcorehttp/CMakeLists.txt +++ b/indra/llcorehttp/CMakeLists.txt @@ -198,6 +198,7 @@ endif (DARWIN) ) set(example_libs + ${LEGACY_STDIO_LIBS} ${LLCOREHTTP_LIBRARIES} ${WINDOWS_LIBRARIES} ${LLMESSAGE_LIBRARIES} diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt index 33520ad64c..e4f64448c5 100644 --- a/indra/llplugin/slplugin/CMakeLists.txt +++ b/indra/llplugin/slplugin/CMakeLists.txt @@ -63,6 +63,7 @@ set_target_properties(SLPlugin endif () target_link_libraries(SLPlugin + ${LEGACY_STDIO_LIBS} ${LLPLUGIN_LIBRARIES} ${LLMESSAGE_LIBRARIES} ${LLCOMMON_LIBRARIES} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 2ad969a705..0ba3b07566 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1977,11 +1977,8 @@ endif (WINDOWS) # dumped into the target binary and runtime lookup will find the most # modern version. -if (WINDOWS) - list(INSERT PNG_PRELOAD_ARCHIVES 0 legacy_stdio_definitions) -endif (WINDOWS) - target_link_libraries(${VIEWER_BINARY_NAME} + ${LEGACY_STDIO_LIBS} ${PNG_PRELOAD_ARCHIVES} ${ZLIB_PRELOAD_ARCHIVES} ${URIPARSER_PRELOAD_ARCHIVES} diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 4187076030..0f14862cba 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -83,6 +83,7 @@ list(APPEND test_SOURCE_FILES ${test_HEADER_FILES}) add_executable(lltest ${test_SOURCE_FILES}) target_link_libraries(lltest + ${LEGACY_STDIO_LIBS} ${LLDATABASE_LIBRARIES} ${LLINVENTORY_LIBRARIES} ${LLMESSAGE_LIBRARIES} diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt index 1c3479bf69..1b038c26b5 100644 --- a/indra/win_crash_logger/CMakeLists.txt +++ b/indra/win_crash_logger/CMakeLists.txt @@ -72,7 +72,9 @@ find_library(DXGUID_LIBRARY dxguid ${DIRECTX_LIBRARY_DIR}) add_executable(windows-crash-logger WIN32 ${win_crash_logger_SOURCE_FILES}) + target_link_libraries(windows-crash-logger + ${LEGACY_STDIO_LIBS} ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES} ${LLCRASHLOGGER_LIBRARIES} ${LLWINDOW_LIBRARIES} -- cgit v1.3 From 96639a8d09862eca95c483336d603aeb85694370 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 30 Jan 2019 17:16:06 -0800 Subject: Fix failure when building packages-info.txt when autobuild can't be found in xcode's PATH --- indra/cmake/BuildPackagesInfo.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/BuildPackagesInfo.cmake b/indra/cmake/BuildPackagesInfo.cmake index 4314cca33d..8f8b6b2330 100644 --- a/indra/cmake/BuildPackagesInfo.cmake +++ b/indra/cmake/BuildPackagesInfo.cmake @@ -1,6 +1,7 @@ # -*- cmake -*- # Construct the version and copyright information based on package data. include(Python) +include(FindAutobuild) # packages-formatter.py runs autobuild install --versions, which needs to know # the build_directory, which (on Windows) depends on AUTOBUILD_ADDRSIZE. @@ -13,7 +14,7 @@ add_custom_command(OUTPUT packages-info.txt DEPENDS ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py ${CMAKE_SOURCE_DIR}/../autobuild.xml COMMAND ${PYTHON_EXECUTABLE} - ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} + ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} -DAUTOBUILD=${AUTOBUILD_EXECUTABLE} ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > packages-info.txt ) -- cgit v1.3 From 3a7d40136415fbf1897d5240ef4e4d48f79c8a26 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 26 Jun 2019 15:04:16 -0400 Subject: DRTVWR-476: On Mac, copy libhunspell-1.3.0.dylib for test programs. --- indra/cmake/Copy3rdPartyLibs.cmake | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index e121328d64..3f669c833a 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -188,6 +188,7 @@ elseif(DARWIN) libexception_handler.dylib ${EXPAT_COPY} libGLOD.dylib + libhunspell-1.3.0.dylib libndofdev.dylib libnghttp2.dylib libnghttp2.14.dylib -- cgit v1.3 From d43dcc50c588631f9d55f7d9b959674a87bf9e92 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 17 Oct 2019 13:28:33 -0400 Subject: DRTVWR-476: We've observed a couple different values for VS 2017. --- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 3f669c833a..7ee13bb056 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -81,7 +81,7 @@ if(WINDOWS) elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 list(APPEND LMSVC_VER 120) list(APPEND LMSVC_VERDOT 12.0) - elseif (MSVC_VERSION EQUAL 1916) # Visual Studio 2017 + elseif (MSVC_VERSION EQUAL 1915 OR MSVC_VERSION EQUAL 1916) # Visual Studio 2017 list(APPEND LMSVC_VER 150) list(APPEND LMSVC_VERDOT 15.0) else (MSVC80) -- cgit v1.3 From 5f1140c03c9677753bd4a0ebe60b48e37d28669e Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 31 Oct 2019 09:22:07 -0400 Subject: DRTVWR-476: For VS 2017, MSVC_VERSION can be any of a range. Thanks NickyD. --- indra/cmake/Copy3rdPartyLibs.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 7ee13bb056..1e33205143 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -81,7 +81,7 @@ if(WINDOWS) elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 list(APPEND LMSVC_VER 120) list(APPEND LMSVC_VERDOT 12.0) - elseif (MSVC_VERSION EQUAL 1915 OR MSVC_VERSION EQUAL 1916) # Visual Studio 2017 + elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) # Visual Studio 2017 list(APPEND LMSVC_VER 150) list(APPEND LMSVC_VERDOT 15.0) else (MSVC80) -- cgit v1.3 From 70a63ca331484575fbd6ffb432e40f6555bb8a51 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 31 Oct 2019 13:54:51 -0400 Subject: DRTVWR-476, SL-12205: Update to glod built with VS 2017 runtime libs. --- autobuild.xml | 14 ++--- indra/cmake/Copy3rdPartyLibs.cmake | 115 ++++++++++++------------------------- indra/newview/viewer_manifest.py | 17 +----- 3 files changed, 47 insertions(+), 99 deletions(-) (limited to 'indra/cmake') diff --git a/autobuild.xml b/autobuild.xml index 7c330cdf8a..439b7ef963 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1088,9 +1088,9 @@ archive hash - b618532b67f253d321329cfc7a1101e0 + 014f6dca98a0964a5d9de31a9fdf3333 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/44337/391697/glod-1.0pre3.531370-darwin64-531370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/45956/405375/glod-1.0pre3.532346-darwin64-532346.tar.bz2 name darwin64 @@ -1126,11 +1126,11 @@ archive hash - 3be25680814037b801481dfc80850992 + fe8215c04f959e703653a6133e142fd4 hash_algorithm md5 url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/44368/391838/glod-1.0pre3.531370-windows-531370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/45955/405362/glod-1.0pre3.532346-windows-532346.tar.bz2 name windows @@ -1140,16 +1140,16 @@ archive hash - c896cb1a2a5d55f2d15877f557c1311b + 77f7c414366a903e66769d7af31c42aa url - http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/44367/391831/glod-1.0pre3.531370-windows64-531370.tar.bz2 + http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/45954/405349/glod-1.0pre3.532346-windows64-532346.tar.bz2 name windows64 version - 1.0pre3.531370 + 1.0pre3.532346 google_breakpad diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 1e33205143..c3309b2195 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -74,96 +74,57 @@ if(WINDOWS) #******************************* # Copy MS C runtime dlls, required for packaging. if (MSVC80) - list(APPEND LMSVC_VER 80) - list(APPEND LMSVC_VERDOT 8.0) + set(MSVC_VER 80) elseif (MSVC_VERSION EQUAL 1600) # VisualStudio 2010 MESSAGE(STATUS "MSVC_VERSION ${MSVC_VERSION}") elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12 - list(APPEND LMSVC_VER 120) - list(APPEND LMSVC_VERDOT 12.0) + set(MSVC_VER 120) elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1920) # Visual Studio 2017 - list(APPEND LMSVC_VER 150) - list(APPEND LMSVC_VERDOT 15.0) + set(MSVC_VER 140) else (MSVC80) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") endif (MSVC80) - # try to copy VS2010 redist independently of system version - # maint-7360 CP - # list(APPEND LMSVC_VER 100) - # list(APPEND LMSVC_VERDOT 10.0) - - list(LENGTH LMSVC_VER count) - math(EXPR count "${count}-1") - foreach(i RANGE ${count}) - list(GET LMSVC_VER ${i} MSVC_VER) - list(GET LMSVC_VERDOT ${i} MSVC_VERDOT) - MESSAGE(STATUS "Copying redist libs for VC ${MSVC_VERDOT}") - FIND_PATH(debug_msvc_redist_path NAME msvcr${MSVC_VER}d.dll - PATHS - [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${MSVC_VERDOT}\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC${MSVC_VER}.DebugCRT - [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64 - [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32 - ${MSVC_DEBUG_REDIST_PATH} - NO_DEFAULT_PATH - ) - - if(EXISTS ${debug_msvc_redist_path}) - set(debug_msvc_files - msvcr${MSVC_VER}d.dll - msvcp${MSVC_VER}d.dll - ) - - copy_if_different( - ${debug_msvc_redist_path} - "${SHARED_LIB_STAGING_DIR_DEBUG}" - out_targets - ${debug_msvc_files} - ) - set(third_party_targets ${third_party_targets} ${out_targets}) + MESSAGE(STATUS "Copying redist libs for VC ${MSVC_VER}") + if(ADDRESS_SIZE EQUAL 32) + # this folder contains the 32bit DLLs.. (yes really!) + set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64") + else(ADDRESS_SIZE EQUAL 32) + # this folder contains the 64bit DLLs.. (yes really!) + set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32") + endif(ADDRESS_SIZE EQUAL 32) + + FIND_PATH(release_msvc_redist_path NAME msvcr${MSVC_VER}.dll + PATHS + ${registry_find_path} + NO_DEFAULT_PATH + ) - unset(debug_msvc_redist_path CACHE) - endif() + if(EXISTS ${release_msvc_redist_path}) + set(release_msvc_files + msvcp${MSVC_VER}.dll + msvcr${MSVC_VER}.dll + vcruntime${MSVC_VER}.dll + ) - if(ADDRESS_SIZE EQUAL 32) - # this folder contains the 32bit DLLs.. (yes really!) - set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64") - else(ADDRESS_SIZE EQUAL 32) - # this folder contains the 64bit DLLs.. (yes really!) - set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32") - endif(ADDRESS_SIZE EQUAL 32) + copy_if_different( + ${release_msvc_redist_path} + "${SHARED_LIB_STAGING_DIR_RELEASE}" + out_targets + ${release_msvc_files} + ) + set(third_party_targets ${third_party_targets} ${out_targets}) - FIND_PATH(release_msvc_redist_path NAME msvcr${MSVC_VER}.dll - PATHS - ${registry_find_path} - NO_DEFAULT_PATH + copy_if_different( + ${release_msvc_redist_path} + "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" + out_targets + ${release_msvc_files} ) + set(third_party_targets ${third_party_targets} ${out_targets}) - if(EXISTS ${release_msvc_redist_path}) - set(release_msvc_files - msvcr${MSVC_VER}.dll - msvcp${MSVC_VER}.dll - ) - - copy_if_different( - ${release_msvc_redist_path} - "${SHARED_LIB_STAGING_DIR_RELEASE}" - out_targets - ${release_msvc_files} - ) - set(third_party_targets ${third_party_targets} ${out_targets}) - - copy_if_different( - ${release_msvc_redist_path} - "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" - out_targets - ${release_msvc_files} - ) - set(third_party_targets ${third_party_targets} ${out_targets}) - - unset(release_msvc_redist_path CACHE) - endif() - endforeach() + unset(release_msvc_redist_path CACHE) + endif() elseif(DARWIN) set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources") diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index bff18afd53..57099f8ac9 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -527,18 +527,8 @@ class WindowsManifest(ViewerManifest): # These need to be installed as a SxS assembly, currently a 'private' assembly. # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx - if self.args['configuration'].lower() == 'debug': - self.path("msvcr140d.dll") - self.path("msvcp140d.dll") - else: - # SL-12205: For reasons not yet diagnosed, an early build of - # the VS 2017 viewer requires VS 2013 runtime DLLs as well as - # VS 2017 runtime DLLs. - self.path("msvcr120.dll") - self.path("msvcp120.dll") - self.path("msvcr140.dll") - self.path("msvcp140.dll") - self.path("vcruntime140.dll") + self.path("msvcp140.dll") + self.path("vcruntime140.dll") # SLVoice executable with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')): @@ -612,10 +602,7 @@ class WindowsManifest(ViewerManifest): # MSVC DLLs needed for CEF and have to be in same directory as plugin with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'sharedlibs', 'Release')): - self.path("msvcp120.dll") - self.path("msvcr120.dll") self.path("msvcp140.dll") - self.path("msvcr140.dll") self.path("vcruntime140.dll") # CEF files common to all configurations -- cgit v1.3 From 44b9dd2e8076c703ad474a56a4bc1eb2a9d4529b Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 31 Oct 2019 14:46:11 -0400 Subject: DRTVWR-476, SL-12205: Search for msvcp140.dll, not msvcr140.dll Evidently, with VS 2017, what would have been msvcr140.dll has become vcruntime140.dll instead. msvcr140.dll is no longer a good sample DLL for which to search. --- indra/cmake/Copy3rdPartyLibs.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index c3309b2195..d662103ef4 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -94,7 +94,7 @@ if(WINDOWS) set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32") endif(ADDRESS_SIZE EQUAL 32) - FIND_PATH(release_msvc_redist_path NAME msvcr${MSVC_VER}.dll + FIND_PATH(release_msvc_redist_path NAME msvcp${MSVC_VER}.dll PATHS ${registry_find_path} NO_DEFAULT_PATH @@ -122,8 +122,11 @@ if(WINDOWS) ${release_msvc_files} ) set(third_party_targets ${third_party_targets} ${out_targets}) + MESSAGE(STATUS "Copied ${third_party_targets}") unset(release_msvc_redist_path CACHE) + else() + MESSAGE(SEND_ERROR "Redist libs for VC ${MSVC_VER} not found!") endif() elseif(DARWIN) -- cgit v1.3 From b08c44a0dc701f35f96b7700f56cf7000c254fe3 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 1 Nov 2019 10:33:05 -0400 Subject: DRTVWR-476, SL-12205: Refactor MSVC redist library copying. Specify all of msvcp$VER.dll, msvcr$VER.dll and vcruntime$VER.dll -- but check each of them individually, because any given VS release has only a subset of those. Add messaging to clarify what we're doing. Introduce to_staging_dirs CMake macro to cut down on redundant boilerplate: the idiom in which we use copy_if_different twice, once to the Release staging directory and once to the RelWithDebInfo staging directory, each time appending the target pathnames to third_party_targets. Replace that idiom with calls to to_staging_dirs. --- indra/cmake/Copy3rdPartyLibs.cmake | 108 ++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 62 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index d662103ef4..1365f7b9cc 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -7,6 +7,21 @@ include(CMakeCopyIfDifferent) include(Linking) +# When we copy our dependent libraries, we almost always want to copy them to +# both the Release and the RelWithDebInfo staging directories. This has +# resulted in duplicate (or worse, erroneous attempted duplicate) +# copy_if_different commands. Encapsulate that usage. +# Pass FROM_DIR, TARGETS and the files to copy. TO_DIR is implicit. +# to_staging_dirs diverges from copy_if_different in that it appends to TARGETS. +MACRO(to_staging_dirs from_dir targets) + foreach(staging_dir + "${SHARED_LIB_STAGING_DIR_RELEASE}" + "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}") + copy_if_different("${from_dir}" "${staging_dir}" out_targets ${ARGN}) + list(APPEND "${targets}" "${out_targets}") + endforeach() +ENDMACRO(to_staging_dirs from_dir to_dir targets) + ################################################################### # set up platform specific lists of files that need to be copied ################################################################### @@ -85,7 +100,6 @@ if(WINDOWS) MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake") endif (MSVC80) - MESSAGE(STATUS "Copying redist libs for VC ${MSVC_VER}") if(ADDRESS_SIZE EQUAL 32) # this folder contains the 32bit DLLs.. (yes really!) set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64") @@ -94,40 +108,34 @@ if(WINDOWS) set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32") endif(ADDRESS_SIZE EQUAL 32) - FIND_PATH(release_msvc_redist_path NAME msvcp${MSVC_VER}.dll - PATHS - ${registry_find_path} - NO_DEFAULT_PATH - ) + # Having a string containing the system registry path is a start, but to + # get CMake to actually read the registry, we must engage some other + # operation. + get_filename_component(registry_path "${registry_find_path}" ABSOLUTE) - if(EXISTS ${release_msvc_redist_path}) - set(release_msvc_files + # These are candidate DLL names. Empirically, VS versions before 2015 have + # msvcp*.dll and msvcr*.dll. VS 2017 has msvcp*.dll and vcruntime*.dll. + # Check each of them. + foreach(release_msvc_file msvcp${MSVC_VER}.dll msvcr${MSVC_VER}.dll vcruntime${MSVC_VER}.dll ) - - copy_if_different( - ${release_msvc_redist_path} - "${SHARED_LIB_STAGING_DIR_RELEASE}" - out_targets - ${release_msvc_files} - ) - set(third_party_targets ${third_party_targets} ${out_targets}) - - copy_if_different( - ${release_msvc_redist_path} - "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" - out_targets - ${release_msvc_files} - ) - set(third_party_targets ${third_party_targets} ${out_targets}) - MESSAGE(STATUS "Copied ${third_party_targets}") - - unset(release_msvc_redist_path CACHE) - else() - MESSAGE(SEND_ERROR "Redist libs for VC ${MSVC_VER} not found!") - endif() + if(EXISTS "${registry_path}/${release_msvc_file}") + to_staging_dirs( + ${registry_path} + third_party_targets + ${release_msvc_file}) + else() + # This isn't a WARNING because, as noted above, every VS version + # we've observed has only a subset of the specified DLL names. + MESSAGE(STATUS "Redist lib ${release_msvc_file} not found") + endif() + endforeach() + MESSAGE(STATUS "Will copy redist files for MSVC ${MSVC_VER}:") + foreach(target ${third_party_targets}) + MESSAGE(STATUS "${target}") + endforeach() elseif(DARWIN) set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources") @@ -239,52 +247,28 @@ endif(WINDOWS) # Done building the file lists, now set up the copy commands. ################################################################ -copy_if_different( - ${vivox_lib_dir} - "${SHARED_LIB_STAGING_DIR_DEBUG}" - out_targets - ${vivox_libs} - ) -set(third_party_targets ${third_party_targets} ${out_targets}) - +# Curiously, slvoice_files are only copied to SHARED_LIB_STAGING_DIR_RELEASE. +# It's unclear whether this is oversight or intentional, but anyway leave the +# single copy_if_different command rather than using to_staging_dirs. copy_if_different( ${slvoice_src_dir} "${SHARED_LIB_STAGING_DIR_RELEASE}" out_targets ${slvoice_files} ) -copy_if_different( - ${vivox_lib_dir} - "${SHARED_LIB_STAGING_DIR_RELEASE}" - out_targets - ${vivox_libs} - ) - -set(third_party_targets ${third_party_targets} ${out_targets}) +list(APPEND third_party_targets ${out_targets}) -copy_if_different( +to_staging_dirs( ${vivox_lib_dir} - "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" - out_targets + third_party_targets ${vivox_libs} ) -set(third_party_targets ${third_party_targets} ${out_targets}) -copy_if_different( +to_staging_dirs( ${release_src_dir} - "${SHARED_LIB_STAGING_DIR_RELEASE}" - out_targets - ${release_files} - ) -set(third_party_targets ${third_party_targets} ${out_targets}) - -copy_if_different( - ${release_src_dir} - "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}" - out_targets + third_party_targets ${release_files} ) -set(third_party_targets ${third_party_targets} ${out_targets}) if(NOT USESYSTEMLIBS) add_custom_target( -- cgit v1.3 From 56e4a676e9398365561017b2b9b121a2531f2605 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 9 Apr 2020 08:49:08 -0400 Subject: DRTVWR-476: For Boost 1.72, must suffix lib names with -x{32,64} --- indra/cmake/Boost.cmake | 102 +++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 49 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake index e05e3ca0e5..06a7ab6d75 100644 --- a/indra/cmake/Boost.cmake +++ b/indra/cmake/Boost.cmake @@ -18,11 +18,15 @@ if (USESYSTEMLIBS) else (USESYSTEMLIBS) use_prebuilt_binary(boost) set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include) - set(BOOST_VERSION "1.55") + + # As of sometime between Boost 1.67 and 1.72, Boost libraries are suffixed + # with the address size. + set(addrsfx "-x${ADDRESS_SIZE}") if (WINDOWS) if(MSVC80) # This should be obsolete at this point + set(BOOST_VERSION "1.55") set(BOOST_CONTEXT_LIBRARY optimized libboost_context-vc80-mt-${BOOST_VERSION} debug libboost_context-vc80-mt-gd-${BOOST_VERSION}) @@ -47,80 +51,80 @@ else (USESYSTEMLIBS) else(MSVC80) # MSVC 10.0 config set(BOOST_CONTEXT_LIBRARY - optimized libboost_context-mt - debug libboost_context-mt-gd) + optimized libboost_context-mt${addrsfx} + debug libboost_context-mt${addrsfx}-gd) set(BOOST_FIBER_LIBRARY - optimized libboost_fiber-mt - debug libboost_fiber-mt-gd) + optimized libboost_fiber-mt${addrsfx} + debug libboost_fiber-mt${addrsfx}-gd) set(BOOST_FILESYSTEM_LIBRARY - optimized libboost_filesystem-mt - debug libboost_filesystem-mt-gd) + optimized libboost_filesystem-mt${addrsfx} + debug libboost_filesystem-mt${addrsfx}-gd) set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized libboost_program_options-mt - debug libboost_program_options-mt-gd) + optimized libboost_program_options-mt${addrsfx} + debug libboost_program_options-mt${addrsfx}-gd) set(BOOST_REGEX_LIBRARY - optimized libboost_regex-mt - debug libboost_regex-mt-gd) + optimized libboost_regex-mt${addrsfx} + debug libboost_regex-mt${addrsfx}-gd) set(BOOST_SIGNALS_LIBRARY - optimized libboost_signals-mt - debug libboost_signals-mt-gd) + optimized libboost_signals-mt${addrsfx} + debug libboost_signals-mt${addrsfx}-gd) set(BOOST_SYSTEM_LIBRARY - optimized libboost_system-mt - debug libboost_system-mt-gd) + optimized libboost_system-mt${addrsfx} + debug libboost_system-mt${addrsfx}-gd) set(BOOST_THREAD_LIBRARY - optimized libboost_thread-mt - debug libboost_thread-mt-gd) + optimized libboost_thread-mt${addrsfx} + debug libboost_thread-mt${addrsfx}-gd) endif (MSVC80) elseif (LINUX) set(BOOST_CONTEXT_LIBRARY - optimized boost_context-mt - debug boost_context-mt-d) + optimized boost_context-mt${addrsfx} + debug boost_context-mt${addrsfx}-d) set(BOOST_FIBER_LIBRARY - optimized boost_fiber-mt - debug boost_fiber-mt-d) + optimized boost_fiber-mt${addrsfx} + debug boost_fiber-mt${addrsfx}-d) set(BOOST_FILESYSTEM_LIBRARY - optimized boost_filesystem-mt - debug boost_filesystem-mt-d) + optimized boost_filesystem-mt${addrsfx} + debug boost_filesystem-mt${addrsfx}-d) set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized boost_program_options-mt - debug boost_program_options-mt-d) + optimized boost_program_options-mt${addrsfx} + debug boost_program_options-mt${addrsfx}-d) set(BOOST_REGEX_LIBRARY - optimized boost_regex-mt - debug boost_regex-mt-d) + optimized boost_regex-mt${addrsfx} + debug boost_regex-mt${addrsfx}-d) set(BOOST_SIGNALS_LIBRARY - optimized boost_signals-mt - debug boost_signals-mt-d) + optimized boost_signals-mt${addrsfx} + debug boost_signals-mt${addrsfx}-d) set(BOOST_SYSTEM_LIBRARY - optimized boost_system-mt - debug boost_system-mt-d) + optimized boost_system-mt${addrsfx} + debug boost_system-mt${addrsfx}-d) set(BOOST_THREAD_LIBRARY - optimized boost_thread-mt - debug boost_thread-mt-d) + optimized boost_thread-mt${addrsfx} + debug boost_thread-mt${addrsfx}-d) elseif (DARWIN) set(BOOST_CONTEXT_LIBRARY - optimized boost_context-mt - debug boost_context-mt-d) + optimized boost_context-mt${addrsfx} + debug boost_context-mt${addrsfx}-d) set(BOOST_FIBER_LIBRARY - optimized boost_fiber-mt - debug boost_fiber-mt-d) + optimized boost_fiber-mt${addrsfx} + debug boost_fiber-mt${addrsfx}-d) set(BOOST_FILESYSTEM_LIBRARY - optimized boost_filesystem-mt - debug boost_filesystem-mt-d) + optimized boost_filesystem-mt${addrsfx} + debug boost_filesystem-mt${addrsfx}-d) set(BOOST_PROGRAM_OPTIONS_LIBRARY - optimized boost_program_options-mt - debug boost_program_options-mt-d) + optimized boost_program_options-mt${addrsfx} + debug boost_program_options-mt${addrsfx}-d) set(BOOST_REGEX_LIBRARY - optimized boost_regex-mt - debug boost_regex-mt-d) + optimized boost_regex-mt${addrsfx} + debug boost_regex-mt${addrsfx}-d) set(BOOST_SIGNALS_LIBRARY - optimized boost_signals-mt - debug boost_signals-mt-d) + optimized boost_signals-mt${addrsfx} + debug boost_signals-mt${addrsfx}-d) set(BOOST_SYSTEM_LIBRARY - optimized boost_system-mt - debug boost_system-mt-d) + optimized boost_system-mt${addrsfx} + debug boost_system-mt${addrsfx}-d) set(BOOST_THREAD_LIBRARY - optimized boost_thread-mt - debug boost_thread-mt-d) + optimized boost_thread-mt${addrsfx} + debug boost_thread-mt${addrsfx}-d) endif (WINDOWS) endif (USESYSTEMLIBS) -- cgit v1.3 From 92c70ff637da5fda06aaeb40914c77499bf2d0ce Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 7 May 2020 16:59:19 -0400 Subject: DRTVWR-476: Help DirectX.cmake cope with multiple SDK versions. First, get rid of ancient cruft in the find_path() calls: on a 64-bit system, "$ENV{PROGRAMFILES}" expands to the 64-bit 'Program Files' directory rather than the 32-bit 'Program Files (x86)' directory, and none of the ancient cruft would be found there anyway. Empirically, find_path(dxdiag.h) is able to find the file using environment variables (INCLUDE from VS variables?), so it doesn't need the specific pathnames coded into that call. Once we find DIRECTX_INCLUDE_DIR, don't immediately insert it into include_directories: we've had troubles with incompatible Windows SDK versions (compile errors in Microsoft header files!) when DIRECTX_INCLUDE_DIR preceded the Windows SDK directory in the include path. The DIRECTX_FIND_QUIETLY logic seemed backwards: the message(STATUS) output was emitted only when DIRECTX_FIND_QUIETLY was false. Reverse that. The ancient cruft in find_path(dxguid.lib) was causing it to find the wrong (very old) DirectX library. Remove ancient cruft. But empirically, without that, even once we've found DIRECTX_INCLUDE_DIR, CMake could not implicitly find dxguid.lib. If the DirectX directory hierarchy were structured as .../version/Include and .../version/Lib, a relative pathname would have been sufficient hint. Unfortunately it's structured as .../Include/version and .../Lib/version, so a relative pathname would have to include the specific version. Instead, replace "/Include/" with "/Lib/". But even then, we have to drill down to the architecture-specific subdirectory based on ADDRESS_SIZE. --- indra/cmake/DirectX.cmake | 52 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 33 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake index 25163d0322..201b157264 100644 --- a/indra/cmake/DirectX.cmake +++ b/indra/cmake/DirectX.cmake @@ -1,46 +1,32 @@ # -*- cmake -*- if (WINDOWS) - find_path(DIRECTX_INCLUDE_DIR dxdiag.h - "$ENV{DXSDK_DIR}/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Include" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Include" - "C:/DX90SDK/Include" - "$ENV{PROGRAMFILES}/DX90SDK/Include" - ) + find_path(DIRECTX_INCLUDE_DIR dxdiag.h) if (DIRECTX_INCLUDE_DIR) - include_directories(${DIRECTX_INCLUDE_DIR}) - if (DIRECTX_FIND_QUIETLY) + if (NOT DIRECTX_FIND_QUIETLY) message(STATUS "Found DirectX include: ${DIRECTX_INCLUDE_DIR}") - endif (DIRECTX_FIND_QUIETLY) + endif (NOT DIRECTX_FIND_QUIETLY) else (DIRECTX_INCLUDE_DIR) message(FATAL_ERROR "Could not find DirectX SDK Include") endif (DIRECTX_INCLUDE_DIR) - - find_path(DIRECTX_LIBRARY_DIR dxguid.lib - "$ENV{DXSDK_DIR}/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2008)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (November 2007)/Lib/x86" - "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2007)/Lib/x86" - "C:/DX90SDK/Lib" - "$ENV{PROGRAMFILES}/DX90SDK/Lib" - ) + # dxhint isn't meant to be the hard-coded DIRECTX_LIBRARY_DIR, we're just + # suggesting it as a hint to the next find_path(). The version is embedded + # in the DIRECTX_INCLUDE_DIR path string after Include and Lib, which is why + # we don't just append a relative path: if there are multiple versions + # installed on the host, we need to be sure we're using THE SAME version. + string(REPLACE "/Include/" "/Lib/" dxhint "${DIRECTX_INCLUDE_DIR}") + if (ADDRESS_SIZE EQUAL 32) + set(archdir x86) + else() + set(archdir x64) + endif() + string(APPEND dxhint "/${archdir}") + find_path(DIRECTX_LIBRARY_DIR dxguid.lib HINTS "${dxhint}") if (DIRECTX_LIBRARY_DIR) - if (DIRECTX_FIND_QUIETLY) - message(STATUS "Found DirectX include: ${DIRECTX_LIBRARY_DIR}") - endif (DIRECTX_FIND_QUIETLY) + if (NOT DIRECTX_FIND_QUIETLY) + message(STATUS "Found DirectX library: ${DIRECTX_LIBRARY_DIR}") + endif (NOT DIRECTX_FIND_QUIETLY) else (DIRECTX_LIBRARY_DIR) message(FATAL_ERROR "Could not find DirectX SDK Libraries") endif (DIRECTX_LIBRARY_DIR) -- cgit v1.3 From c74810ca3fc7e5a3f6b84a3d3259294aaa9288be Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Mon, 11 May 2020 11:39:27 -0400 Subject: DRTVWR-476: Use find_library(dxguid) rather than find_path(). --- indra/cmake/DirectX.cmake | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'indra/cmake') diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake index 201b157264..be9797b575 100644 --- a/indra/cmake/DirectX.cmake +++ b/indra/cmake/DirectX.cmake @@ -11,10 +11,11 @@ if (WINDOWS) endif (DIRECTX_INCLUDE_DIR) # dxhint isn't meant to be the hard-coded DIRECTX_LIBRARY_DIR, we're just - # suggesting it as a hint to the next find_path(). The version is embedded - # in the DIRECTX_INCLUDE_DIR path string after Include and Lib, which is why - # we don't just append a relative path: if there are multiple versions - # installed on the host, we need to be sure we're using THE SAME version. + # suggesting it as a hint to find_library(). The Windows SDK version number + # is embedded in the DIRECTX_INCLUDE_DIR path string after Include and Lib, + # which is why we don't just append a relative path: if there are multiple + # versions installed on the host, we need to be sure we're using THE SAME + # version. string(REPLACE "/Include/" "/Lib/" dxhint "${DIRECTX_INCLUDE_DIR}") if (ADDRESS_SIZE EQUAL 32) set(archdir x86) @@ -22,7 +23,8 @@ if (WINDOWS) set(archdir x64) endif() string(APPEND dxhint "/${archdir}") - find_path(DIRECTX_LIBRARY_DIR dxguid.lib HINTS "${dxhint}") + find_library(DXGUID_LIBRARY dxguid HINTS "${dxhint}") + get_filename_component(DIRECTX_LIBRARY_DIR "${DXGUID_LIBRARY}" DIRECTORY) if (DIRECTX_LIBRARY_DIR) if (NOT DIRECTX_FIND_QUIETLY) message(STATUS "Found DirectX library: ${DIRECTX_LIBRARY_DIR}") -- cgit v1.3 From 6148a6443af886f9b71b4c88084db943950e146c Mon Sep 17 00:00:00 2001 From: Nicky Dasmijn Date: Tue, 19 May 2020 00:03:19 +0200 Subject: Remove DirectX.cmake. With recent SDKs (dating back to at least VS 2013 and the 8.1 SDK) DirectX is included in the SDK and does not need any special detection logic. --- indra/cmake/CMakeLists.txt | 1 - indra/cmake/DirectX.cmake | 36 ------------------------------------ indra/llwindow/CMakeLists.txt | 1 - indra/newview/CMakeLists.txt | 1 - 4 files changed, 39 deletions(-) delete mode 100644 indra/cmake/DirectX.cmake (limited to 'indra/cmake') diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 84e1c5d6fd..7864271c02 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -22,7 +22,6 @@ set(cmake_SOURCE_FILES Copy3rdPartyLibs.cmake DBusGlib.cmake DeploySharedLibs.cmake - DirectX.cmake DragDrop.cmake EXPAT.cmake FindAPR.cmake diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake deleted file mode 100644 index be9797b575..0000000000 --- a/indra/cmake/DirectX.cmake +++ /dev/null @@ -1,36 +0,0 @@ -# -*- cmake -*- - -if (WINDOWS) - find_path(DIRECTX_INCLUDE_DIR dxdiag.h) - if (DIRECTX_INCLUDE_DIR) - if (NOT DIRECTX_FIND_QUIETLY) - message(STATUS "Found DirectX include: ${DIRECTX_INCLUDE_DIR}") - endif (NOT DIRECTX_FIND_QUIETLY) - else (DIRECTX_INCLUDE_DIR) - message(FATAL_ERROR "Could not find DirectX SDK Include") - endif (DIRECTX_INCLUDE_DIR) - - # dxhint isn't meant to be the hard-coded DIRECTX_LIBRARY_DIR, we're just - # suggesting it as a hint to find_library(). The Windows SDK version number - # is embedded in the DIRECTX_INCLUDE_DIR path string after Include and Lib, - # which is why we don't just append a relative path: if there are multiple - # versions installed on the host, we need to be sure we're using THE SAME - # version. - string(REPLACE "/Include/" "/Lib/" dxhint "${DIRECTX_INCLUDE_DIR}") - if (ADDRESS_SIZE EQUAL 32) - set(archdir x86) - else() - set(archdir x64) - endif() - string(APPEND dxhint "/${archdir}") - find_library(DXGUID_LIBRARY dxguid HINTS "${dxhint}") - get_filename_component(DIRECTX_LIBRARY_DIR "${DXGUID_LIBRARY}" DIRECTORY) - if (DIRECTX_LIBRARY_DIR) - if (NOT DIRECTX_FIND_QUIETLY) - message(STATUS "Found DirectX library: ${DIRECTX_LIBRARY_DIR}") - endif (NOT DIRECTX_FIND_QUIETLY) - else (DIRECTX_LIBRARY_DIR) - message(FATAL_ERROR "Could not find DirectX SDK Libraries") - endif (DIRECTX_LIBRARY_DIR) - -endif (WINDOWS) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 0743fd899f..5476dc324c 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -11,7 +11,6 @@ project(llwindow) include(00-Common) -include(DirectX) include(DragDrop) include(LLCommon) include(LLImage) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index a01e6ee4f6..6f21ec93cc 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -15,7 +15,6 @@ include(BuildPackagesInfo) include(BuildVersion) include(CMakeCopyIfDifferent) include(DBusGlib) -include(DirectX) include(DragDrop) include(EXPAT) include(FMODEX) -- cgit v1.3 From e7d3b7cc9356dcf76b5f9a1bf4c9c833d180b2f8 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 26 Jun 2020 11:16:38 -0400 Subject: DRTVWR-476: On Windows, request 64-bit compiler to avoid TeamCity build failures due to 32-bit compiler running out of virtual memory for precompiled headers. --- indra/cmake/00-Common.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/cmake') diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 03da30649a..865c057e33 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -60,7 +60,10 @@ if (WINDOWS) # http://www.cmake.org/pipermail/cmake/2009-September/032143.html string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + # Without PreferredToolArchitecture=x64, as of 2020-06-26 the 32-bit + # compiler on our TeamCity build hosts has started running out of virtual + # memory for the precompiled header file. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /p:PreferredToolArchitecture=x64") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo" -- cgit v1.3