示例#1
0
MojErr MojService::dispatchReply(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	// parse payload
	MojObjectBuilder builder;
	MojObject payload;
	MojErr err = MojErrNone;
	MojInt64 errCode = MojErrNone;
	errCode = err = msg->payload(builder);
	MojErrCatchAll(err);
	if (errCode == MojErrNone)
		payload = builder.object();

	// get errCode
	bool retVal = false;
	if (payload.get(MojServiceMessage::ReturnValueKey, retVal) && !retVal) {
		if (!payload.get(MojServiceMessage::ErrorCodeKey, errCode))
			errCode = MojErrUnknown;
	}
	// find request
	MojRefCountedPtr<MojServiceRequest> req;
	err = getRequest(msg, req);
	MojErrCheck(err);

	// do the dispatch
	err = dispatchReplyImpl(req.get(), msg, payload, (MojErr) errCode);
	MojErrCatchAll(err);

	return MojErrNone;
}
示例#2
0
MojErr MojLunaService::dispatchReplyImpl(MojServiceRequest* req, MojServiceMessage *msg, MojObject& payload, MojErr errCode)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(req);
	MojAssertMutexUnlocked(m_mutex);

	// don't automatically cancel a subscription if the payload has "subscribed":true
	bool subscribed = false;
	payload.get(_T("subscribed"), subscribed);

	// remove if there are more responses coming. due to the vagaries of the luna-service protocol,
	// we never really know for sure, but this is a good guess.
	bool remove = (req->numReplies() + 1 >= req->numRepliesExpected()) || (errCode != MojErrNone && !subscribed);
	MojErr err = req->dispatchReply(msg, payload, errCode);
	MojErrCatchAll(err) {
		remove = true;
	}
	if (remove) {
		if (req->numRepliesExpected() == 1) {
			bool found = false;
			err = removeRequest(req, found);
			MojErrCheck(err);
		} else {
			err = cancel(req);
			MojErrCheck(err);
		}
	}
	return MojErrNone;
}
示例#3
0
// Note: this is a blocking interface exclusively for unit tests.
// It will not deliver cancel callbacks if clients drop off the bus.
MojErr MojLunaService::dispatch()
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssertMutexUnlocked(m_mutex);

	MojAssert(m_loop);
	GMainContext* context = g_main_loop_get_context(m_loop);
	g_main_context_iteration(context, true);

	return MojErrNone;
}
示例#4
0
MojErr MojService::removeRequest(MojServiceRequest* req, bool& foundOut)
{
	MojAssert(req);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);
	MojThreadGuard guard(m_mutex);

	MojErr err = m_requests.del(req->token(), foundOut);
	MojErrCheck(err);

	return MojErrNone;
}
示例#5
0
MojErr MojService::getRequest(MojServiceMessage* msg, MojRefCountedPtr<MojServiceRequest>& reqOut)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);
	MojThreadGuard guard(m_mutex);

	if (!m_requests.get(msg->token(), reqOut)) {
		MojErrThrow(MojErrResponseHandlerNotFound);
	}
	return MojErrNone;
}
示例#6
0
MojErr MojLunaService::addCategory(const MojChar* name, CategoryHandler* handler)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(name && handler);
	MojAssertMutexUnlocked(m_mutex);
	MojThreadGuard guard(m_mutex);

	// create array of LSMethods
	MethodVec pubMethods;
	MethodVec privMethods;
	const CategoryHandler::CallbackMap& callbacks = handler->callbacks();
	for (CategoryHandler::CallbackMap::ConstIterator i = callbacks.begin();
		 i != callbacks.end();
		 i++) {
			LSMethod m = {i.key(), &handleRequest};

			MethodVec& methods = i->m_pub ? pubMethods : privMethods;
			MojErr err = methods.push(m);
			MojErrCheck(err);
	}
    LSMethod nullMethod = {NULL, NULL};
    MojErr err = pubMethods.push(nullMethod);
    MojErrCheck(err);
    err = privMethods.push(nullMethod);
    MojErrCheck(err);

    // create category object to hang on to method array
	MojRefCountedPtr<LunaCategory> cat(new LunaCategory(this, handler, pubMethods, privMethods));
	MojAllocCheck(cat.get());
	LSMethod* pubLsMethods = const_cast<LSMethod*>(cat->m_pubMethods.begin());
	LSMethod* privLsMethods = const_cast<LSMethod*>(cat->m_privMethods.begin());

	MojLunaErr lserr;
    bool retVal;
    if (m_service) {
    	retVal = LSPalmServiceRegisterCategory(m_service, name, pubLsMethods, privLsMethods, NULL, cat.get(), lserr);
    	MojLsErrCheck(retVal, lserr);
    } else {
    	MojAssert(m_handle);
    	retVal = LSRegisterCategory(m_handle, name, privLsMethods, NULL, NULL, lserr);
    	MojLsErrCheck(retVal, lserr);
        retVal = LSCategorySetData(m_handle, name, cat.get(), lserr);
        MojLsErrCheck(retVal, lserr);
    }

	MojString categoryStr;
	err = categoryStr.assign(name);
	MojErrCheck(err);
	err = m_categories.put(categoryStr, cat);
	MojErrCheck(err);

	return MojErrNone;
}
示例#7
0
MojErr MojService::getCategory(const MojChar* name, MojRefCountedPtr<Category>& catOut)
{
	MojAssert(name);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);
	MojThreadGuard guard(m_mutex);

	if (!m_categories.get(name, catOut)) {
		MojErrThrow(MojErrCategoryNotFound);
	}
	return MojErrNone;
}
示例#8
0
MojErr MojService::enableSubscription(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	MojErr err = addSubscription(msg);
	MojErrCheck(err);
	err = enableSubscriptionImpl(msg);
	MojErrCheck(err);

	return MojErrNone;
}
示例#9
0
MojErr MojService::dispatchCancel(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	SubscriptionKey key;
	MojErr err = key.init(msg);
	MojErrCheck(err);
	err = dispatchCancel(key);
	MojErrCheck(err);

	return MojErrNone;
}
示例#10
0
MojErr MojService::cancel(MojServiceRequest* req)
{
	MojAssert(req);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	bool found = false;
	MojErr err = removeRequest(req, found);
	MojErrCheck(err);
	if (found) {
		err = cancelImpl(req);
		MojErrCheck(err);
	}
	return MojErrNone;
}
示例#11
0
MojErr MojService::dispatchCancel(const SubscriptionKey& key)
{
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);
	MojThreadGuard guard(m_mutex);

	SubscriptionMap::ConstIterator i = m_subscriptions.find(key);
	if (i != m_subscriptions.end()) {
		MojRefCountedPtr<MojServiceMessage> msg = *i;
		guard.unlock();

		MojErr err = msg->dispatchCancel();
		MojErrCatchAll(err);
	}
	return MojErrNone;
}
示例#12
0
MojErr MojService::send(MojServiceRequest* req, const MojChar* service, const MojChar* method, Token& tokenOut)
{
	MojAssert(req && service && method);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	// NOV-130089: sendImpl and addReqest must be atomic
	MojThreadGuard guard(m_mutex);

	MojErr err = sendImpl(req, service, method, tokenOut);
	MojErrCheck(err);
	err = addRequest(req);
	MojErrCheck(err);

	return MojErrNone;
}
示例#13
0
MojErr MojService::addSubscription(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	SubscriptionKey key;
	MojErr err = key.init(msg);
	MojErrCheck(err);

	MojThreadGuard guard(m_mutex);
	MojAssert(!m_subscriptions.contains(key));
	err = m_subscriptions.put(key, msg);
	MojErrCheck(err);

	return MojErrNone;
}
示例#14
0
MojErr MojLunaService::enableSubscriptionImpl(MojServiceMessage* msg)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(msg);
	MojAssertMutexUnlocked(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());
    bool retVal = LSSubscriptionAdd(handle, token, lsMessage->impl(), lserr);
    MojLsErrCheck(retVal, lserr);

    return MojErrNone;
}
示例#15
0
MojErr MojLunaService::cancelImpl(MojServiceRequest* req)
{
    LOG_TRACE("Entering function %s", __FUNCTION__);
	MojAssert(req);
	MojAssert(m_service || m_handle);
	MojAssertMutexUnlocked(m_mutex);

	MojLunaRequest* lunaReq = static_cast<MojLunaRequest*>(req);
	if (req->numRepliesExpected() > 1 && !lunaReq->cancelled()) {
		LSMessageToken lsToken = (LSMessageToken) req->token();
		MojAssert(lsToken != LSMESSAGE_TOKEN_INVALID);
		MojLunaErr lserr;
		LSHandle* handle = getHandle(lunaReq->onPublic());
		bool cancelled = LSCallCancel(handle, lsToken, lserr);
		MojLsErrCheck(cancelled, lserr);
		lunaReq->cancelled(true);
	}
	return MojErrNone;
}
示例#16
0
MojErr MojService::removeSubscription(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	SubscriptionKey key;
	MojErr err = key.init(msg);
	MojErrCheck(err);

	MojThreadGuard guard(m_mutex);
	bool found = false;
	err = m_subscriptions.del(key, found);
	MojErrCheck(err);
	MojAssert(found);
	err = removeSubscriptionImpl(msg);
	MojErrCheck(err);

	return MojErrNone;
}
示例#17
0
MojErr MojService::dispatchRequest(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	// get payload
	MojObject payload;
	MojErr reqErr;
	MojErr err = reqErr = msg->payload(payload);
	MojErrCatchAll(err) {
		return msg->replyError(reqErr);
	}
	// get callback
	Category* category = msg->serviceCategory();
	MojAssert(category);
	MojAssert(category && category->m_service == this);
	// invoke
	err = reqErr = category->m_handler->invoke(msg->method(), msg, payload);
	MojErrCatchAll(err) {
		MojString payloadStr;
		(void) payload.toJson(payloadStr);
		MojString errStr;
		(void) MojErrToString(reqErr, errStr);
		MojLogError(s_log, _T("%s (%d) - sender='%s' method='%s' payload='%s'"),
				errStr.data(), (int) reqErr, msg->senderName(), msg->method(), payloadStr.data());

		if (msg->numReplies() == 0) {
			return msg->replyError(reqErr);
		}
	}
	if (msg->numReplies() == 0 && msg->hasData()) {
		return msg->reply();
	}
	return MojErrNone;
}