MongoDB  2.7.0
fail_point.h
1 /*
2  * Copyright (C) 2012 10gen Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Affero General Public License, version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Affero General Public License for more details.
12  *
13  * You should have received a copy of the GNU Affero General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * As a special exception, the copyright holders give permission to link the
17  * code of portions of this program with the OpenSSL library under certain
18  * conditions as described in each individual source file and distribute
19  * linked combinations including the program with the OpenSSL library. You
20  * must comply with the GNU Affero General Public License in all respects
21  * for all of the code used other than as permitted herein. If you modify
22  * file(s) with this exception, you may extend this exception to your
23  * version of the file(s), but you are not obligated to do so. If you do not
24  * wish to do so, delete this exception statement from your version. If you
25  * delete this exception statement from all source files in the program,
26  * then also delete it in the license file.
27  */
28 
29 #pragma once
30 
31 #include "mongo/base/disallow_copying.h"
32 #include "mongo/db/jsobj.h"
33 #include "mongo/platform/atomic_word.h"
34 #include "mongo/util/concurrency/mutex.h"
35 
36 namespace mongo {
66  class FailPoint {
67  MONGO_DISALLOW_COPYING(FailPoint);
68 
69  public:
70  typedef AtomicUInt32::WordType ValType;
71  enum Mode { off, alwaysOn, random, nTimes, numModes };
72  enum RetCode { fastOff = 0, slowOff, slowOn };
73 
74  FailPoint();
75 
81  inline bool shouldFail() {
82  RetCode ret = shouldFailOpenBlock();
83 
84  if (MONGO_likely(ret == fastOff)) {
85  return false;
86  }
87 
89  return ret == slowOn;
90  }
91 
99  inline RetCode shouldFailOpenBlock() {
100  if (MONGO_likely((_fpInfo.loadRelaxed() & ACTIVE_BIT) == 0)) {
101  return fastOff;
102  }
103 
104  return slowShouldFailOpenBlock();
105  }
106 
111  void shouldFailCloseBlock();
112 
130  void setMode(Mode mode, ValType val = 0, const BSONObj& extra = BSONObj());
131 
135  BSONObj toBSON() const;
136 
137  private:
138  static const ValType ACTIVE_BIT = 1 << 31;
139  static const ValType REF_COUNTER_MASK = ~ACTIVE_BIT;
140 
141  // Bit layout:
142  // 31: tells whether this fail point is active.
143  // 0~30: unsigned ref counter for active dynamic instances.
144  AtomicUInt32 _fpInfo;
145 
146  // Invariant: These should be read only if ACTIVE_BIT of _fpInfo is set.
147  Mode _mode;
148  AtomicInt32 _timesOrPeriod;
149  BSONObj _data;
150 
151  // protects _mode, _timesOrPeriod, _data
152  mutable mutex _modMutex;
153 
157  void enableFailPoint();
158 
162  void disableFailPoint();
163 
167  RetCode slowShouldFailOpenBlock();
168 
173  const BSONObj& getData() const;
174 
175  friend class ScopedFailPoint;
176  };
177 
184  MONGO_DISALLOW_COPYING(ScopedFailPoint);
185 
186  public:
187  ScopedFailPoint(FailPoint* failPoint);
188  ~ScopedFailPoint();
189 
193  inline bool isActive() {
194  if (_once) {
195  return false;
196  }
197 
198  _once = true;
199 
200  FailPoint::RetCode ret = _failPoint->shouldFailOpenBlock();
201  _shouldClose = ret != FailPoint::fastOff;
202  return ret == FailPoint::slowOn;
203  }
204 
209  const BSONObj& getData() const;
210 
211  private:
212  FailPoint* _failPoint;
213  bool _once;
214  bool _shouldClose;
215  };
216 
217  #define MONGO_FAIL_POINT(symbol) MONGO_unlikely(symbol.shouldFail())
218 
223  #define MONGO_FAIL_POINT_BLOCK(symbol, blockSymbol) \
224  for (mongo::ScopedFailPoint blockSymbol(&symbol); \
225  MONGO_unlikely(blockSymbol.isActive()); )
226 }
void shouldFailCloseBlock()
Decrements the reference counter.
Definition: fail_point.cpp:44
void setMode(Mode mode, ValType val=0, const BSONObj &extra=BSONObj())
Changes the settings of this fail point.
Definition: fail_point.cpp:48
const BSONObj & getData() const
Definition: fail_point.cpp:166
A simple thread-safe fail point implementation that can be activated and deactivated, as well as embed temporary data into it.
Definition: fail_point.h:66
RetCode shouldFailOpenBlock()
Checks whether fail point is active and increments the reference counter without decrementing it...
Definition: fail_point.h:99
bool isActive()
Definition: fail_point.h:193
BSON classes.
bool shouldFail()
Note: This is not side-effect free - it can change the state to OFF after calling.
Definition: fail_point.h:81
Helper class for making sure that FailPoint::shouldFailCloseBlock is called when FailPoint::shouldFai...
Definition: fail_point.h:183
BSONObj toBSON() const
Definition: fail_point.cpp:144
On pthread systems, it is an error to destroy a mutex while held (boost mutex may use pthread)...
Definition: mutex.h:74
C++ representation of a "BSON" object – that is, an extended JSON-style object in a binary representa...
Definition: bsonobj.h:77