MongoDB  2.7.0
list.h
1 // list.h
2 
31 #pragma once
32 
33 #include "mongo/util/log.h"
34 
35 namespace mongo {
36 
37  /* DON'T USE THIS. it was a dumb idea.
38 
39  this class uses a mutex for writes, but not for reads.
40  we can get fancier later...
41 
42  struct Member : public List1<Member>::Base {
43  const char *host;
44  int port;
45  };
46  List1<Member> _members;
47  _members.head()->next();
48 
49  */
50  template<typename T>
51  class List1 : boost::noncopyable {
52  public:
53  /* next() and head() return 0 at end of list */
54 
55  List1() : _head(0), _m("List1"), _orphans(0) { }
56 
57  class Base {
58  friend class List1;
59  T *_next;
60  public:
61  Base() : _next(0){}
62  ~Base() { wassert(false); } // we never want this to happen
63  T* next() const { return _next; }
64  };
65 
77  T* head() const { return (T*) _head; }
78 
79  void push(T* t) {
80  verify( t->_next == 0 );
81  scoped_lock lk(_m);
82  t->_next = (T*) _head;
83  _head = t;
84  }
85 
86  // intentionally leaks.
87  void orphanAll() {
88  scoped_lock lk(_m);
89  _head = 0;
90  }
91 
92  /* t is not deleted, but is removed from the list. (orphaned) */
93  void orphan(T* t) {
94  scoped_lock lk(_m);
95  T *&prev = (T*&) _head;
96  T *n = prev;
97  while( n != t ) {
98  uassert( 14050 , "List1: item to orphan not in list", n );
99  prev = n->_next;
100  n = prev;
101  }
102  prev = t->_next;
103  if( ++_orphans > 500 )
104  log() << "warning List1 orphans=" << _orphans;
105  }
106 
107  private:
108  volatile T *_head;
109  mongo::mutex _m;
110  int _orphans;
111  };
112 
113 };
Definition: list.h:51
T * head() const
note this is safe:
Definition: list.h:77
Definition: mutex.h:101
On pthread systems, it is an error to destroy a mutex while held (boost mutex may use pthread)...
Definition: mutex.h:74
LogstreamBuilder log()
Returns a LogstreamBuilder for logging a message with LogSeverity::Log().
Definition: log.h:69
Definition: list.h:57