Skip to content

Commit 012f742

Browse files
committed
viewer#2884 Convert webrtc and experience coroutines into idle callbacks
1 parent d33047b commit 012f742

File tree

5 files changed

+136
-129
lines changed

5 files changed

+136
-129
lines changed

indra/llmessage/llexperiencecache.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,8 @@ void LLExperienceCache::initSingleton()
110110

111111
LLCoprocedureManager::instance().initializePool("ExpCache");
112112

113-
LLCoros::instance().launch("LLExperienceCache::idleCoro",
114-
boost::bind(&LLExperienceCache::idleCoro, this));
115-
113+
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
114+
mExpirationTimerHandle = LL::Timers::instance().scheduleEvery([this]() { expirationTimer(); return false; }, SECS_BETWEEN_REQUESTS);
116115
}
117116

118117
void LLExperienceCache::cleanup()
@@ -125,6 +124,8 @@ void LLExperienceCache::cleanup()
125124
cache_stream << (*this);
126125
}
127126
sShutdown = true;
127+
128+
LL::Timers::instance().cancel(mExpirationTimerHandle);
128129
}
129130

130131
//-------------------------------------------------------------------------
@@ -392,30 +393,20 @@ void LLExperienceCache::setCapabilityQuery(LLExperienceCache::CapabilityQuery_t
392393
}
393394

394395

395-
void LLExperienceCache::idleCoro()
396+
void LLExperienceCache::expirationTimer()
396397
{
397-
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
398+
LL_PROFILE_ZONE_SCOPED;
398399
const F32 ERASE_EXPIRED_TIMEOUT = 60.f; // seconds
399400

400-
LL_INFOS("ExperienceCache") << "Launching Experience cache idle coro." << LL_ENDL;
401-
do
401+
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
402402
{
403-
if (mEraseExpiredTimer.checkExpirationAndReset(ERASE_EXPIRED_TIMEOUT))
404-
{
405-
eraseExpired();
406-
}
407-
408-
if (!mRequestQueue.empty())
409-
{
410-
requestExperiences();
411-
}
412-
413-
llcoro::suspendUntilTimeout(SECS_BETWEEN_REQUESTS);
414-
415-
} while (!sShutdown);
403+
eraseExpired();
404+
}
416405

417-
// The coroutine system will likely be shut down by the time we get to this point
418-
// (or at least no further cycling will occur on it since the user has decided to quit.)
406+
if (!mRequestQueue.empty())
407+
{
408+
requestExperiences();
409+
}
419410
}
420411

421412
void LLExperienceCache::erase(const LLUUID& key)

indra/llmessage/llexperiencecache.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030
#define LL_LLEXPERIENCECACHE_H
3131

3232
#include "linden_common.h"
33-
#include "llsingleton.h"
33+
34+
#include "llcallbacklist.h" // LL::Timers::handle_t
35+
#include "llcorehttputil.h"
3436
#include "llframetimer.h"
37+
#include "llsingleton.h"
3538
#include "llsd.h"
36-
#include "llcorehttputil.h"
39+
3740
#include <boost/signals2.hpp>
3841
#include <boost/function.hpp>
3942

@@ -144,7 +147,9 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
144147
std::string mCacheFileName;
145148
static bool sShutdown; // control for coroutines, they exist out of LLExperienceCache's scope, so they need a static control
146149

147-
void idleCoro();
150+
LL::Timers::handle_t mExpirationTimerHandle;
151+
void expirationTimer();
152+
148153
void eraseExpired();
149154
void requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, RequestQueue_t);
150155
void requestExperiences();

indra/newview/llvoicevivox.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6637,13 +6637,13 @@ void LLVivoxVoiceClient::expireVoiceFonts()
66376637
}
66386638
}
66396639

