File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ cmake_minimum_required (VERSION 3.15 )
2+ project (chroma-examples LANGUAGES CXX )
3+
4+ set (CMAKE_CXX_STANDARD 26)
5+ set (CMAKE_CXX_STANDARD_REQUIRED True )
6+
7+ find_package (chroma REQUIRED )
8+
9+ add_executable (chroma-critical-section src/main.cpp )
10+ target_link_libraries (chroma-critical-section PRIVATE chroma::chroma )
11+ target_include_directories (chroma-critical-section PRIVATE include )
12+
13+ # WORKAROUND:
14+ # Conan needs the new CMakeConfigDeps generator to handle INTERFACE options etc properly
15+ target_compile_features (chroma-critical-section PRIVATE cxx_std_26 )
16+ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" )
17+ target_compile_options (chroma-critical-section PRIVATE "-stdlib=libc++" "-freflection-latest" )
18+ target_link_options (chroma-critical-section PRIVATE "-stdlib=libc++" )
19+ target_link_libraries (chroma-critical-section PRIVATE "c++abi" )
20+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
21+ target_compile_options (chroma-critical-section PRIVATE "-freflection" )
22+ endif ()
Original file line number Diff line number Diff line change 1+ from conan import ConanFile
2+ from conan .tools .cmake import CMake , cmake_layout
3+
4+ class Consumer (ConanFile ):
5+ name = "chroma-critical-section"
6+ version = "0.1"
7+ settings = "os" , "compiler" , "build_type" , "arch"
8+ requires = "chroma/0.0.1"
9+ generators = "CMakeDeps" , "CMakeToolchain"
10+
11+ def layout (self ):
12+ cmake_layout (self )
13+
14+ def build (self ):
15+ cmake = CMake (self )
16+ cmake .configure ()
17+ cmake .build ()
Original file line number Diff line number Diff line change 1+
2+ #pragma once
3+ #include < mutex>
4+ #include < utility>
5+ #include < chroma>
6+
7+ class locked_context {
8+ public:
9+ explicit locked_context (std::mutex& mtx) : m_mutex(&mtx) { m_mutex->lock (); }
10+
11+ ~locked_context () {
12+ if (m_mutex != nullptr ) {
13+ m_mutex->unlock ();
14+ }
15+ }
16+
17+ locked_context (locked_context&& other) noexcept
18+ : m_mutex(std::exchange(other.m_mutex, nullptr )) {}
19+
20+ locked_context& operator =(locked_context&& other) noexcept {
21+ if (this != &other) {
22+ if (m_mutex != nullptr ) {
23+ m_mutex->unlock ();
24+ }
25+ m_mutex = std::exchange (other.m_mutex , nullptr );
26+ }
27+ return *this ;
28+ }
29+
30+ locked_context (const locked_context&) = delete ;
31+ locked_context& operator =(const locked_context&) = delete ;
32+
33+ [[nodiscard]] chroma::color<locked_context> context () const {
34+ if (m_mutex == nullptr ) {
35+ throw std::runtime_error (" Invalid context" );
36+ }
37+ return {};
38+ }
39+
40+ static constexpr auto error_message = " not in locked context" ;
41+
42+ private:
43+ std::mutex* m_mutex;
44+ };
Original file line number Diff line number Diff line change 1+ #include < chroma>
2+ #include < lock.hpp>
3+
4+ void still_in_critical_section (callable_from<locked_context> = {}) {
5+ // ...
6+ }
7+
8+ void must_be_locked (callable_from<locked_context> = {}) {
9+ // call can be implicit, lock is still held
10+ still_in_critical_section ();
11+ }
12+
13+ int main () {
14+ std::mutex mtx;
15+ {
16+ locked_context lock (mtx); // acquire lock
17+
18+ // get color for the acquired lock
19+ must_be_locked (lock.context ());
20+ }
21+ }
You can’t perform that action at this time.
0 commit comments