From 98dfba0d2f24aeb92e023df9d48b23fef8253024 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Thu, 14 May 2020 14:51:52 -0400
Subject: [PATCH] DRTVWR-476: Wrap boost::fibers::mutex et al. with LLCoros
 aliases.

Specifically:

LLCoros::Mutex means boost::fibers::mutex
LLCoros::LockType means std::unique_lock<boost::fibers::mutex>
LLCoros::ConditionVariable means boost::fibers::condition_variable
LLCoros::cv_status means boost::fibers::cv_status

So as not to drag in all of boost::fibers::mutex.hpp or condition_variable.hpp
for each consumer of llcoros.h, instead #define LLCOROS_MUTEX_HEADER and
LLCOROS_CONDVAR_HEADER. Those who need them can #include the relevant macro.

Update llcond.h and llthreadsafequeue.h accordingly.
---
 indra/llcommon/llcond.h            | 27 ++++++++++++++-------------
 indra/llcommon/llcoros.h           | 19 +++++++++++++++++++
 indra/llcommon/llthreadsafequeue.h | 11 ++++++-----
 3 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/indra/llcommon/llcond.h b/indra/llcommon/llcond.h
index b4289528dee..e31b67d8937 100644
--- a/indra/llcommon/llcond.h
+++ b/indra/llcommon/llcond.h
@@ -15,8 +15,9 @@
 #define LL_LLCOND_H
 
 #include "llunits.h"
-#include <boost/fiber/condition_variable.hpp>
-#include <mutex>
+#include "llcoros.h"
+#include LLCOROS_MUTEX_HEADER
+#include "mutex.h"
 #include <chrono>
 
 /**
@@ -32,7 +33,7 @@
  * For a scalar DATA type, consider LLScalarCond instead. For specifically
  * bool, consider LLBoolCond.
  *
- * Use of boost::fibers::condition_variable makes LLCond work between
+ * Use of LLCoros::ConditionVariable makes LLCond work between
  * coroutines as well as between threads.
  */
 template <typename DATA>
@@ -45,13 +46,13 @@ class LLCond
     // This is the DATA controlled by the condition_variable.
     value_type mData;
     // condition_variable must be used in conjunction with a mutex. Use
-    // boost::fibers::mutex instead of std::mutex because the latter blocks
+    // LLCoros::Mutex instead of std::mutex because the latter blocks
     // the entire calling thread, whereas the former blocks only the current
-    // coroutine within the calling thread. Yet boost::fiber::mutex is safe to
+    // coroutine within the calling thread. Yet LLCoros::Mutex is safe to
     // use across threads as well: it subsumes std::mutex functionality.
-    boost::fibers::mutex mMutex;
-    // Use boost::fibers::condition_variable for the same reason.
-    boost::fibers::condition_variable mCond;
+    LLCoros::Mutex mMutex;
+    // Use LLCoros::ConditionVariable for the same reason.
+    LLCoros::ConditionVariable mCond;
 
 public:
     /// LLCond can be explicitly initialized with a specific value for mData if
@@ -82,7 +83,7 @@ class LLCond
     void update_one(MODIFY modify)
     {
         { // scope of lock can/should end before notify_one()
-            std::unique_lock<boost::fibers::mutex> lk(mMutex);
+            LLCoros::LockType lk(mMutex);
             modify(mData);
         }
         mCond.notify_one();
@@ -101,7 +102,7 @@ class LLCond
     void update_all(MODIFY modify)
     {
         { // scope of lock can/should end before notify_all()
-            std::unique_lock<boost::fibers::mutex> lk(mMutex);
+            LLCoros::LockType lk(mMutex);
             modify(mData);
         }
         mCond.notify_all();
@@ -117,7 +118,7 @@ class LLCond
     template <typename Pred>
     void wait(Pred pred)
     {
-        std::unique_lock<boost::fibers::mutex> lk(mMutex);
+        LLCoros::LockType lk(mMutex);
         // We must iterate explicitly since the predicate accepted by
         // condition_variable::wait() requires a different signature:
         // condition_variable::wait() calls its predicate with no arguments.
@@ -204,14 +205,14 @@ class LLCond
     template <typename Clock, typename Duration, typename Pred>
     bool wait_until(const std::chrono::time_point<Clock, Duration>& timeout_time, Pred pred)
     {
-        std::unique_lock<boost::fibers::mutex> lk(mMutex);
+        LLCoros::LockType lk(mMutex);
         // We advise the caller to pass a predicate accepting (const DATA&).
         // But what if they instead pass a predicate accepting non-const
         // (DATA&)? Such a predicate could modify mData, which would be Bad.
         // Forbid that.
         while (! pred(const_cast<const value_type&>(mData)))
         {
-            if (boost::fibers::cv_status::timeout == mCond.wait_until(lk, timeout_time))
+            if (LLCoros::cv_status::timeout == mCond.wait_until(lk, timeout_time))
             {
                 // It's possible that wait_until() timed out AND the predicate
                 // became true more or less simultaneously. Even though
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 95859198d44..d49a6e939c0 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -33,11 +33,24 @@
 #include <boost/fiber/fss.hpp>
 #include <boost/fiber/future/promise.hpp>
 #include <boost/fiber/future/future.hpp>
+#include "mutex.h"
 #include "llsingleton.h"
 #include "llinstancetracker.h"
 #include <boost/function.hpp>
 #include <string>
 
+// e.g. #include LLCOROS_MUTEX_HEADER
+#define LLCOROS_MUTEX_HEADER   <boost/fiber/mutex.hpp>
+#define LLCOROS_CONDVAR_HEADER <boost/fiber/condition_variable.hpp>
+
+namespace boost {
+    namespace fibers {
+        class mutex;
+        enum class cv_status;
+        class condition_variable;
+    }
+}
+
 /**
  * Registry of named Boost.Coroutine instances
  *
@@ -260,6 +273,12 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     template <typename T>
     static Future<T> getFuture(Promise<T>& promise) { return promise.get_future(); }
 
+    // use mutex, lock, condition_variable suitable for coroutines
+    using Mutex = boost::fibers::mutex;
+    using LockType = std::unique_lock<Mutex>;
+    using cv_status = boost::fibers::cv_status;
+    using ConditionVariable = boost::fibers::condition_variable;
+
     /// for data local to each running coroutine
     template <typename T>
     using local_ptr = boost::fibers::fiber_specific_ptr<T>;
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
index bac536f7ee3..8f5e0f3bf3a 100644
--- a/indra/llcommon/llthreadsafequeue.h
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -31,7 +31,8 @@
 #include <deque>
 #include <string>
 #include "mutex.h"
-#include <boost/fiber/condition_variable.hpp>
+#include "llcoros.h"
+#include LLCOROS_CONDVAR_HEADER
 
 //
 // A general queue exception.
@@ -119,10 +120,10 @@ class LLThreadSafeQueue
 	U32 mCapacity;
 	bool mClosed;
 
-	boost::fibers::mutex mLock;
-	typedef std::unique_lock<decltype(mLock)> lock_t;
-	boost::fibers::condition_variable mCapacityCond;
-	boost::fibers::condition_variable mEmptyCond;
+	LLCoros::Mutex mLock;
+	typedef LLCoros::LockType lock_t;
+	LLCoros::ConditionVariable mCapacityCond;
+	LLCoros::ConditionVariable mEmptyCond;
 };
 
 // LLThreadSafeQueue
-- 
GitLab