~ubuntu-branches/ubuntu/utopic/mongodb/utopic

« back to all changes in this revision

Viewing changes to src/mongo/db/kill_current_op.cpp

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-07-03 09:23:46 UTC
  • mfrom: (1.3.10) (44.1.14 sid)
  • Revision ID: package-import@ubuntu.com-20140703092346-c5bvt46wnzougyly
Tags: 1:2.6.3-0ubuntu1
* New upstream stable release:
  - Dropped patches, included upstream:
    + 0003-All-platforms-but-Windows-find-hash-in-std-tr1.patch
    + 0008-Use-system-libstemmer.patch
    + 0011-Use-a-signed-char-to-store-BSONType-enumerations.patch
    + 0001-SERVER-12064-Atomic-operations-for-gcc-non-Intel-arc.patch
    + 0002-SERVER-12065-Support-ARM-and-AArch64-builds.patch
  - d/p/*: Refreshed/rebased remaining patches.
  - Use system provided libyaml-cpp:
    + d/control: Add libyaml-cpp-dev to BD's.
    + d/rules: Enable --with-system-yaml option.
    + d/p/fix-yaml-detection.patch: Fix detection of libyaml-cpp library.
  - d/mongodb-server.mongodb.upstart: Sync changes from upstream.
  - d/control,mongodb-dev.*: Drop mongodb-dev package; it has no reverse
    dependencies and upstream no longer install header files.
  - d/NEWS: Point users to upstream upgrade documentation for upgrades
    from 2.4 to 2.6.
* Merge from Debian unstable.
* d/control: BD on libv8-3.14-dev to ensure that transitioning to new v8
  versions is a explicit action due to changes in behaviour in >= 3.25
  (LP: #1295723).
* d/mongodb-server.prerm: Dropped debug echo call from maintainer script
  (LP: #1294455).

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
*
13
13
*    You should have received a copy of the GNU Affero General Public License
14
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 for
 
21
*    all of the code used other than as permitted herein. If you modify file(s)
 
22
*    with this exception, you may extend this exception to your version of the
 
23
*    file(s), but you are not obligated to do so. If you do not wish to do so,
 
24
*    delete this exception statement from your version. If you delete this
 
25
*    exception statement from all source files in the program, then also delete
 
26
*    it in the license file.
15
27
*/
16
28
 
17
29
#include "mongo/db/kill_current_op.h"
21
33
#include "mongo/bson/util/atomic_int.h"
22
34
#include "mongo/db/client.h"
23
35
#include "mongo/db/curop.h"
 
36
#include "mongo/platform/random.h"
24
37
#include "mongo/scripting/engine.h"
 
38
#include "mongo/util/fail_point_service.h"
25
39
 
26
40
namespace mongo {
27
41
 
 
42
    // Enabling the checkForInterruptFail fail point will start a game of random chance on the
 
43
    // connection specified in the fail point data, generating an interrupt with a given fixed
 
44
    // probability.  Example invocation:
 
45
    //
 
46
    // {configureFailPoint: "checkForInterruptFail",
 
47
    //  mode: "alwaysOn",
 
48
    //  data: {conn: 17, chance: .01, allowNested: true}}
 
49
    //
 
50
    // All three data fields must be specified.  In the above example, all interrupt points on
 
51
    // connection 17 will generate a kill on the current operation with probability p(.01),
 
52
    // including interrupt points of nested operations.  If "allowNested" is false, nested
 
53
    // operations are not targeted.  "chance" must be a double between 0 and 1, inclusive.
 
54
    MONGO_FP_DECLARE(checkForInterruptFail);
 
55
 
28
56
    void KillCurrentOp::interruptJs( AtomicUInt *op ) {
29
57
        if ( !globalScriptEngine )
30
58
            return;
104
132
        _condvar.notify_all();
105
133
    }
106
134
 
107
 
