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

  1. typedef boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, vertex_properties, edge_properties> locking_order_graph;

    The mutex_grapher singleton contains one locking_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

  1. const locking_order_graph & graph() const;

    Provides access to the locking_order_graph.

  2. 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.

  3. 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 the locking_order_graph. The default cycle handler prints a message to stderr, and then calls abort().

  4. void write_graphviz(std::ostream & out_stream) const;

    Calls boost::write_graphviz(), passing it the out_stream parameter, and the locking_order_graph. The vertices are labeled with the name member of the graph's bundled vertex_properties. The edges are colored black if the locking_order_violation member of the the graph's bundled edge_properties is false, and red if it is true.

mutex_grapher private construct/copy/destruct

  1. mutex_grapher();

    Private constructor. The mutex_grapher singleton may only be accessed by creating a mutex_grapher::unique_lock object.