Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion indra/alscript/masters/almasterwatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "almasterwatch.h"

#include "almainloop.h"
#include "alserialworker.h"
#include "alwatchedfile.h"
#include "llsingleton.h"
Expand Down Expand Up @@ -74,7 +75,7 @@ namespace
ALMasterWatch::look_t ALMasterWatch::offThread()
{
return [](std::vector<std::string> paths, stamped_t found) {
const LL::WorkQueue::ptr_t main_loop = LL::WorkQueue::getInstance("mainloop");
const LL::WorkQueue::ptr_t main_loop = ALMainLoop::queue();
if (!main_loop)
{
// No main loop to hand them back to -- a test -- so looked at
Expand Down
2 changes: 2 additions & 0 deletions indra/llcommon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ target_sources(
llcommon
PRIVATE
alfilewrite.cpp
almainloop.cpp
alserialworker.cpp
alparamtype.cpp
alrecoverystore.cpp
Expand Down Expand Up @@ -122,6 +123,7 @@ target_sources(
FILES
alfilewrite.h
allinebreaks.h
almainloop.h
alserialworker.h
alparamtype.h
alrandmap.h
Expand Down
57 changes: 57 additions & 0 deletions indra/llcommon/almainloop.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @file almainloop.cpp
* @brief The queue the main loop services, and a test's say over it.
*
* $LicenseInfo:firstyear=2026&license=viewerlgpl$
* Alchemy Viewer Source Code
* Copyright (C) 2026, Rye <rye@alchemyviewer.org>
*
* 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
* $/LicenseInfo$
*/

#include "linden_common.h"

#include "almainloop.h"

#include <atomic>

namespace
{
// Read from the threads that ask whether to hand back, so a choice made
// on the main thread is seen whole.
std::atomic<const ALMainLoop::Choice*> sChoice{ nullptr };
}

LL::WorkQueue::ptr_t ALMainLoop::queue()
{
if (const Choice* choice = sChoice.load(std::memory_order_acquire))
{
return choice->mChosen;
}
return LL::WorkQueue::getInstance("mainloop");
}

ALMainLoop::Choice::Choice(LL::WorkQueue* chosen)
: mChosen(chosen ? LL::WorkQueue::getInstance(chosen->getKey()) : nullptr)
, mOuter(sChoice.load(std::memory_order_relaxed))
{
sChoice.store(this, std::memory_order_release);
}

ALMainLoop::Choice::~Choice()
{
sChoice.store(mOuter, std::memory_order_release);
}
58 changes: 58 additions & 0 deletions indra/llcommon/almainloop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* @file almainloop.h
* @brief The queue the main loop services, and a test's say over it.
*
* $LicenseInfo:firstyear=2026&license=viewerlgpl$
* Alchemy Viewer Source Code
* Copyright (C) 2026, Rye <rye@alchemyviewer.org>
*
* 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
* $/LicenseInfo$
*/

#pragma once

#include "workqueue.h"

// The queue the viewer's main loop services: what work done on another
// thread hands its result back through. Code that works off the main
// thread asks here rather than for the queue by its name, so that a test
// can say which way that code goes.
namespace ALMainLoop
{
// The main loop's queue, or null where nothing services one -- a test
// that has not chosen one -- and the work is done in place instead.
LL_COMMON_API LL::WorkQueue::ptr_t queue();

// While one lives, queue() answers the queue it was given, or null for
// none, whatever queue of the main loop's name there is. Without it a
// queue one test made would choose the way for every test after it in
// the process. The newest living one wins. Main thread only.
class LL_COMMON_API Choice
{
public:
explicit Choice(LL::WorkQueue* chosen);
~Choice();

Choice(const Choice&) = delete;
Choice& operator=(const Choice&) = delete;

private:
friend LL::WorkQueue::ptr_t queue();

LL::WorkQueue::ptr_t mChosen;
const Choice* mOuter;
};
}
3 changes: 2 additions & 1 deletion indra/llcommon/alwatchedfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

#include "alwatchedfile.h"

#include "almainloop.h"
#include "alserialworker.h"
#include "fsyspath.h"
#include "llerror.h"
Expand Down Expand Up @@ -188,7 +189,7 @@ class ALWatchedFile::Watcher : public std::enable_shared_from_this<Watcher>
{
return;
}
const LL::WorkQueue::ptr_t main = LL::WorkQueue::getInstance("mainloop");
const LL::WorkQueue::ptr_t main = ALMainLoop::queue();
if (!mWorker)
{
mWorker = std::make_unique<ALSerialWorker>("WatchedFiles");
Expand Down
Loading
Loading