summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libcamera/base/meson.build1
-rw-r--r--include/libcamera/base/mutex.h132
-rw-r--r--include/libcamera/base/thread.h7
-rw-r--r--src/libcamera/base/meson.build1
-rw-r--r--src/libcamera/base/mutex.cpp55
-rw-r--r--src/libcamera/base/thread.cpp15
-rw-r--r--src/v4l2/v4l2_camera_proxy.h4
7 files changed, 192 insertions, 23 deletions
diff --git a/include/libcamera/base/meson.build b/include/libcamera/base/meson.build
index 1a71ce5a..37c4435a 100644
--- a/include/libcamera/base/meson.build
+++ b/include/libcamera/base/meson.build
@@ -13,6 +13,7 @@ libcamera_base_headers = files([
'flags.h',
'log.h',
'message.h',
+ 'mutex.h',
'object.h',
'private.h',
'semaphore.h',
diff --git a/include/libcamera/base/mutex.h b/include/libcamera/base/mutex.h
new file mode 100644
index 00000000..2d23e49e
--- /dev/null
+++ b/include/libcamera/base/mutex.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * mutex.h - Mutex classes with clang thread safety annotation
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <mutex>
+
+#include <libcamera/base/thread_annotations.h>
+
+namespace libcamera {
+
+/* \todo using Mutex = std::mutex if libc++ is used. */
+
+#ifndef __DOXYGEN__
+
+class LIBCAMERA_TSA_CAPABILITY("mutex") Mutex final
+{
+public:
+ constexpr Mutex()
+ {
+ }
+
+ void lock() LIBCAMERA_TSA_ACQUIRE()
+ {
+ mutex_.lock();
+ }
+
+ void unlock() LIBCAMERA_TSA_RELEASE()
+ {
+ mutex_.unlock();
+ }
+
+private:
+ friend class MutexLocker;
+
+ std::mutex mutex_;
+};
+
+class LIBCAMERA_TSA_SCOPED_CAPABILITY MutexLocker final
+{
+public:
+ explicit MutexLocker(Mutex &mutex) LIBCAMERA_TSA_ACQUIRE(mutex)
+ : lock_(mutex.mutex_)
+ {
+ }
+
+ MutexLocker(Mutex &mutex, std::defer_lock_t t) noexcept LIBCAMERA_TSA_EXCLUDES(mutex)
+ : lock_(mutex.mutex_, t)
+ {
+ }
+
+ ~MutexLocker() LIBCAMERA_TSA_RELEASE()
+ {
+ }
+
+ void lock() LIBCAMERA_TSA_ACQUIRE()
+ {
+ lock_.lock();
+ }
+
+ bool try_lock() LIBCAMERA_TSA_TRY_ACQUIRE(true)
+ {
+ return lock_.try_lock();
+ }
+
+ void unlock() LIBCAMERA_TSA_RELEASE()
+ {
+ lock_.unlock();
+ }
+
+private:
+ friend class ConditionVariable;
+
+ std::unique_lock<std::mutex> lock_;
+};
+
+class ConditionVariable final
+{
+public:
+ ConditionVariable()
+ {
+ }
+
+ void notify_one() noexcept
+ {
+ cv_.notify_one();
+ }
+
+ void notify_all() noexcept
+ {
+ cv_.notify_all();
+ }
+
+ template<class Predicate>
+ void wait(MutexLocker &locker, Predicate stopWaiting)
+ {
+ cv_.wait(locker.lock_, stopWaiting);
+ }
+
+ template<class Rep, class Period, class Predicate>
+ bool wait_for(MutexLocker &locker,
+ const std::chrono::duration<Rep, Period> &relTime,
+ Predicate stopWaiting)
+ {
+ return cv_.wait_for(locker.lock_, relTime, stopWaiting);
+ }
+
+private:
+ std::condition_variable cv_;
+};
+
+#else /* __DOXYGEN__ */
+
+class Mutex final
+{
+};
+
+class MutexLocker final
+{
+};
+
+class ConditionVariable final
+{
+};
+
+#endif /* __DOXYGEN__ */
+} /* namespace libcamera */
diff --git a/include/libcamera/base/thread.h b/include/libcamera/base/thread.h
index 1ebf8363..44678c34 100644
--- a/include/libcamera/base/thread.h
+++ b/include/libcamera/base/thread.h
@@ -7,15 +7,14 @@
#pragma once
-#include <condition_variable>
#include <memory>
-#include <mutex>
#include <sys/types.h>
#include <thread>
#include <libcamera/base/private.h>
#include <libcamera/base/message.h>
+#include <libcamera/base/mutex.h>
#include <libcamera/base/signal.h>
#include <libcamera/base/utils.h>
@@ -27,10 +26,6 @@ class Object;
class ThreadData;
class ThreadMain;
-using ConditionVariable = std::condition_variable;
-using Mutex = std::mutex;
-using MutexLocker = std::unique_lock<std::mutex>;
-
class Thread
{
public:
diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build
index 05fed7ac..b93b8505 100644
--- a/src/libcamera/base/meson.build
+++ b/src/libcamera/base/meson.build
@@ -11,6 +11,7 @@ libcamera_base_sources = files([
'flags.cpp',
'log.cpp',
'message.cpp',
+ 'mutex.cpp',
'object.cpp',
'semaphore.cpp',
'signal.cpp',
diff --git a/src/libcamera/base/mutex.cpp b/src/libcamera/base/mutex.cpp
new file mode 100644
index 00000000..e34e8618
--- /dev/null
+++ b/src/libcamera/base/mutex.cpp
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2021, Google Inc.
+ *
+ * mutex.cpp - Mutex classes with clang thread safety annotation
+ */
+
+#include <libcamera/base/mutex.h>
+
+/**
+ * \file base/mutex.h
+ * \brief Mutex classes with clang thread safety annotation
+ */
+
+namespace libcamera {
+
+/**
+ * \class Mutex
+ * \brief std::mutex wrapper with clang thread safety annotation
+ *
+ * The Mutex class wraps a std::mutex instance to add clang thread safety
+ * annotation support. The class exposes the same interface as std::mutex and
+ * can be used as a transparent replacement. It integrates with the
+ * MutexLocker and ConditionVariable classes.
+ *
+ * See https://en.cppreference.com/w/cpp/thread/mutex for the complete API
+ * documentation.
+ */
+
+/**
+ * \class MutexLocker
+ * \brief std::unique_lock wrapper with clang thread safety annotation
+ *
+ * The MutexLocker class wraps a std::unique_lock instance to add clang thread
+ * safety annotation support. The class exposes the same interface as
+ * std::unique_lock and can be used as a transparent replacement. It integrates
+ * with the Mutex and ConditionVariable classes.
+ *
+ * See https://en.cppreference.com/w/cpp/thread/unique_lock for the complete API
+ * documentation.
+ */
+
+/**
+ * \class ConditionVariable
+ * \brief std::condition_variable wrapper integrating with MutexLocker
+ *
+ * The ConditionVariable class wraps a std::condition_variable instance to
+ * integrate with the MutexLocker class. The class exposes the same interface as
+ * std::condition_variable and can be used as a transparent replacement.
+ *
+ * See https://en.cppreference.com/w/cpp/thread/condition_variable for the
+ * complete API documentation.
+ */
+
+} /* namespace libcamera */
diff --git a/src/libcamera/base/thread.cpp b/src/libcamera/base/thread.cpp
index b893135f..b2043b7e 100644
--- a/src/libcamera/base/thread.cpp
+++ b/src/libcamera/base/thread.cpp
@@ -205,21 +205,6 @@ ThreadData *ThreadData::current()
}
/**
- * \typedef ConditionVariable
- * \brief An alias for std::condition_variable
- */
-
-/**
- * \typedef Mutex
- * \brief An alias for std::mutex
- */
-
-/**
- * \typedef MutexLocker
- * \brief An alias for std::unique_lock<std::mutex>
- */
-
-/**
* \class Thread
* \brief A thread of execution
*
diff --git a/src/v4l2/v4l2_camera_proxy.h b/src/v4l2/v4l2_camera_proxy.h
index 040954dd..fa0a49e0 100644
--- a/src/v4l2/v4l2_camera_proxy.h
+++ b/src/v4l2/v4l2_camera_proxy.h
@@ -14,7 +14,7 @@
#include <sys/types.h>
#include <vector>
-#include <libcamera/base/thread.h>
+#include <libcamera/base/mutex.h>
#include <libcamera/camera.h>
@@ -59,7 +59,7 @@ private:
int vidioc_querybuf(V4L2CameraFile *file, struct v4l2_buffer *arg);
int vidioc_qbuf(V4L2CameraFile *file, struct v4l2_buffer *arg);
int vidioc_dqbuf(V4L2CameraFile *file, struct v4l2_buffer *arg,
- libcamera::Mutex *lock);
+ libcamera::Mutex *lock) LIBCAMERA_TSA_REQUIRES(*lock);
int vidioc_streamon(V4L2CameraFile *file, int *arg);
int vidioc_streamoff(V4L2CameraFile *file, int *arg);