ROS 2 rclcpp + rcl - kilted  kilted
ROS 2 C++ Client Library with ROS Client Library
write_preferring_read_write_lock.cpp
1 // Copyright 2020 Open Source Robotics Foundation, Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "rclcpp/wait_set_policies/detail/write_preferring_read_write_lock.hpp"
16 
17 namespace rclcpp
18 {
19 namespace wait_set_policies
20 {
21 namespace detail
22 {
23 
24 WritePreferringReadWriteLock::WritePreferringReadWriteLock(
25  std::function<void()> enter_waiting_function)
26 : read_mutex_(*this), write_mutex_(*this), enter_waiting_function_(enter_waiting_function)
27 {}
28 
29 WritePreferringReadWriteLock::ReadMutex &
30 WritePreferringReadWriteLock::get_read_mutex()
31 {
32  return read_mutex_;
33 }
34 
36 WritePreferringReadWriteLock::get_write_mutex()
37 {
38  return write_mutex_;
39 }
40 
41 WritePreferringReadWriteLock::ReadMutex::ReadMutex(WritePreferringReadWriteLock & parent_lock)
42 : parent_lock_(parent_lock)
43 {}
44 
45 void
46 WritePreferringReadWriteLock::ReadMutex::lock()
47 {
48  std::unique_lock<std::mutex> lock(parent_lock_.mutex_);
49  while (
50  parent_lock_.number_of_writers_waiting_ > 0 ||
51  parent_lock_.writer_active_ ||
52  parent_lock_.reader_active_)
53  {
54  parent_lock_.condition_variable_.wait(lock);
55  }
56  parent_lock_.reader_active_ = true;
57  // implicit unlock of parent_lock_.mutex_
58 }
59 
60 void
61 WritePreferringReadWriteLock::ReadMutex::unlock()
62 {
63  std::unique_lock<std::mutex> lock(parent_lock_.mutex_);
64  parent_lock_.reader_active_ = false;
65  parent_lock_.condition_variable_.notify_all();
66  // implicit unlock of parent_lock_.mutex_
67 }
68 
69 WritePreferringReadWriteLock::WriteMutex::WriteMutex(WritePreferringReadWriteLock & parent_lock)
70 : parent_lock_(parent_lock)
71 {}
72 
73 void
74 WritePreferringReadWriteLock::WriteMutex::lock()
75 {
76  std::unique_lock<std::mutex> lock(parent_lock_.mutex_);
77  parent_lock_.number_of_writers_waiting_ += 1;
78  if (nullptr != parent_lock_.enter_waiting_function_) {
79  parent_lock_.enter_waiting_function_();
80  }
81  while (parent_lock_.reader_active_ || parent_lock_.writer_active_) {
82  parent_lock_.condition_variable_.wait(lock);
83  }
84  parent_lock_.number_of_writers_waiting_ -= 1;
85  parent_lock_.writer_active_ = true;
86  // implicit unlock of parent_lock_.mutex_
87 }
88 
89 void
90 WritePreferringReadWriteLock::WriteMutex::unlock()
91 {
92  std::unique_lock<std::mutex> lock(parent_lock_.mutex_);
93  parent_lock_.writer_active_ = false;
94  parent_lock_.condition_variable_.notify_all();
95  // implicit unlock of parent_lock_.mutex_
96 }
97 
98 } // namespace detail
99 } // namespace wait_set_policies
100 } // namespace rclcpp
Versions of rosidl_typesupport_cpp::get_message_type_support_handle that handle adapted types.