    void KillCurrentOp::checkForInterrupt( bool heedMutex ) {
 
135
namespace {
 
136
 
 
137
    // Global state for checkForInterrupt fail point.
 
138
    PseudoRandom checkForInterruptPRNG(static_cast<int64_t>(time(NULL)));
 
139
 
 
140
    // Helper function for checkForInterrupt fail point.  Decides whether the operation currently
 
141
    // being run by the given Client meet the (probabilistic) conditions for interruption as
 
142
    // specified in the fail point info.
 
143
    bool opShouldFail(const Client& c, const BSONObj& failPointInfo) {
 
144
        // Only target the client with the specified connection number.
 
145
        if (c.getConnectionId() != failPointInfo["conn"].safeNumberLong()) {
 
146
            return false;
 
147
        }
 
148
 
 
149
        // Only target nested operations if requested.
 
150
        if (!failPointInfo["allowNested"].trueValue() && c.curop()->parent() != NULL) {
 
151
            return false;
 
152
        }
 
153
 
 
154
        // Return true with (approx) probability p = "chance".  Recall: 0 <= chance <= 1.
 
155
        double next = static_cast<double>(std::abs(checkForInterruptPRNG.nextInt64()));
 
156
        double upperBound =
 
157
            std::numeric_limits<int64_t>::max() * failPointInfo["chance"].numberDouble();
 
158
        if (next > upperBound) {
 
159
            return false;
 
160
        }
 
161
        return true;
 
162
    }
 
163
 
 
164
} // namespace
 
165
 
 
166
    void KillCurrentOp::checkForInterrupt(bool heedMutex) {
108
167
        Client& c = cc();
109
 
        if ( heedMutex && Lock::somethingWriteLocked() && c.hasWrittenThisPass() )
 
168
 
 
169
        if (heedMutex && Lock::somethingWriteLocked() && c.hasWrittenSinceCheckpoint()) {
110
170
            return;
111
 
        if( _globalKill )
112
 
            uasserted(11600,"interrupted at shutdown");
113
 
        if( c.curop()->killPending() ) {
114
 
            notifyAllWaiters();
115
 
            uasserted(11601,"operation was interrupted");
 
171
        }
 
172
 
 
173
        uassert(ErrorCodes::InterruptedAtShutdown, "interrupted at shutdown", !_globalKill);
 
174
 
 
175
        if (c.curop()->maxTimeHasExpired()) {
 
176
            c.curop()->kill();
 
177
            notifyAllWaiters();
 
178
            uasserted(ErrorCodes::ExceededTimeLimit, "operation exceeded time limit");
 
179
        }
 
180
        MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) {
 
181
            if (opShouldFail(c, scopedFailPoint.getData())) {
 
182
                log() << "set pending kill on " << (c.curop()->parent() ? "nested" : "top-level")
 
183
                      << " op " << c.curop()->opNum().get() << ", for checkForInterruptFail";
 
184
                c.curop()->kill();
 
185
            }
 
186
        }
 
187
        if (c.curop()->killPending()) {
 
188
            notifyAllWaiters();
 
189
            uasserted(11601, "operation was interrupted");
116
190
        }
117
191
    }
118
192
    
119
193
    const char * KillCurrentOp::checkForInterruptNoAssert() {
120
194
        Client& c = cc();
121
 
        if( _globalKill )
 
195
 
 
196
        if (_globalKill) {
122
197
            return "interrupted at shutdown";
123
 
        if( c.curop()->killPending() )
 
198
        }
 
199
        if (c.curop()->maxTimeHasExpired()) {
 
200
            c.curop()->kill();
 
201
            return "exceeded time limit";
 
202
        }
 
203
        MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) {
 
204
            if (opShouldFail(c, scopedFailPoint.getData())) {
 
205
                log() << "set pending kill on " << (c.curop()->parent() ? "nested" : "top-level")
 
206
                      << " op " << c.curop()->opNum().get() << ", for checkForInterruptFail";
 
207
                c.curop()->kill();
 
208
            }
 
209
        }
 
210
        if (c.curop()->killPending()) {
124
211
            return "interrupted";
 
212
        }
125
213
        return "";
126
214
    }
127
215