Class mutex_grapher
poet::mutex_grapher — Maintains a locking order graph for acyclic_mutexes.
Synopsis
class mutex_grapher { public: // types typedef boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, vertex_properties, edge_properties> locking_order_graph; typedef std::list<const acyclic_mutex_base *> mutex_list_type; // Bundled vertex properties for locking_order_graph. struct vertex_properties { std::string name; }; // Bundled edge properties for locking_order_graph. struct edge_properties { bool locking_order_violation; }; // Provides locked access to the mutex_grapher singleton. class unique_lock : public monitor_unique_lock<monitor_ptr<mutex_grapher, boost::mutex> > { public: // construct/copy/destruct unique_lock(); }; // public member functions const locking_order_graph & graph() const; const mutex_list_type & locked_mutexes() const; template<typename Func> void set_cycle_handler(Func); void write_graphviz(std::ostream &) const; private: // construct/copy/destruct mutex_grapher(); };
Description
The mutex_grapher
class is a singleton which maintains a graph of
the locking order for the program's acyclic_mutexes.
It checks this graph to insure it has
a consistent locking order which cannot deadlock.
The class also provides information that may be useful in debugging any locking order inconsistencies which are discovered. The user may examine the locking_order_graph, output it to a graphviz file, and examine the list of mutexes currently locked by each thread. The user may also specify a custom handler to be called in the event an inconsistency is detected.
Example Code
See also
-
acyclic_mutex: a mutex wrapper whose locking events are automatically tracked by
mutex_grapher
.
mutex_grapher
public types
-
typedef boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, vertex_properties, edge_properties> locking_order_graph;
The
mutex_grapher
singleton contains onelocking_order_graph
object which records all the locking order information for acyclic_mutexes. Read access to the graph is provided through mutex_grapher::graph().Each vertex in the graph represents either a group of acyclic_mutexes which all have equivalent keys, or a single default-constructed acyclic_mutex (which has no key). A vertexes is added to the graph the first time one of its associated mutexes is locked.
Each edge in the graph represents an established locking order between two vertices. When a thread attempts to lock an acyclic_mutex while already holding a lock on one or more acyclic_mutexes, a directed edge is added to the graph (if the edge in question does not already exist). The edge is directed from the vertex of the most recently locked mutex towards the vertex of the new mutex the thread is attempting to lock. After each new edge is added, the locking order graph is checked for cycles. As long as the graph remains free of cycles, the locking order among the program's acyclic_mutexes is valid and will not result in deadlock.
See the documentation of the Boost Graph Library for more information on boost::adjacency_list.
mutex_grapher
public member functions
-
const locking_order_graph & graph() const;
Provides access to the
locking_order_graph
. -
const mutex_list_type & locked_mutexes() const;
Returns a list of
acyclic_mutex_base
pointers to the mutexes currently locked by the calling thread. The list is ordered in the same order that the mutexes were locked. This list is thread-specific data, and thus will vary depending on what thread this method is called from. -
template<typename Func> void set_cycle_handler(Func func);
The function object
func
will be called (with no arguments) when a cycle is detected in thelocking_order_graph
. The default cycle handler prints a message to stderr, and then callsabort()
. -
void write_graphviz(std::ostream & out_stream) const;
Calls
boost::write_graphviz
(), passing it theout_stream
parameter, and thelocking_order_graph
. The vertices are labeled with thename
member of the graph's bundledvertex_properties
. The edges are colored black if thelocking_order_violation
member of the the graph's bundlededge_properties
is false, and red if it is true.
mutex_grapher
private construct/copy/destruct
-
mutex_grapher();
Private constructor. The
mutex_grapher
singleton may only be accessed by creating amutex_grapher::unique_lock
object.