MojErr MojDbKindState::id(const MojChar* name, const MojChar* objKey, MojDbReq& req, MojObject& idOut, bool& createdOut) { MojAssert(name && objKey); MojAssertMutexLocked(m_lock); createdOut = false; // reload object each time because last update may have been rolled back MojObject obj; MojRefCountedPtr<MojDbStorageItem> item; MojErr err = readIds(objKey, req, obj, item); MojErrCheck(err); if (!obj.get(name, idOut)) { // get next id from seq MojDbStorageSeq* seq = m_kindEngine->indexSeq(); MojAssert(seq); MojInt64 id = 0; MojErr err = seq->get(id); MojErrCheck(err); // update copy of id map and write it out err = obj.put(name, id); MojErrCheck(err); err = writeIds(objKey, obj, req, item); MojErrCheck(err); // update retval idOut = id; createdOut = true; } return MojErrNone; }
MojErr MojLunaService::removeSubscriptionImpl(MojServiceMessage* msg) { LOG_TRACE("Entering function %s", __FUNCTION__); MojAssert(msg); MojAssertMutexLocked(m_mutex); /*MojString token; MojErr err = token.format(_T("%d"), msg->token()); MojErrCheck(err); MojLunaErr lserr; MojLunaMessage* lsMessage = static_cast<MojLunaMessage*>(msg); LSHandle* handle = LSMessageGetConnection(lsMessage->impl()); LSSubscriptionIter* iter = NULL; bool retVal = LSSubscriptionAcquire(handle, token, &iter, lserr); MojLsErrCheck(retVal, lserr); while (LSSubscriptionHasNext(iter)) { LSMessage* msg = LSSubscriptionNext(iter); MojAssert(msg); MojUnused(msg); LSSubscriptionRemove(iter); } LSSubscriptionRelease(iter);*/ return MojErrNone; }
void MojLogEngine::updateLoggerLevel(MojLogger* logger) { MojAssertMutexLocked(m_mutex); MojAssert(logger); bool matched = false; const MojChar* loggerName = logger->name(); MojSize loggerLen = MojStrLen(loggerName); for (LevelMap::ConstIterator i = m_levels.begin(); i != m_levels.end(); ++i) { const MojChar* confName = i.key().data(); MojSize confLen = i.key().length(); if (loggerLen >= confLen && !MojStrNCmp(loggerName, confName, confLen) && (loggerName[confLen] == _T('\0') || loggerName[confLen] == _T('.'))) { // update the level, but keep iterating because there may be a longer match logger->level(i.value()); matched = true; } } if (!matched) { // default to default logger->level(m_defaultLogger.level()); } }
MojErr MojDbKindState::writeObj(const MojChar* key, const MojObject& val, MojDbStorageDatabase* db, MojDbStorageTxn* txn, MojRefCountedPtr<MojDbStorageItem>& oldItem) { MojAssert(key && db && txn); MojAssertMutexLocked(m_lock); // reconstitute obj MojObject obj; if (oldItem.get()) { MojErr err = oldItem->toObject(obj, *m_kindEngine, false); MojErrCheck(err); } MojErr err = obj.put(key, val); MojErrCheck(err); // we directly use the storage engine apis because the higher-level apis depend on the kind state. MojBuffer buf; err = obj.toBytes(buf); MojErrCheck(err); txn->quotaEnabled(false); if (oldItem.get()) { err = db->update(m_kindId, buf, oldItem.get(), txn); MojErrCheck(err); } else { err = db->insert(m_kindId, buf, txn); MojErrCheck(err); // get old item so we can update it next time err = db->get(m_kindId, txn, false, oldItem); MojErrCheck(err); } txn->quotaEnabled(true); return MojErrNone; }
void MojSlotBase::disconnect() { MojAssertMutexLocked(m_signal->m_mutex); MojAssert(m_connected); m_connected = false; handler()->release(); }
MojErr MojService::addRequest(MojServiceRequest* req) { MojAssert(req); MojAssertMutexLocked(m_mutex); MojLogTrace(s_log); MojErr err = m_requests.put(req->token(), req); MojErrCheck(err); return MojErrNone; }
void MojLogEngine::updateAppender(MojAutoPtr<MojLogAppender> appender) { MojAssertMutexLocked(m_mutex); if (appender.get()) { m_configuredAppender = appender; m_appender = m_configuredAppender.get(); } else { m_configuredAppender.reset(); m_appender = &m_defaultAppender; } }
MojErr MojDbWatcher::fireImpl() { MojAssertMutexLocked(m_mutex); MojErr err = invalidate(); MojErrCheck(err); err = m_signal.fire(); MojErrCatchAll(err); MojLogDebug(MojDb::s_log, _T("Watcher_fired!!: err = %d; state= %d; index name = %s; domain = %s\n"), (int)err, (int)m_state, ((m_index) ? m_index->name().data() : NULL), ((m_domain) ? m_domain.data() : NULL)); return MojErrNone; }
MojErr MojDbKindState::initKindToken(MojDbReq& req) { MojAssertMutexLocked(m_lock); // load tokens MojObject token; bool created = false; MojErr err = id(m_kindId, KindTokensKey, req, token, created); MojErrCheck(err); m_kindToken = token.intValue(); return MojErrNone; }
MojErr MojDbKindState::initTokens(MojDbReq& req, const StringSet& strings) { // TODO: bug inside this function. (latest strace step) MojAssertMutexLocked(m_lock); // TODO: filing load tokens. Go inside readObj // load tokens MojErr err = readObj(TokensKey, m_tokensObj, m_kindEngine->kindDb(), req.txn(), m_oldTokensItem); MojErrCheck(err); // populate token vec MojUInt8 maxToken = 0; err = m_tokenVec.resize(m_tokensObj.size()); MojErrCheck(err); for (MojObject::ConstIterator i = m_tokensObj.begin(); i != m_tokensObj.end(); ++i) { MojString key = i.key(); MojInt64 value = i.value().intValue(); MojSize idx = (MojSize) (value - MojObjectWriter::TokenStartMarker); if (value < MojObjectWriter::TokenStartMarker || value >= MojUInt8Max || idx >= m_tokenVec.size()) { MojErrThrow(MojErrDbInvalidToken); } if (value > maxToken) { maxToken = (MojUInt8) value; } err = m_tokenVec.setAt(idx, key); MojErrCheck(err); } if (maxToken > 0) { m_nextToken = (MojUInt8) (maxToken + 1); } // add strings bool updated = false; for (StringSet::ConstIterator i = strings.begin(); i != strings.end(); ++i) { if (!m_tokensObj.contains(*i)) { updated = true; MojUInt8 token = 0; TokenVec tokenVec; MojObject tokenObj; err = addPropImpl(*i, false, token, tokenVec, tokenObj); MojErrCheck(err); } } if (updated) { err = writeTokens(m_tokensObj); MojErrCheck(err); } return MojErrNone; }
MojErr MojDbKindState::writeTokens(const MojObject& tokensObj) { MojAssert(m_kindEngine); MojAssertMutexLocked(m_lock); MojDbStorageDatabase* db = m_kindEngine->kindDb(); MojRefCountedPtr<MojDbStorageTxn> txn; MojErr err = db->beginTxn(txn); MojErrCheck(err); MojAssert(txn.get()); err = writeObj(TokensKey, tokensObj, db, txn.get(), m_oldTokensItem); MojErrCheck(err); err = txn->commit(); MojErrCheck(err); return MojErrNone; }
MojErr MojDbWatcher::invalidate() { MojAssertMutexLocked(m_mutex); MojAssert(m_index); MojAssert(m_state == StateActive); MojLogDebug(MojDb::s_log, _T("Watcher_invalidate: state= %d; index name = %s; domain = %s\n"), (int)m_state, ((m_index) ? m_index->name().data() : NULL),((m_domain) ? m_domain.data() : NULL)); // index always drops its mutex before firing, so // it's ok to hold our mutex while calling into index MojDbIndex* index = m_index; m_index = NULL; m_state = StateInvalid; MojErr err = index->cancelWatch(this); MojErrCheck(err); return MojErrNone; }
MojErr MojDbKindState::addPropImpl(const MojChar* propName, bool write, MojUInt8& tokenOut, TokenVec& vecOut, MojObject& tokenObjOut) { MojAssert(propName); MojAssertMutexLocked(m_lock); tokenOut = MojTokenSet::InvalidToken; // check if we've already added the prop MojUInt32 token; bool found = false; MojErr err = m_tokensObj.get(propName, token, found); MojErrCheck(err); if (found) { MojAssert(token <= MojUInt8Max); tokenOut = (MojUInt8) token; return MojErrNone; } // update the db and our in-memory state if (m_nextToken < MojUInt8Max) { // update copies of obj and vec MojObject obj(m_tokensObj); TokenVec tokenVec(m_tokenVec); MojString prop; err = prop.assign(propName); MojErrCheck(err); err = tokenVec.push(prop); MojErrCheck(err); err = obj.put(propName, m_nextToken); MojErrCheck(err); // write object if (write) { err = writeTokens(obj); MojErrCheck(err); } // update state and return values m_tokensObj = obj; m_tokenVec.swap(tokenVec); tokenOut = m_nextToken++; vecOut = m_tokenVec; tokenObjOut = m_tokensObj; } return MojErrNone; }
MojErr MojLunaService::sendImpl(MojServiceRequest* req, const MojChar* service, const MojChar* method, Token& tokenOut) { LOG_TRACE("Entering function %s", __FUNCTION__); MojAssert(req && service && method); MojAssert(m_service || m_handle); MojAssertMutexLocked(m_mutex); MojLunaRequest* lunaReq = static_cast<MojLunaRequest*>(req); const MojChar* json = lunaReq->payload(); LOG_DEBUG("[db_lunaService] request sent: %s", json); MojString uri; MojErr err = uri.format(_T("%s://%s/%s"), UriScheme, service, method); MojErrCheck(err); MojLunaErr lserr; LSMessageToken lsToken; LSHandle* handle = getHandle(lunaReq->onPublic()); if (req->numRepliesExpected() > 1) { if (!lunaReq->isProxyRequest()) { bool retVal = LSCall(handle, uri, json, &handleResponse, this, &lsToken, lserr); MojLsErrCheck(retVal, lserr); } else { bool retVal = LSCallFromApplication(handle, uri, json, lunaReq->getRequester(), &handleResponse, this, &lsToken, lserr); MojLsErrCheck(retVal, lserr); } } else { if (!lunaReq->isProxyRequest()) { bool retVal = LSCallOneReply(handle, uri, json, &handleResponse, this, &lsToken, lserr); MojLsErrCheck(retVal, lserr); } else { bool retVal = LSCallFromApplicationOneReply(handle, uri, json, lunaReq->getRequester(), &handleResponse, this, &lsToken, lserr); MojLsErrCheck(retVal, lserr); } } tokenOut = (Token) lsToken; return MojErrNone; }