@@ -60,7 +60,7 @@ exchange(T& obj, U&& new_value)
6060
6161#if defined(HAVE_PTHREAD_RWLOCK)
6262
63- // / A shared mutex type implemented using pthread_rwlock_t.
63+ // / A shared mutex type implemented using ` pthread_rwlock_t` .
6464class shared_mutex_pthread {
6565#if defined(PTHREAD_RWLOCK_INITIALIZER)
6666 pthread_rwlock_t _M_rwlock = PTHREAD_RWLOCK_INITIALIZER;
@@ -141,7 +141,7 @@ class shared_mutex_pthread {
141141 bool try_lock_shared () {
142142 int __ret = pthread_rwlock_tryrdlock (&_M_rwlock);
143143 // If the maximum number of read locks has been exceeded, we just fail
144- // to acquire the lock. Unlike for lock(), we are not allowed to throw
144+ // to acquire the lock. Unlike for lock(), we are not allowed to throw
145145 // an exception.
146146 if (__ret == EBUSY || __ret == EAGAIN)
147147 return false ;
@@ -157,7 +157,7 @@ class shared_mutex_pthread {
157157
158158#else
159159
160- // / A shared mutex type implemented using std::condition_variable.
160+ // / A shared mutex type implemented using ` std::condition_variable` .
161161class shared_mutex_cv {
162162 // Based on Howard Hinnant's reference implementation from N2406.
163163
@@ -213,6 +213,7 @@ class shared_mutex_cv {
213213
214214 // Exclusive ownership
215215
216+ // / @copydoc shared_mutex::lock()
216217 void lock () {
217218 unique_lock<mutex> __lk (_M_mut);
218219 // Wait until we can set the write-entered flag.
@@ -222,6 +223,7 @@ class shared_mutex_cv {
222223 _M_gate2.wait (__lk, [=] { return _M_readers () == 0 ; });
223224 }
224225
226+ // / @copydoc shared_mutex::try_lock()
225227 bool try_lock () {
226228 unique_lock<mutex> __lk (_M_mut, try_to_lock);
227229 if (__lk.owns_lock () && _M_state == 0 ) {
@@ -231,6 +233,7 @@ class shared_mutex_cv {
231233 return false ;
232234 }
233235
236+ // / @copydoc shared_mutex::unlock()
234237 void unlock () {
235238 lock_guard<mutex> __lk (_M_mut);
236239 assert (_M_write_entered ());
@@ -242,12 +245,14 @@ class shared_mutex_cv {
242245
243246 // Shared ownership
244247
248+ // / @copydoc shared_mutex::lock_shared()
245249 void lock_shared () {
246250 unique_lock<mutex> __lk (_M_mut);
247251 _M_gate1.wait (__lk, [=] { return _M_state < _S_max_readers; });
248252 ++_M_state;
249253 }
250254
255+ // / @copydoc shared_mutex::try_lock_shared()
251256 bool try_lock_shared () {
252257 unique_lock<mutex> __lk (_M_mut, try_to_lock);
253258 if (!__lk.owns_lock ())
@@ -259,6 +264,7 @@ class shared_mutex_cv {
259264 return false ;
260265 }
261266
267+ // / @copydoc shared_mutex::unlock_shared()
262268 void unlock_shared () {
263269 lock_guard<mutex> __lk (_M_mut);
264270 assert (_M_readers () > 0 );
@@ -280,6 +286,10 @@ class shared_mutex_cv {
280286#endif
281287} // namespace detail
282288
289+ /* *
290+ * @brief A shared mutex type that can be locked exclusively
291+ * by one thread or shared non-exclusively by multiple threads.
292+ */
283293class shared_mutex {
284294 public:
285295 shared_mutex () = default ;
@@ -288,12 +298,33 @@ class shared_mutex {
288298 shared_mutex (const shared_mutex&) = delete ;
289299 shared_mutex& operator =(const shared_mutex&) = delete ;
290300
301+ // / Takes ownership of the associated mutex.
291302 void lock () { _M_impl.lock (); }
303+
304+ /* *
305+ * @brief Tries to take ownership of the mutex without blocking.
306+ *
307+ * @return True if the method takes ownership; false otherwise.
308+ */
292309 bool try_lock () { return _M_impl.try_lock (); }
310+
311+ // / Releases the ownership of the mutex from the calling thread.
293312 void unlock () { _M_impl.unlock (); }
294313
314+ /* *
315+ * @brief Blocks the calling thread until
316+ * the thread obtains shared ownership of the mutex.
317+ */
295318 void lock_shared () { _M_impl.lock_shared (); }
319+
320+ /* *
321+ * @brief Tries to take shared ownership of the mutex without blocking.
322+ *
323+ * @return True if the method takes ownership; false otherwise.
324+ */
296325 bool try_lock_shared () { return _M_impl.try_lock_shared (); }
326+
327+ // / Releases the shared ownership of the mutex from the calling thread.
297328 void unlock_shared () { _M_impl.unlock_shared (); }
298329
299330#if defined(HAVE_PTHREAD_RWLOCK)
@@ -310,33 +341,78 @@ class shared_mutex {
310341};
311342
312343template <typename Mutex>
344+ /* *
345+ * @brief A shared mutex wrapper that supports timed lock operations
346+ * and non-exclusive sharing by multiple threads.
347+ */
313348class shared_lock {
314349 public:
350+ // / A typedef for the mutex type.
315351 typedef Mutex mutex_type;
316352
317353 shared_lock () noexcept : _M_pm(nullptr ), _M_owns(false ) {}
318354
355+ /* *
356+ * @brief Creates a `shared_lock` instance and locks
357+ * the associated mutex.
358+ *
359+ * @param __m The associated mutex.
360+ */
319361 explicit shared_lock (mutex_type& __m)
320362 : _M_pm(std::addressof(__m)), _M_owns(true ) {
321363 __m.lock_shared ();
322364 }
323365
366+ /* *
367+ * @brief Creates a `shared_lock` instance and does not lock
368+ * the associated mutex.
369+ *
370+ * @param __m The associated mutex.
371+ */
324372 shared_lock (mutex_type& __m, defer_lock_t ) noexcept
325373 : _M_pm(std::addressof(__m)), _M_owns(false ) {}
326374
375+ /* *
376+ * @brief Creates a `shared_lock` instance and tries to lock
377+ * the associated mutex without blocking.
378+ *
379+ * @param __m The associated mutex.
380+ */
327381 shared_lock (mutex_type& __m, try_to_lock_t )
328382 : _M_pm(std::addressof(__m)), _M_owns(__m.try_lock_shared()) {}
329383
384+ /* *
385+ * @brief Creates a `shared_lock` instance and assumes
386+ * that the calling thread already owns the associated mutex.
387+ *
388+ * @param __m The associated mutex.
389+ */
330390 shared_lock (mutex_type& __m, adopt_lock_t )
331391 : _M_pm(std::addressof(__m)), _M_owns(true ) {}
332392
333393 template <typename _Clock, typename _Duration>
394+
395+ /* *
396+ * @brief Creates a `shared_lock` instance and tries to lock
397+ * the associated mutex until the specified absolute time has passed.
398+ *
399+ * @param __m The associated mutex.
400+ * @param __abs_time The absolute time.
401+ */
334402 shared_lock (mutex_type& __m,
335403 const chrono::time_point<_Clock, _Duration>& __abs_time)
336404 : _M_pm(std::addressof(__m)),
337405 _M_owns (__m.try_lock_shared_until(__abs_time)) {}
338406
339407 template <typename _Rep, typename _Period>
408+
409+ /* *
410+ * @brief Creates a `shared_lock` instance and tries to lock
411+ * the associated mutex until the specified duration has passed.
412+ *
413+ * @param __m The associated mutex.
414+ * @param __rel_time The time duration.
415+ */
340416 shared_lock (mutex_type& __m,
341417 const chrono::duration<_Rep, _Period>& __rel_time)
342418 : _M_pm(std::addressof(__m)),
@@ -350,36 +426,67 @@ class shared_lock {
350426 shared_lock (shared_lock const &) = delete ;
351427 shared_lock& operator =(shared_lock const &) = delete ;
352428
429+ /* *
430+ * @brief Creates a `shared_lock` instance based on the other shared lock.
431+ *
432+ * @param __sl The other `shared_lock` instance.
433+ */
353434 shared_lock (shared_lock&& __sl) noexcept : shared_lock() { swap (__sl); }
354435
436+ /* *
437+ * @brief The default move assignment operator.
438+ *
439+ * @param __sl The other `shared_lock` instance.
440+ */
355441 shared_lock& operator =(shared_lock&& __sl) noexcept {
356442 shared_lock (std::move (__sl)).swap (*this );
357443 return *this ;
358444 }
359445
446+ // / @copydoc shared_mutex::lock()
360447 void lock () {
361448 _M_lockable ();
362449 _M_pm->lock_shared ();
363450 _M_owns = true ;
364451 }
365452
453+ // / @copydoc shared_mutex::try_lock()
366454 bool try_lock () {
367455 _M_lockable ();
368456 return _M_owns = _M_pm->try_lock_shared ();
369457 }
370458
371459 template <typename _Rep, typename _Period>
460+
461+ /* *
462+ * @brief Tries to take shared ownership of the mutex
463+ * and blocks it until the specified time elapses.
464+ *
465+ * @param __rel_time The time duration.
466+ *
467+ * @return True if the method takes ownership; false otherwise.
468+ */
372469 bool try_lock_for (const chrono::duration<_Rep, _Period>& __rel_time) {
373470 _M_lockable ();
374471 return _M_owns = _M_pm->try_lock_shared_for (__rel_time);
375472 }
376473
377474 template <typename _Clock, typename _Duration>
475+
476+ /* *
477+ * @brief Tries to take shared ownership of the mutex
478+ * and blocks it until the absolute time has passed.
479+ *
480+ * @param __abs_time The absolute time.
481+ *
482+ * @return True if the method takes ownership; false otherwise.
483+ */
378484 bool try_lock_until (const chrono::time_point<_Clock, _Duration>& __abs_time) {
379485 _M_lockable ();
380486 return _M_owns = _M_pm->try_lock_shared_until (__abs_time);
381487 }
382488
489+ // / @copydoc shared_mutex::unlock()
383490 void unlock () {
384491 if (!_M_owns)
385492 THROW_OR_ABORT (std::system_error (
@@ -388,20 +495,44 @@ class shared_lock {
388495 _M_owns = false ;
389496 }
390497
498+ /* *
499+ * @brief Exchanges the data members of two `shared_lock` instances.
500+ *
501+ * @param __u The other `shared_lock` instance.
502+ */
391503 void swap (shared_lock& __u) noexcept {
392504 std::swap (_M_pm, __u._M_pm );
393505 std::swap (_M_owns, __u._M_owns );
394506 }
395507
508+ /* *
509+ * @brief Disassociates the mutex without unlocking.
510+ *
511+ * @return A pointer to the associated mutex
512+ * or a null pointer if there is no associated mutex.
513+ */
396514 mutex_type* release () noexcept {
397515 _M_owns = false ;
398516 return detail::exchange (_M_pm, nullptr );
399517 }
400518
519+ /* *
520+ * @brief Checks whether the lock owns its associated mutex.
521+ *
522+ * @return True if the lock has the associated mutex and owns it;
523+ * false otherwise.
524+ */
401525 bool owns_lock () const noexcept { return _M_owns; }
402526
527+ // / @copydoc shared_lock::owns_lock()
403528 explicit operator bool () const noexcept { return _M_owns; }
404529
530+ /* *
531+ * @brief Gets a pointer to the associated mutex.
532+ *
533+ * @return The pointer to the associated mutex,
534+ * or the null pointer if there is no associated mutex.
535+ */
405536 mutex_type* mutex () const noexcept { return _M_pm; }
406537
407538 private:
0 commit comments