6640-
LLSD args;
6641-
args["URL"] = LLTrans::getString("voice_morphing_url");
6642-
args["PREMIUM_URL"] = LLTrans::getString("premium_voice_morphing_url");
6643-
66446640
// Give a notification if any voice fonts have expired.
66456641
if (have_expired)
66466642
{
6643+
LLSD args;
6644+
args["URL"] = LLTrans::getString("voice_morphing_url");
6645+
args["PREMIUM_URL"] = LLTrans::getString("premium_voice_morphing_url");
6646+
66476647
if (expired_in_use)
66486648
{
66496649
LLNotificationsUtil::add("VoiceEffectsExpiredInUse", args);

indra/newview/llvoicewebrtc.cpp

Lines changed: 104 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ LLWebRTCVoiceClient::LLWebRTCVoiceClient() :
218218
mAvatarNameCacheConnection(),
219219
mIsInTuningMode(false),
220220
mIsProcessingChannels(false),
221-
mIsCoroutineActive(false),
221+
mIsTimerActive(false),
222222
mWebRTCPump("WebRTCClientPump"),
223223
mWebRTCDeviceInterface(nullptr)
224224
{
@@ -295,6 +295,16 @@ void LLWebRTCVoiceClient::cleanUp()
295295
mNeighboringRegions.clear();
296296
sessionState::for_each(boost::bind(predShutdownSession, _1));
297297
LL_DEBUGS("Voice") << "Exiting" << LL_ENDL;
298+
stopTimer();
299+
}
300+
301+
void LLWebRTCVoiceClient::stopTimer()
302+
{
303+
if (mIsTimerActive)
304+
{
305+
mIsTimerActive = false;
306+
LL::Timers::instance().cancel(mVoiceTimerHandle);
307+
}
298308
}
299309

300310
void LLWebRTCVoiceClient::LogMessage(llwebrtc::LLWebRTCLogCallback::LogLevel level, const std::string& message)
@@ -443,8 +453,7 @@ void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer)
443453

444454
//---------------------------------------------------
445455
// Primary voice loop.
446-
// This voice loop is called every 100ms plus the time it
447-
// takes to process the various functions called in the loop
456+
// This voice loop is called every 100ms
448457
// The loop does the following:
449458
// * gates whether we do channel processing depending on
450459
// whether we're running a WebRTC voice channel or
@@ -456,118 +465,109 @@ void LLWebRTCVoiceClient::removeObserver(LLFriendObserver *observer)
456465
// connection to various voice channels.
457466
// * Sends updates to the voice server when this agent's
458467
// voice levels, or positions have changed.
459-
void LLWebRTCVoiceClient::voiceConnectionCoro()
468+
void LLWebRTCVoiceClient::connectionTimer()
460469
{
461-
LL_DEBUGS("Voice") << "starting" << LL_ENDL;
462-
mIsCoroutineActive = true;
463-
LLCoros::set_consuming(true);
470+
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOICE;
464471
try
465472
{
466-
LLMuteList::getInstance()->addObserver(this);
467-
while (!sShuttingDown)
468-
{
469-
LL_PROFILE_ZONE_NAMED_CATEGORY_VOICE("voiceConnectionCoroLoop")
470-
// TODO: Doing some measurement and calculation here,
471-
// we could reduce the timeout to take into account the
472-
// time spent on the previous loop to have the loop
473-
// cycle at exactly 100ms, instead of 100ms + loop
474-
// execution time.
475-
// Could help with voice updates making for smoother
476-
// voice when we're busy.
477-
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
478-
if (sShuttingDown) return; // 'this' migh already be invalid
479-
bool voiceEnabled = mVoiceEnabled;
480-
481-
if (!isAgentAvatarValid())
473+
// TODO: Doing some measurement and calculation here,
474+
// we could reduce the timeout to take into account the
475+
// time spent on the previous loop to have the loop
476+
// cycle at exactly 100ms, instead of 100ms + loop
477+
// execution time.
478+
// Could help with voice updates making for smoother
479+
// voice when we're busy.
480+
bool voiceEnabled = mVoiceEnabled;
481+
482+
if (!isAgentAvatarValid())
483+
{
484+
if (sShuttingDown)
482485
{
483-
continue;
486+
cleanUp();
484487
}
488+
return;
489+
}
485490

486-
LLViewerRegion *regionp = gAgent.getRegion();
487-
if (!regionp)
491+
LLViewerRegion* regionp = gAgent.getRegion();
492+
if (!regionp)
493+
{
494+
if (sShuttingDown)
488495
{
489-
continue;
496+
cleanUp();
490497
}
498+
return;
499+
}
491500

492-
if (!mProcessChannels)
501+
if (!mProcessChannels)
502+
{
503+
// we've switched away from webrtc voice, so shut all channels down.
504+
// leave channel can be called again and again without adverse effects.
505+
// it merely tells channels to shut down if they're not already doing so.
506+
leaveChannel(false);
507+
}
508+
else if (inSpatialChannel())
509+
{
510+
bool useEstateVoice = true;
511+
// add session for region or parcel voice.
512+
if (!regionp || regionp->getRegionID().isNull())
493513
{
494-
// we've switched away from webrtc voice, so shut all channels down.
495-
// leave channel can be called again and again without adverse effects.
496-
// it merely tells channels to shut down if they're not already doing so.
497-
leaveChannel(false);
514+
// no region, no voice.
515+
return;
498516
}
499-
else if (inSpatialChannel())
500-
{
501-
bool useEstateVoice = true;
502-
// add session for region or parcel voice.
503-
if (!regionp || regionp->getRegionID().isNull())
504-
{
505-
// no region, no voice.
506-
continue;
507-
}
508517

509-
voiceEnabled = voiceEnabled && regionp->isVoiceEnabled();
518+
voiceEnabled = voiceEnabled && regionp->isVoiceEnabled();
510519

511-
if (voiceEnabled)
520+
if (voiceEnabled)
521+
{
522+
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
523+
// check to see if parcel changed.
524+
if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
512525
{
513-
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
514-
// check to see if parcel changed.
515-
if (parcel && parcel->getLocalID() != INVALID_PARCEL_ID)
526+
// parcel voice
527+
if (!parcel->getParcelFlagAllowVoice())
516528
{
517-
// parcel voice
518-
if (!parcel->getParcelFlagAllowVoice())
519-
{
520-
voiceEnabled = false;
521-
}
522-
else if (!parcel->getParcelFlagUseEstateVoiceChannel())
523-
{
524-
// use the parcel-specific voice channel.
525-
S32 parcel_local_id = parcel->getLocalID();
526-
std::string channelID = regionp->getRegionID().asString() + "-" + std::to_string(parcel->getLocalID());
527-
528-
useEstateVoice = false;
529-
if (!inOrJoiningChannel(channelID))
530-
{
531-
startParcelSession(channelID, parcel_local_id);
532-
}
533-
}
529+
voiceEnabled = false;
534530
}
535-
if (voiceEnabled && useEstateVoice && !inEstateChannel())
531+
else if (!parcel->getParcelFlagUseEstateVoiceChannel())
536532
{
537-
// estate voice
538-
startEstateSession();
533+
// use the parcel-specific voice channel.
534+
S32 parcel_local_id = parcel->getLocalID();
535+
std::string channelID = regionp->getRegionID().asString() + "-" + std::to_string(parcel->getLocalID());
536+
537+
useEstateVoice = false;
538+
if (!inOrJoiningChannel(channelID))
539+
{
540+
startParcelSession(channelID, parcel_local_id);
541+
}
539542
}
540543
}
541-
if (!voiceEnabled)
542-
{
543-
// voice is disabled, so leave and disable PTT
544-
leaveChannel(true);
545-
}
546-
else
544+
if (voiceEnabled && useEstateVoice && !inEstateChannel())
547545
{
548-
// we're in spatial voice, and voice is enabled, so determine positions in order
549-
// to send position updates.
550-
updatePosition();
546+
// estate voice
547+
startEstateSession();
551548
}
552549
}
553-
LL::WorkQueue::postMaybe(mMainQueue,
554-
[=] {
555-
if (sShuttingDown)
556-
{
557-
return;
558-
}
559-
sessionState::processSessionStates();
560-
if (mProcessChannels && voiceEnabled && !mHidden)
561-
{
562-
sendPositionUpdate(false);
563-
updateOwnVolume();
564-
}
565-
});
550+
if (!voiceEnabled)
551+
{
552+
// voice is disabled, so leave and disable PTT
553+
leaveChannel(true);
554+
}
555+
else
556+
{
557+
// we're in spatial voice, and voice is enabled, so determine positions in order
558+
// to send position updates.
559+
updatePosition();
560+
}
561+
}
562+
if (!sShuttingDown)
563+
{
564+
sessionState::processSessionStates();
565+
if (mProcessChannels && voiceEnabled && !mHidden)
566+
{
567+
sendPositionUpdate(false);
568+
updateOwnVolume();
569+
}
566570
}
567-
}
568-
catch (const LLCoros::Stop&)
569-
{
570-
LL_DEBUGS("LLWebRTCVoiceClient") << "Received a shutdown exception" << LL_ENDL;
571571
}
572572
catch (const LLContinueError&)
573573
{
@@ -582,7 +582,10 @@ void LLWebRTCVoiceClient::voiceConnectionCoro()
582582
throw;
583583
}
584584

585-
cleanUp();
585+
if (sShuttingDown)
586+
{
587+
cleanUp();
588+
}
586589
}
587590

588591
// For spatial, determine which neighboring regions to connect to
@@ -1340,7 +1343,7 @@ bool LLWebRTCVoiceClient::isVoiceWorking() const
13401343
// webrtc is working if the coroutine is active in the case of
13411344
// webrtc. WebRTC doesn't need to connect to a secondary process
13421345
// or a login server to become active.
1343-
return mIsCoroutineActive;
1346+
return mIsTimerActive;
13441347
}
13451348

13461349
// Returns true if calling back the session URI after the session has closed is possible.
@@ -1552,7 +1555,7 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
15521555
LL_DEBUGS("Voice")
15531556
<< "( " << (enabled ? "enabled" : "disabled") << " )"
15541557
<< " was "<< (mVoiceEnabled ? "enabled" : "disabled")
1555-
<< " coro "<< (mIsCoroutineActive ? "active" : "inactive")
1558+
<< " coro "<< (mIsTimerActive ? "active" : "inactive")
15561559
<< LL_ENDL;
15571560

15581561
if (enabled != mVoiceEnabled)
@@ -1569,10 +1572,13 @@ void LLWebRTCVoiceClient::setVoiceEnabled(bool enabled)
15691572
status = LLVoiceClientStatusObserver::STATUS_VOICE_ENABLED;
15701573
mSpatialCoordsDirty = true;
15711574
updatePosition();
1572-
if (!mIsCoroutineActive)
1575+
if (!mIsTimerActive)
15731576
{
1574-
LLCoros::instance().launch("LLWebRTCVoiceClient::voiceConnectionCoro",
1575-
boost::bind(&LLWebRTCVoiceClient::voiceConnectionCoro, LLWebRTCVoiceClient::getInstance()));
1577+
LL_DEBUGS("Voice") << "Starting" << LL_ENDL;
1578+
mIsTimerActive = true;
1579+
LLMuteList::getInstance()->addObserver(this);
1580+
const F32 SECS_BETWEEN_REQUESTS = 0.5f;
1581+
mVoiceTimerHandle = LL::Timers::instance().scheduleEvery([this]() { connectionTimer(); return false; }, UPDATE_THROTTLE_SECONDS);
15761582
}
15771583
else
15781584
{

0 commit comments

Comments
 (0)