From 38e73e021974c89dfed373b64bd266400c665da3 Mon Sep 17 00:00:00 2001 From: C Vasco Date: Sun, 15 May 2022 20:57:57 -0500 Subject: [PATCH] Refactor hierarchical_mutex example for clarity Organize code to show the symmetry between unlock and lock. Lock and unlock each have check, action, update pattern, emphasized here. The two exceptions now have more info on the source of the error. Using 'level' instead of 'hierarchical_value' helps quickly and simply convey meaning. Using 'level' allows for better variable names like 'instance_level' and 'thread_level' --- listings/listing_3.8.cpp | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/listings/listing_3.8.cpp b/listings/listing_3.8.cpp index a2f8276..77a11ef 100644 --- a/listings/listing_3.8.cpp +++ b/listings/listing_3.8.cpp @@ -4,49 +4,61 @@ class hierarchical_mutex { std::mutex internal_mutex; - unsigned long const hierarchy_value; - unsigned long previous_hierarchy_value; - static thread_local unsigned long this_thread_hierarchy_value; + unsigned long const instance_level; + unsigned long previous_level; + static thread_local unsigned long thread_level; - void check_for_hierarchy_violation() + void check_lock_order() { - if(this_thread_hierarchy_value <= hierarchy_value) + if(thread_level <= instance_level) { - throw std::logic_error("mutex hierarchy violated"); + throw std::logic_error("mutex lock order violated"); } } - void update_hierarchy_value() + void update_levels_on_lock() { - previous_hierarchy_value=this_thread_hierarchy_value; - this_thread_hierarchy_value=hierarchy_value; + previous_level=thread_level; + thread_level=instance_level; + } + void check_unlock_order() + { + if(thread_level != instance_level) + { + throw std::logic_error("mutex unlock order violated"); + } + } + void update_levels_on_unlock() + { + thread_level=previous_level; } public: explicit hierarchical_mutex(unsigned long value): - hierarchy_value(value), - previous_hierarchy_value(0) + instance_level(value), + previous_level(0) {} void lock() { - check_for_hierarchy_violation(); + check_lock_order(); internal_mutex.lock(); - update_hierarchy_value(); + update_levels_on_lock(); } void unlock() { - this_thread_hierarchy_value=previous_hierarchy_value; + check_unlock_order(); + update_levels_on_unlock(); internal_mutex.unlock(); } bool try_lock() { - check_for_hierarchy_violation(); + check_lock_order(); if(!internal_mutex.try_lock()) return false; - update_hierarchy_value(); + update_levels_on_lock(); return true; } }; thread_local unsigned long - hierarchical_mutex::this_thread_hierarchy_value(ULONG_MAX); + hierarchical_mutex::thread_level(ULONG_MAX); int main() {