From c231c97eeefc484b74198ba86251054b7dc0e6bb Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 2 May 2024 21:13:28 -0400 Subject: WIP: In llcallbacklist.h, add singleton LLLater for time delays. The big idea is to reduce the number of per-tick callbacks asking, "Is it time yet? Is it time yet?" We do that for LLEventTimer and LLEventTimeout. LLLater presents doAtTime(LLDate), with doAfterInterval() and doPeriodically() methods implemented using doAtTime(). All return handles. The free functions doAfterInterval() and doPeriodically() now forward to the corresponding LLLater methods. LLLater also presents isRunning(handle) and cancel(handle). LLLater borrows the tactic of LLEventTimer: while there's at least one running timer, it registers an LLCallbackList tick() callback to service ready timers. But instead of looping over all of them asking, "Are you ready?" it keeps them in a priority queue ordered by desired timestamp, and only touches those whose timestamp has been reached. Also, it honors a maximum time slice: once the ready timers have run for longer than the limit, it defers processing other ready timers to the next tick() call. The intent is to consume fewer cycles per tick() call, both by the management machinery and the timers themselves. Revamp LLCallbackList to accept C++ callables in addition to (classic C function pointer, void*) pairs. Make addFunction() return a handle (different than LLLater handles) that can be passed to a new deleteFunction() overload, since std::function instances can't be compared for equality. In fact, implement LLCallbackList using boost::signals2::signal, which provides almost exactly what we want. LLCallbackList continues to accept (function pointer, void*) pairs, but now we store a lambda that calls the function pointer with that void*. It takes less horsing around to create a C++ callable from a (function pointer, void*) pair than the other way around. For containsFunction() and deleteFunction(), such pairs are the keys for a lookup table whose values are handles. Instead of having a static global LLCallbackList gIdleCallbacks, make LLCallbackList an LLSingleton to guarantee initialization. For backwards compatibility, gIdleCallbacks is now a macro for LLCallbackList::instance(). Move doOnIdleOneTime() and doOnIdleRepeating() functions to LLCallbackList methods, but for backwards compatibility continue providing free functions. Reimplement LLEventTimer using LLLater::doPeriodically(). One implication is that LLEventTimer need no longer be derived from LLInstanceTracker, which we used to iterate over all instances every tick. Give it start() and stop() methods, since some subclasses (e.g. LLFlashTimer) used to call its member LLTimer's start() and stop(). Remove updateClass(): LLCallbackList::callFunctions() now takes care of that. Remove LLToastLifeTimer::start() and stop(), since LLEventTimer now provides those. Remove getRemainingTimeF32(), since LLLater does not (yet) provide that feature. While at it, make LLEventTimer::tick() return bool instead of BOOL, and change existing overrides. Make LLApp::stepFrame() call LLCallbackList::callFunctions() instead of LLEventTimer::updateClass(). We could have refactored LLEventTimer to use the mechanism now built into LLLater, but frankly the LLEventTimer API is rather clumsy. You MUST derive a subclass and override tick(), and you must instantiate your subclass on the heap because, when your tick() override returns false, LLEventTimer deletes its subclass instance. The LLLater API is simpler to use, and LLEventTimer is much simplified by using it. Merge lleventfilter.h's LLEventTimeoutBase into LLEventTimeout, and likewise merge LLEventThrottleBase into LLEventThrottle. The separation was for testability, but now that they're no longer based on LLTimer, it becomes harder to use dummy time for testing. Temporarily skip tests based on LLEventTimeoutBase and LLEventThrottleBase. Instead of listening for LLEventPump("mainloop") ticks and using LLTimer, LLEventTimeout now uses LLLater::doAfterInterval(). Instead of LLTimer and LLEventTimeout, LLEventThrottle likewise now uses LLLater::doAfterInterval(). Recast a couple local LLEventTimeout pre-lambda callable classes with lambdas. Dignify F64 with a new typedef LLDate::timestamp. LLDate heavily depends on that as its base time representation, but there are those who question use of floating-point for time. This is a step towards insulating us from any future change. --- indra/llcommon/lldate.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/llcommon/lldate.cpp') diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 2ddcf40895..6c23444820 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -41,9 +41,9 @@ #include "llstring.h" #include "llfasttimer.h" -static const F64 DATE_EPOCH = 0.0; +static const LLDate::timestamp DATE_EPOCH = 0.0; -static const F64 LL_APR_USEC_PER_SEC = 1000000.0; +static const LLDate::timestamp LL_APR_USEC_PER_SEC = 1000000.0; // should be APR_USEC_PER_SEC, but that relies on INT64_C which // isn't defined in glib under our build set up for some reason @@ -233,13 +233,13 @@ bool LLDate::fromStream(std::istream& s) return false; } - F64 seconds_since_epoch = time / LL_APR_USEC_PER_SEC; + timestamp seconds_since_epoch = time / LL_APR_USEC_PER_SEC; // check for fractional c = s.peek(); if(c == '.') { - F64 fractional = 0.0; + timestamp fractional = 0.0; s >> fractional; seconds_since_epoch += fractional; } @@ -299,12 +299,12 @@ bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec return true; } -F64 LLDate::secondsSinceEpoch() const +LLDate::timestamp LLDate::secondsSinceEpoch() const { return mSecondsSinceEpoch; } -void LLDate::secondsSinceEpoch(F64 seconds) +void LLDate::secondsSinceEpoch(timestamp seconds) { mSecondsSinceEpoch = seconds; } -- cgit v1.2.3 From 7137647e90d8c11197513f542f04fb39b483d663 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 15 May 2024 12:19:54 -0400 Subject: Manual whitespace cleanup (fix_whitespace.py). --- indra/llcommon/lldate.cpp | 394 +++++++++++++++++++++++----------------------- 1 file changed, 197 insertions(+), 197 deletions(-) (limited to 'indra/llcommon/lldate.cpp') diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index 6c23444820..592b7cff1b 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -1,4 +1,4 @@ -/** +/** * @file lldate.cpp * @author Phoenix * @date 2006-02-05 @@ -7,21 +7,21 @@ * $LicenseInfo:firstyear=2006&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, Linden Research, Inc. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License only. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -44,36 +44,36 @@ static const LLDate::timestamp DATE_EPOCH = 0.0; static const LLDate::timestamp LL_APR_USEC_PER_SEC = 1000000.0; - // should be APR_USEC_PER_SEC, but that relies on INT64_C which - // isn't defined in glib under our build set up for some reason + // should be APR_USEC_PER_SEC, but that relies on INT64_C which + // isn't defined in glib under our build set up for some reason LLDate::LLDate() : mSecondsSinceEpoch(DATE_EPOCH) {} LLDate::LLDate(const LLDate& date) : - mSecondsSinceEpoch(date.mSecondsSinceEpoch) + mSecondsSinceEpoch(date.mSecondsSinceEpoch) {} LLDate::LLDate(F64SecondsImplicit seconds_since_epoch) : - mSecondsSinceEpoch(seconds_since_epoch.value()) + mSecondsSinceEpoch(seconds_since_epoch.value()) {} LLDate::LLDate(const std::string& iso8601_date) { - if(!fromString(iso8601_date)) - { - LL_WARNS() << "date " << iso8601_date << " failed to parse; " - << "ZEROING IT OUT" << LL_ENDL; - mSecondsSinceEpoch = DATE_EPOCH; - } + if(!fromString(iso8601_date)) + { + LL_WARNS() << "date " << iso8601_date << " failed to parse; " + << "ZEROING IT OUT" << LL_ENDL; + mSecondsSinceEpoch = DATE_EPOCH; + } } std::string LLDate::asString() const { - std::ostringstream stream; - toStream(stream); - return stream.str(); + std::ostringstream stream; + toStream(stream); + return stream.str(); } //@ brief Converts time in seconds since EPOCH @@ -83,236 +83,236 @@ std::string LLDate::asString() const // is one of the standards used and the prefered format std::string LLDate::asRFC1123() const { - return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); + return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT")); } std::string LLDate::toHTTPDateString (std::string fmt) const { LL_PROFILE_ZONE_SCOPED; - - time_t locSeconds = (time_t) mSecondsSinceEpoch; - struct tm * gmt = gmtime (&locSeconds); - return toHTTPDateString(gmt, fmt); + + time_t locSeconds = (time_t) mSecondsSinceEpoch; + struct tm * gmt = gmtime (&locSeconds); + return toHTTPDateString(gmt, fmt); } std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt) { LL_PROFILE_ZONE_SCOPED; - // avoid calling setlocale() unnecessarily - it's expensive. - static std::string prev_locale = ""; - std::string this_locale = LLStringUtil::getLocale(); - if (this_locale != prev_locale) - { - setlocale(LC_TIME, this_locale.c_str()); - prev_locale = this_locale; - } - - // use strftime() as it appears to be faster than std::time_put - char buffer[128]; - strftime(buffer, 128, fmt.c_str(), gmt); - std::string res(buffer); + // avoid calling setlocale() unnecessarily - it's expensive. + static std::string prev_locale = ""; + std::string this_locale = LLStringUtil::getLocale(); + if (this_locale != prev_locale) + { + setlocale(LC_TIME, this_locale.c_str()); + prev_locale = this_locale; + } + + // use strftime() as it appears to be faster than std::time_put + char buffer[128]; + strftime(buffer, 128, fmt.c_str(), gmt); + std::string res(buffer); #if LL_WINDOWS - // Convert from locale-dependant charset to UTF-8 (EXT-8524). - res = ll_convert_string_to_utf8_string(res); + // Convert from locale-dependant charset to UTF-8 (EXT-8524). + res = ll_convert_string_to_utf8_string(res); #endif - return res; + return res; } void LLDate::toStream(std::ostream& s) const { - apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); - - apr_time_exp_t exp_time; - if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) - { - s << "1970-01-01T00:00:00Z"; - return; - } - - s << std::dec << std::setfill('0'); + apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); + + apr_time_exp_t exp_time; + if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) + { + s << "1970-01-01T00:00:00Z"; + return; + } + + s << std::dec << std::setfill('0'); #if( LL_WINDOWS || __GNUC__ > 2) - s << std::right; + s << std::right; #else - s.setf(ios::right); + s.setf(ios::right); #endif - s << std::setw(4) << (exp_time.tm_year + 1900) - << '-' << std::setw(2) << (exp_time.tm_mon + 1) - << '-' << std::setw(2) << (exp_time.tm_mday) - << 'T' << std::setw(2) << (exp_time.tm_hour) - << ':' << std::setw(2) << (exp_time.tm_min) - << ':' << std::setw(2) << (exp_time.tm_sec); - if (exp_time.tm_usec > 0) - { - s << '.' << std::setw(2) - << (int)(exp_time.tm_usec / (LL_APR_USEC_PER_SEC / 100)); - } - s << 'Z' - << std::setfill(' '); + s << std::setw(4) << (exp_time.tm_year + 1900) + << '-' << std::setw(2) << (exp_time.tm_mon + 1) + << '-' << std::setw(2) << (exp_time.tm_mday) + << 'T' << std::setw(2) << (exp_time.tm_hour) + << ':' << std::setw(2) << (exp_time.tm_min) + << ':' << std::setw(2) << (exp_time.tm_sec); + if (exp_time.tm_usec > 0) + { + s << '.' << std::setw(2) + << (int)(exp_time.tm_usec / (LL_APR_USEC_PER_SEC / 100)); + } + s << 'Z' + << std::setfill(' '); } bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *sec) const { - apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); - - apr_time_exp_t exp_time; - if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) - { - return false; - } + apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC); + + apr_time_exp_t exp_time; + if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS) + { + return false; + } - if (year) - *year = exp_time.tm_year + 1900; + if (year) + *year = exp_time.tm_year + 1900; - if (month) - *month = exp_time.tm_mon + 1; + if (month) + *month = exp_time.tm_mon + 1; - if (day) - *day = exp_time.tm_mday; + if (day) + *day = exp_time.tm_mday; - if (hour) - *hour = exp_time.tm_hour; + if (hour) + *hour = exp_time.tm_hour; - if (min) - *min = exp_time.tm_min; + if (min) + *min = exp_time.tm_min; - if (sec) - *sec = exp_time.tm_sec; + if (sec) + *sec = exp_time.tm_sec; - return true; + return true; } bool LLDate::fromString(const std::string& iso8601_date) { - std::istringstream stream(iso8601_date); - return fromStream(stream); + std::istringstream stream(iso8601_date); + return fromStream(stream); } bool LLDate::fromStream(std::istream& s) { - struct apr_time_exp_t exp_time; - apr_int32_t tm_part; - int c; - - s >> tm_part; - exp_time.tm_year = tm_part - 1900; - c = s.get(); // skip the hypen - if (c != '-') { return false; } - s >> tm_part; - exp_time.tm_mon = tm_part - 1; - c = s.get(); // skip the hypen - if (c != '-') { return false; } - s >> tm_part; - exp_time.tm_mday = tm_part; - - c = s.get(); // skip the T - if (c != 'T') { return false; } - - s >> tm_part; - exp_time.tm_hour = tm_part; - c = s.get(); // skip the : - if (c != ':') { return false; } - s >> tm_part; - exp_time.tm_min = tm_part; - c = s.get(); // skip the : - if (c != ':') { return false; } - s >> tm_part; - exp_time.tm_sec = tm_part; - - // zero out the unused fields - exp_time.tm_usec = 0; - exp_time.tm_wday = 0; - exp_time.tm_yday = 0; - exp_time.tm_isdst = 0; - exp_time.tm_gmtoff = 0; - - // generate a time_t from that - apr_time_t time; - if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS) - { - return false; - } - - timestamp seconds_since_epoch = time / LL_APR_USEC_PER_SEC; - - // check for fractional - c = s.peek(); - if(c == '.') - { - timestamp fractional = 0.0; - s >> fractional; - seconds_since_epoch += fractional; - } - - c = s.peek(); // check for offset - if (c == '+' || c == '-') - { - S32 offset_sign = (c == '+') ? 1 : -1; - S32 offset_hours = 0; - S32 offset_minutes = 0; - S32 offset_in_seconds = 0; - - s >> offset_hours; - - c = s.get(); // skip the colon a get the minutes if there are any - if (c == ':') - { - s >> offset_minutes; - } - - offset_in_seconds = (offset_hours * 60 + offset_sign * offset_minutes) * 60; - seconds_since_epoch -= offset_in_seconds; - } - else if (c != 'Z') { return false; } // skip the Z - - mSecondsSinceEpoch = seconds_since_epoch; - return true; + struct apr_time_exp_t exp_time; + apr_int32_t tm_part; + int c; + + s >> tm_part; + exp_time.tm_year = tm_part - 1900; + c = s.get(); // skip the hypen + if (c != '-') { return false; } + s >> tm_part; + exp_time.tm_mon = tm_part - 1; + c = s.get(); // skip the hypen + if (c != '-') { return false; } + s >> tm_part; + exp_time.tm_mday = tm_part; + + c = s.get(); // skip the T + if (c != 'T') { return false; } + + s >> tm_part; + exp_time.tm_hour = tm_part; + c = s.get(); // skip the : + if (c != ':') { return false; } + s >> tm_part; + exp_time.tm_min = tm_part; + c = s.get(); // skip the : + if (c != ':') { return false; } + s >> tm_part; + exp_time.tm_sec = tm_part; + + // zero out the unused fields + exp_time.tm_usec = 0; + exp_time.tm_wday = 0; + exp_time.tm_yday = 0; + exp_time.tm_isdst = 0; + exp_time.tm_gmtoff = 0; + + // generate a time_t from that + apr_time_t time; + if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS) + { + return false; + } + + timestamp seconds_since_epoch = time / LL_APR_USEC_PER_SEC; + + // check for fractional + c = s.peek(); + if(c == '.') + { + timestamp fractional = 0.0; + s >> fractional; + seconds_since_epoch += fractional; + } + + c = s.peek(); // check for offset + if (c == '+' || c == '-') + { + S32 offset_sign = (c == '+') ? 1 : -1; + S32 offset_hours = 0; + S32 offset_minutes = 0; + S32 offset_in_seconds = 0; + + s >> offset_hours; + + c = s.get(); // skip the colon a get the minutes if there are any + if (c == ':') + { + s >> offset_minutes; + } + + offset_in_seconds = (offset_hours * 60 + offset_sign * offset_minutes) * 60; + seconds_since_epoch -= offset_in_seconds; + } + else if (c != 'Z') { return false; } // skip the Z + + mSecondsSinceEpoch = seconds_since_epoch; + return true; } bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec) { - struct apr_time_exp_t exp_time; - - exp_time.tm_year = year - 1900; - exp_time.tm_mon = month - 1; - exp_time.tm_mday = day; - exp_time.tm_hour = hour; - exp_time.tm_min = min; - exp_time.tm_sec = sec; - - // zero out the unused fields - exp_time.tm_usec = 0; - exp_time.tm_wday = 0; - exp_time.tm_yday = 0; - exp_time.tm_isdst = 0; - exp_time.tm_gmtoff = 0; - - // generate a time_t from that - apr_time_t time; - if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS) - { - return false; - } - - mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC; - - return true; + struct apr_time_exp_t exp_time; + + exp_time.tm_year = year - 1900; + exp_time.tm_mon = month - 1; + exp_time.tm_mday = day; + exp_time.tm_hour = hour; + exp_time.tm_min = min; + exp_time.tm_sec = sec; + + // zero out the unused fields + exp_time.tm_usec = 0; + exp_time.tm_wday = 0; + exp_time.tm_yday = 0; + exp_time.tm_isdst = 0; + exp_time.tm_gmtoff = 0; + + // generate a time_t from that + apr_time_t time; + if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS) + { + return false; + } + + mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC; + + return true; } LLDate::timestamp LLDate::secondsSinceEpoch() const { - return mSecondsSinceEpoch; + return mSecondsSinceEpoch; } void LLDate::secondsSinceEpoch(timestamp seconds) { - mSecondsSinceEpoch = seconds; + mSecondsSinceEpoch = seconds; } /* static */ LLDate LLDate::now() { - // time() returns seconds, we want fractions of a second, which LLTimer provides --RN - return LLDate(LLTimer::getTotalSeconds()); + // time() returns seconds, we want fractions of a second, which LLTimer provides --RN + return LLDate(LLTimer::getTotalSeconds()); } bool LLDate::operator<(const LLDate& rhs) const @@ -322,13 +322,13 @@ bool LLDate::operator<(const LLDate& rhs) const std::ostream& operator<<(std::ostream& s, const LLDate& date) { - date.toStream(s); - return s; + date.toStream(s); + return s; } std::istream& operator>>(std::istream& s, LLDate& date) { - date.fromStream(s); - return s; + date.fromStream(s); + return s; } -- cgit v1.2.3