Status OperationContext::checkForInterruptNoAssert() noexcept { // TODO: Remove the MONGO_likely(getClient()) once all operation contexts are constructed with // clients. if (MONGO_likely(getClient() && getServiceContext()) && getServiceContext()->getKillAllOperations()) { return Status(ErrorCodes::InterruptedAtShutdown, "interrupted at shutdown"); } if (hasDeadlineExpired()) { if (!_hasArtificialDeadline) { markKilled(_timeoutError); } return Status(_timeoutError, "operation exceeded time limit"); } if (_ignoreInterrupts) { return Status::OK(); } MONGO_FAIL_POINT_BLOCK(checkForInterruptFail, scopedFailPoint) { if (opShouldFail(getClient(), scopedFailPoint.getData())) { log() << "set pending kill on op " << getOpID() << ", for checkForInterruptFail"; markKilled(); } } const auto killStatus = getKillStatus(); if (killStatus != ErrorCodes::OK) { return Status(killStatus, "operation was interrupted"); } return Status::OK(); }
BSONObj BSONElement::embeddedObjectUserCheck() const { if (MONGO_likely(isABSONObj())) return BSONObj(value(), BSONObj::LargeSizeTrait{}); std::stringstream ss; ss << "invalid parameter: expected an object (" << fieldName() << ")"; uasserted(10065, ss.str()); return BSONObj(); // never reachable }
bool DurableImpl::commitIfNeeded() { if (MONGO_likely(commitJob.bytes() < UncommittedBytesLimit)) { return false; } // Just wake up the flush thread flushRequested.notify_one(); return true; }
bool DurableImpl::commitIfNeeded(OperationContext* txn) { // this is safe since since conceptually if you call commitIfNeeded, we're at a valid // spot in an operation to be terminated. cc().checkpointHappened(); if (MONGO_likely(commitJob.bytes() < UncommittedBytesLimit)) { return false; } // Just wake up the flush thread flushRequested.notify_one(); return true; }
int BSONElement::computeSize() const { enum SizeStyle : uint8_t { kFixed, // Total size is a fixed amount + key length. kIntPlusFixed, // Like Fixed, but also add in the int32 immediately following the key. kRegEx, // Handled specially. }; struct SizeInfo { uint8_t style : 2; uint8_t bytes : 6; // Includes type byte. Excludes field name and variable lengths. }; MONGO_STATIC_ASSERT(sizeof(SizeInfo) == 1); // This table should take 20 bytes. Align to next power of 2 to avoid splitting across cache // lines unnecessarily. static constexpr SizeInfo kSizeInfoTable alignas(32)[] = { {SizeStyle::kFixed, 1}, // EOO {SizeStyle::kFixed, 9}, // NumberDouble {SizeStyle::kIntPlusFixed, 5}, // String {SizeStyle::kIntPlusFixed, 1}, // Object {SizeStyle::kIntPlusFixed, 1}, // Array {SizeStyle::kIntPlusFixed, 6}, // BinData {SizeStyle::kFixed, 1}, // Undefined {SizeStyle::kFixed, 13}, // OID {SizeStyle::kFixed, 2}, // Bool {SizeStyle::kFixed, 9}, // Date {SizeStyle::kFixed, 1}, // Null {SizeStyle::kRegEx}, // Regex {SizeStyle::kIntPlusFixed, 17}, // DBRef {SizeStyle::kIntPlusFixed, 5}, // Code {SizeStyle::kIntPlusFixed, 5}, // Symbol {SizeStyle::kIntPlusFixed, 1}, // CodeWScope {SizeStyle::kFixed, 5}, // Int {SizeStyle::kFixed, 9}, // Timestamp {SizeStyle::kFixed, 9}, // Long {SizeStyle::kFixed, 17}, // Decimal }; MONGO_STATIC_ASSERT((sizeof(kSizeInfoTable) / sizeof(kSizeInfoTable[0])) == JSTypeMax + 1); // This is the start of the runtime code for this function. Everything above happens at compile // time. This function attempts to push complex handling of unlikely events out-of-line to // ensure that the common cases never need to spill any registers (at least on x64 with // gcc-5.4), which reduces the function call overhead. int8_t type = *data; if (MONGO_unlikely(type < 0 || type > JSTypeMax)) { if (MONGO_unlikely(type != MinKey && type != MaxKey)) { msgAssertedBadType(type); } // MinKey and MaxKey should be treated the same as Null type = jstNULL; } const auto sizeInfo = kSizeInfoTable[type]; if (sizeInfo.style == SizeStyle::kFixed) return sizeInfo.bytes + fieldNameSize(); if (MONGO_likely(sizeInfo.style == SizeStyle::kIntPlusFixed)) return sizeInfo.bytes + fieldNameSize() + valuestrsize(); return [this, type]() NOINLINE_DECL { // Regex is two c-strings back-to-back. invariant(type == BSONType::RegEx); const char* p = value(); size_t len1 = strlen(p); p = p + len1 + 1; size_t len2 = strlen(p); return (len1 + 1 + len2 + 1) + fieldNameSize() + 1; }(); }