diff options
Diffstat (limited to 'indra/llcommon')
| -rwxr-xr-x | indra/llcommon/CMakeLists.txt | 1 | ||||
| -rwxr-xr-x | indra/llcommon/llapr.h | 2 | ||||
| -rwxr-xr-x | indra/llcommon/llcoros.cpp | 2 | ||||
| -rwxr-xr-x | indra/llcommon/llcoros.h | 6 | ||||
| -rwxr-xr-x | indra/llcommon/lleventcoro.h | 16 | ||||
| -rwxr-xr-x | indra/llcommon/llsys.cpp | 174 | ||||
| -rwxr-xr-x | indra/llcommon/llsys.h | 3 | ||||
| -rwxr-xr-x | indra/llcommon/tests/lleventcoro_test.cpp | 12 | 
8 files changed, 164 insertions, 52 deletions
| diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 3e57280067..95b1d536fe 100755 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -247,7 +247,6 @@ set(llcommon_HEADER_FILES      lluuid.h      lluuidhashmap.h      llversionserver.h -    llversionviewer.h      llworkerthread.h      ll_template_cast.h      metaclass.h diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 034546c3f3..752574c65d 100755 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -182,8 +182,10 @@ typedef LLAtomic32<S32> LLAtomicS32;  // abbreviated flags  #define LL_APR_R (APR_READ) // "r"  #define LL_APR_W (APR_CREATE|APR_TRUNCATE|APR_WRITE) // "w" +#define LL_APR_A (APR_CREATE|APR_WRITE|APR_APPEND) // "w"  #define LL_APR_RB (APR_READ|APR_BINARY) // "rb"  #define LL_APR_WB (APR_CREATE|APR_TRUNCATE|APR_WRITE|APR_BINARY) // "wb" +#define LL_APR_AB (APR_CREATE|APR_WRITE|APR_BINARY|APR_APPEND)  #define LL_APR_RPB (APR_READ|APR_WRITE|APR_BINARY) // "r+b"  #define LL_APR_WPB (APR_CREATE|APR_TRUNCATE|APR_READ|APR_WRITE|APR_BINARY) // "w+b" diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp index 0b5829eb7e..9122704306 100755 --- a/indra/llcommon/llcoros.cpp +++ b/indra/llcommon/llcoros.cpp @@ -115,7 +115,7 @@ std::string LLCoros::getNameByID(const void* self_id) const      // passed to us comes.      for (CoroMap::const_iterator mi(mCoros.begin()), mend(mCoros.end()); mi != mend; ++mi)      { -        namespace coro_private = boost::coroutines::detail; +        namespace coro_private = boost::dcoroutines::detail;          if (static_cast<void*>(coro_private::coroutine_accessor::get_impl(const_cast<coro&>(*mi->second)).get())              == self_id)          { diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h index d75f28ec1a..03df406b68 100755 --- a/indra/llcommon/llcoros.h +++ b/indra/llcommon/llcoros.h @@ -29,7 +29,7 @@  #if ! defined(LL_LLCOROS_H)  #define LL_LLCOROS_H -#include <boost/coroutine/coroutine.hpp> +#include <boost/dcoroutine/coroutine.hpp>  #include "llsingleton.h"  #include <boost/ptr_container/ptr_map.hpp>  #include <string> @@ -78,8 +78,8 @@  class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>  {  public: -    /// Canonical boost::coroutines::coroutine signature we use -    typedef boost::coroutines::coroutine<void()> coro; +    /// Canonical boost::dcoroutines::coroutine signature we use +    typedef boost::dcoroutines::coroutine<void()> coro;      /// Canonical 'self' type      typedef coro::self self; diff --git a/indra/llcommon/lleventcoro.h b/indra/llcommon/lleventcoro.h index 88a5e6ec74..a42af63b65 100755 --- a/indra/llcommon/lleventcoro.h +++ b/indra/llcommon/lleventcoro.h @@ -29,8 +29,8 @@  #if ! defined(LL_LLEVENTCORO_H)  #define LL_LLEVENTCORO_H -#include <boost/coroutine/coroutine.hpp> -#include <boost/coroutine/future.hpp> +#include <boost/dcoroutine/coroutine.hpp> +#include <boost/dcoroutine/future.hpp>  #include <boost/optional.hpp>  #include <string>  #include <stdexcept> @@ -206,13 +206,13 @@ LLSD postAndWait(SELF& self, const LLSD& event, const LLEventPumpOrPumpName& req                   const LLEventPumpOrPumpName& replyPump, const LLSD& replyPumpNamePath=LLSD())  {      // declare the future -    boost::coroutines::future<LLSD> future(self); +    boost::dcoroutines::future<LLSD> future(self);      // make a callback that will assign a value to the future, and listen on      // the specified LLEventPump with that callback      std::string listenerName(LLEventDetail::listenerNameForCoro(self));      LLTempBoundListener connection(          replyPump.getPump().listen(listenerName, -                                   voidlistener(boost::coroutines::make_callback(future)))); +                                   voidlistener(boost::dcoroutines::make_callback(future))));      // skip the "post" part if requestPump is default-constructed      if (requestPump)      { @@ -257,7 +257,7 @@ namespace LLEventDetail       * This helper is specifically for the two-pump version of waitForEventOn().       * 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::coroutines::make_callback() (void return) to provide an event +     * boost::dcoroutines::make_callback() (void return) to provide an event       * listener (bool return), we've adapted LLVoidListener for the purpose. The       * basic idea is that we construct a distinct instance of WaitForEventOnHelper       * -- binding different instance data -- for each of the pumps. Then, when a @@ -331,16 +331,16 @@ LLEventWithID postAndWait2(SELF& self, const LLSD& event,                             const LLSD& replyPump1NamePath=LLSD())  {      // declare the future -    boost::coroutines::future<LLEventWithID> future(self); +    boost::dcoroutines::future<LLEventWithID> future(self);      // either callback will assign a value to this future; listen on      // each specified LLEventPump with a callback      std::string name(LLEventDetail::listenerNameForCoro(self));      LLTempBoundListener connection0(          replyPump0.getPump().listen(name + "a", -                               LLEventDetail::wfeoh(boost::coroutines::make_callback(future), 0))); +                               LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 0)));      LLTempBoundListener connection1(          replyPump1.getPump().listen(name + "b", -                               LLEventDetail::wfeoh(boost::coroutines::make_callback(future), 1))); +                               LLEventDetail::wfeoh(boost::dcoroutines::make_callback(future), 1)));      // skip the "post" part if requestPump is default-constructed      if (requestPump)      { diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index c96f2191f3..57a6de9060 100755 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -80,6 +80,7 @@ using namespace llsd;  #	include <sys/sysinfo.h>  #   include <stdexcept>  const char MEMINFO_FILE[] = "/proc/meminfo"; +#   include <gnu/libc-version.h>  #elif LL_SOLARIS  #	include <stdio.h>  #	include <unistd.h> @@ -175,8 +176,41 @@ bool get_shell32_dll_version(DWORD& major, DWORD& minor, DWORD& build_number)  }  #endif // LL_WINDOWS +// Wrap boost::regex_match() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_match_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_match(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} + +// Wrap boost::regex_search() with a function that doesn't throw. +template <typename S, typename M, typename R> +static bool regex_search_no_exc(const S& string, M& match, const R& regex) +{ +    try +    { +        return boost::regex_search(string, match, regex); +    } +    catch (const std::runtime_error& e) +    { +        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': " +                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; +        return false; +    } +} + +  LLOSInfo::LLOSInfo() : -	mMajorVer(0), mMinorVer(0), mBuild(0) +	mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("")	   {  #if LL_WINDOWS @@ -412,6 +446,102 @@ LLOSInfo::LLOSInfo() :  		mOSString = mOSStringSimple;  	} +#elif LL_LINUX +	 +	struct utsname un; +	if(uname(&un) != -1) +	{ +		mOSStringSimple.append(un.sysname); +		mOSStringSimple.append(" "); +		mOSStringSimple.append(un.release); + +		mOSString = mOSStringSimple; +		mOSString.append(" "); +		mOSString.append(un.version); +		mOSString.append(" "); +		mOSString.append(un.machine); + +		// Simplify 'Simple' +		std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0)); +		if (ostype == "Linux") +		{ +			// Only care about major and minor Linux versions, truncate at second '.' +			std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0); +			std::string::size_type idx2 = (idx1 != std::string::npos) ? mOSStringSimple.find_first_of(".", idx1+1) : std::string::npos; +			std::string simple = mOSStringSimple.substr(0, idx2); +			if (simple.length() > 0) +				mOSStringSimple = simple; +		} +	} +	else +	{ +		mOSStringSimple.append("Unable to collect OS info"); +		mOSString = mOSStringSimple; +	} + +	const char OS_VERSION_MATCH_EXPRESSION[] = "([0-9]+)\\.([0-9]+)(\\.([0-9]+))?"; +	boost::regex os_version_parse(OS_VERSION_MATCH_EXPRESSION); +	boost::smatch matched; + +	std::string glibc_version(gnu_get_libc_version()); +	if ( regex_match_no_exc(glibc_version, matched, os_version_parse) ) +	{ +		LL_INFOS("AppInit") << "Using glibc version '" << glibc_version << "' as OS version" << LL_ENDL; +	 +		std::string version_value; + +		if ( matched[1].matched ) // Major version +		{ +			version_value.assign(matched[1].first, matched[1].second); +			if (sscanf(version_value.c_str(), "%d", &mMajorVer) != 1) +			{ +			  LL_WARNS("AppInit") << "failed to parse major version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_ERRS("AppInit") +				<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION  +				<< "' returned true, but major version [1] did not match" +				<< LL_ENDL; +		} + +		if ( matched[2].matched ) // Minor version +		{ +			version_value.assign(matched[2].first, matched[2].second); +			if (sscanf(version_value.c_str(), "%d", &mMinorVer) != 1) +			{ +			  LL_ERRS("AppInit") << "failed to parse minor version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_ERRS("AppInit") +				<< "OS version regex '" << OS_VERSION_MATCH_EXPRESSION  +				<< "' returned true, but minor version [1] did not match" +				<< LL_ENDL; +		} + +		if ( matched[4].matched ) // Build version (optional) - note that [3] includes the '.' +		{ +			version_value.assign(matched[4].first, matched[4].second); +			if (sscanf(version_value.c_str(), "%d", &mBuild) != 1) +			{ +			  LL_ERRS("AppInit") << "failed to parse build version '" << version_value << "' as a number" << LL_ENDL; +			} +		} +		else +		{ +			LL_INFOS("AppInit") +				<< "OS build version not provided; using zero" +				<< LL_ENDL; +		} +	} +	else +	{ +		LL_WARNS("AppInit") << "glibc version '" << glibc_version << "' cannot be parsed to three numbers; using all zeros" << LL_ENDL; +	} +  #else  	struct utsname un; @@ -444,8 +574,13 @@ LLOSInfo::LLOSInfo() :  		mOSStringSimple.append("Unable to collect OS info");  		mOSString = mOSStringSimple;  	} +  #endif +	std::stringstream dotted_version_string; +	dotted_version_string << mMajorVer << "." << mMinorVer << "." << mBuild; +	mOSVersionString.append(dotted_version_string.str()); +  }  #ifndef LL_WINDOWS @@ -496,6 +631,11 @@ const std::string& LLOSInfo::getOSStringSimple() const  	return mOSStringSimple;  } +const std::string& LLOSInfo::getOSVersionString() const +{ +	return mOSVersionString; +} +  const S32 STATUS_SIZE = 8192;  //static @@ -687,38 +827,6 @@ private:  	LLSD mStats;  }; -// Wrap boost::regex_match() with a function that doesn't throw. -template <typename S, typename M, typename R> -static bool regex_match_no_exc(const S& string, M& match, const R& regex) -{ -    try -    { -        return boost::regex_match(string, match, regex); -    } -    catch (const std::runtime_error& e) -    { -        LL_WARNS("LLMemoryInfo") << "error matching with '" << regex.str() << "': " -                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; -        return false; -    } -} - -// Wrap boost::regex_search() with a function that doesn't throw. -template <typename S, typename M, typename R> -static bool regex_search_no_exc(const S& string, M& match, const R& regex) -{ -    try -    { -        return boost::regex_search(string, match, regex); -    } -    catch (const std::runtime_error& e) -    { -        LL_WARNS("LLMemoryInfo") << "error searching with '" << regex.str() << "': " -                                 << e.what() << ":\n'" << string << "'" << LL_ENDL; -        return false; -    } -} -  LLMemoryInfo::LLMemoryInfo()  {  	refresh(); diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 739e795d3a..cfed0fff17 100755 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -49,6 +49,8 @@ public:  	const std::string& getOSString() const;  	const std::string& getOSStringSimple() const; +	const std::string& getOSVersionString() const; +	  	S32 mMajorVer;  	S32 mMinorVer;  	S32 mBuild; @@ -62,6 +64,7 @@ public:  private:  	std::string mOSString;  	std::string mOSStringSimple; +	std::string mOSVersionString;  }; diff --git a/indra/llcommon/tests/lleventcoro_test.cpp b/indra/llcommon/tests/lleventcoro_test.cpp index 901ba35b2f..8d12529613 100755 --- a/indra/llcommon/tests/lleventcoro_test.cpp +++ b/indra/llcommon/tests/lleventcoro_test.cpp @@ -64,10 +64,10 @@  // 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 <boost/coroutine/coroutine.hpp> +#include <boost/dcoroutine/coroutine.hpp>  // Normally, lleventcoro.h obviates future.hpp. We only include this because  // we implement a "by hand" test of future functionality. -#include <boost/coroutine/future.hpp> +#include <boost/dcoroutine/future.hpp>  #include <boost/bind.hpp>  #include <boost/range.hpp> @@ -87,7 +87,7 @@  /*****************************************************************************  *   from the banana.cpp example program borrowed for test<1>()  *****************************************************************************/ -namespace coroutines = boost::coroutines; +namespace coroutines = boost::dcoroutines;  using coroutines::coroutine;  template<typename Iter> @@ -122,7 +122,7 @@ typedef coroutine<std::string::iterator(void)> match_coroutine_type;  *   Test helpers  *****************************************************************************/  // I suspect this will be typical of coroutines used in Linden software -typedef boost::coroutines::coroutine<void()> coroutine_type; +typedef boost::dcoroutines::coroutine<void()> coroutine_type;  /// Simulate an event API whose response is immediate: sent on receipt of the  /// initial request, rather than after some delay. This is the case that @@ -173,10 +173,10 @@ namespace tut                  // ... do whatever preliminary stuff must happen ...                  // declare the future -                boost::coroutines::future<LLSD> future(self); +                boost::dcoroutines::future<LLSD> future(self);                  // tell the future what to wait for                  LLTempBoundListener connection( -                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::coroutines::make_callback(future)))); +                    LLEventPumps::instance().obtain("source").listen("coro", voidlistener(boost::dcoroutines::make_callback(future))));                  ensure("Not yet", ! future);                  // attempting to dereference ("resolve") the future causes the calling                  // coroutine to wait for it | 
