void ServiceDirectoryClient::onSDEventConnected(qi::Future<SignalLink> future, qi::Promise<void> promise, bool isAdd) { if (promise.future().isFinished()) { return; } if (future.hasError()) { qi::Future<void> fdc = onSocketDisconnected(future.error()); fdc.connect(&qi::Promise<void>::setError, promise, future.error()); return; } bool ready = false; { boost::mutex::scoped_lock lock(_mutex); if (isAdd) _addSignalLink = future.value(); else _removeSignalLink = future.value(); ready = _addSignalLink && _removeSignalLink; } if (ready) { promise.setValue(0); connected(); } }
static void call_from_java_cont(qi::Future<qi::AnyReference> ret, qi::Promise<qi::AnyValue> promise) { if (ret.hasError()) promise.setError(ret.error()); else promise.setValue(qi::AnyValue(ret.value(), false, true)); }
void Session_Service::onTransportSocketResult(qi::Future<TransportSocketPtr> value, long requestId) { qiLogDebug() << "Got transport socket for service"; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (value.hasError()) { sr->promise.setError(value.error()); removeRequest(requestId); return; } } TransportSocketPtr socket = value.value(); // If true, this socket came from the socket cache and has already been identified. // This typically happens when two services are behind the same endpoint. // We forge a message that just shows we've authenticated successfully. if (socket->hasReceivedRemoteCapabilities()) { Message dummy; CapabilityMap cm; cm[AuthProvider::State_Key] = AnyValue::from(AuthProvider::State_Done); dummy.setType(Message::Type_Reply); dummy.setFunction(qi::Message::ServerFunction_Authenticate); dummy.setValue(AnyValue::from(cm), typeOf<CapabilityMap>()->signature()); onAuthentication(TransportSocket::SocketEventData(dummy), requestId, socket, ClientAuthenticatorPtr(new NullClientAuthenticator), SignalSubscriberPtr()); return; } ClientAuthenticatorPtr authenticator = _authFactory->newAuthenticator(); CapabilityMap authCaps; { CapabilityMap tmp = authenticator->initialAuthData(); for (CapabilityMap::iterator it = tmp.begin(), end = tmp.end(); it != end; ++it) authCaps[AuthProvider::UserAuthPrefix + it->first] = it->second; } SignalSubscriberPtr protSubscriber(new SignalSubscriber); *protSubscriber = socket->socketEvent.connect(&Session_Service::onAuthentication, this, _1, requestId, socket, authenticator, protSubscriber); Message msgCapabilities; msgCapabilities.setFunction(Message::ServerFunction_Authenticate); msgCapabilities.setService(Message::Service_Server); msgCapabilities.setType(Message::Type_Call); TransportSocketPtr sdSocket = _sdClient->socket(); CapabilityMap socketCaps; if (sdSocket) { socketCaps = sdSocket->localCapabilities(); socket->advertiseCapabilities(socketCaps); } socketCaps.insert(authCaps.begin(), authCaps.end()); msgCapabilities.setValue(socketCaps, typeOf<CapabilityMap>()->signature()); socket->send(msgCapabilities); }
void RemoteObject::onMetaObject(qi::Future<qi::MetaObject> fut, qi::Promise<void> prom) { if (fut.hasError()) { qiLogVerbose() << "MetaObject error: " << fut.error(); prom.setError(fut.error()); return; } qiLogVerbose() << "Fetched metaobject"; setMetaObject(fut.value()); prom.setValue(0); }
void ObjectRegistrar::onFutureFinished(qi::Future<unsigned int> fut, long id, qi::Promise<unsigned int> result) { if (fut.hasError()) { result.setError(fut.error()); return; } qi::ServiceInfo si; RegisterServiceMap::iterator it; { boost::mutex::scoped_lock sl(_registerServiceRequestMutex); it = _registerServiceRequest.find(id); if (it != _registerServiceRequest.end()) si = it->second.second; if (fut.hasError()) { _registerServiceRequest.erase(id); result.setError(fut.error()); return; } } unsigned int idx = fut.value(); si.setServiceId(idx); { boost::mutex::scoped_lock sl(_servicesMutex); BoundService bs; bs.id = idx; bs.object = it->second.first; bs.serviceInfo = si; bs.name = si.name(); BoundServiceMap::iterator it; it = _services.find(idx); if (it != _services.end()) { qiLogError() << "A service is already registered with that id:" << idx; result.setError("Service already registered."); return; } _services[idx] = bs; //todo register the object on the server (find a better way) Server::addObject(idx, bs.object); } { boost::mutex::scoped_lock sl(_serviceNameToIndexMutex); _serviceNameToIndex[si.name()] = idx; } { boost::mutex::scoped_lock sl(_registerServiceRequestMutex); _registerServiceRequest.erase(it); } // ack the Service directory to tell that we are ready qi::Future<void> fut2 = _sdClient->serviceReady(idx); fut2.connect(boost::bind(&serviceReady, _1, result, idx)); }
void Session_Service::onTransportSocketResult(qi::Future<TransportSocketPtr> value, long requestId) { qiLogDebug() << "Got transport socket for service"; qi::Future<void> fut; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (value.hasError()) { sr->promise.setError(value.error()); removeRequest(requestId); return; } sr->remoteObject = new qi::RemoteObject(sr->serviceId, value.value()); //ask the remoteObject to fetch the metaObject fut = sr->remoteObject->fetchMetaObject(); } fut.connect(&Session_Service::onRemoteObjectComplete, this, _1, requestId); }
// We received a ServiceInfo, and want to establish a connection void Session_Service::onServiceInfoResult(qi::Future<qi::ServiceInfo> result, long requestId, std::string protocol) { qiLogDebug() << "Got serviceinfo message"; { boost::recursive_mutex::scoped_lock sl(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (result.hasError()) { sr->promise.setError(result.error()); removeRequest(requestId); return; } const qi::ServiceInfo &si = result.value(); sr->serviceId = si.serviceId(); if (_sdClient->isLocal()) { // Wait! If sd is local, we necessarily have an open socket // on which service was registered, whose lifetime is bound // to the service TransportSocketPtr s = _sdClient->_socketOfService(sr->serviceId); if (!s) // weird qiLogVerbose() << "_socketOfService returned 0"; else { // check if the socket support that capability if (s->remoteCapability("ClientServerSocket", false)) { qiLogVerbose() << "sd is local and service is capable, going through socketOfService"; onTransportSocketResult(qi::Future<TransportSocketPtr>(s), requestId); return; } } } //empty serviceInfo if (!si.endpoints().size()) { std::stringstream ss; ss << "No endpoints returned for service:" << sr->name << " (id:" << sr->serviceId << ")"; qiLogVerbose() << ss.str(); sr->promise.setError(ss.str()); removeRequest(requestId); return; } if (protocol != "") { std::vector<qi::Url>::const_iterator it = si.endpoints().begin(); for (; it != si.endpoints().end() && it->protocol() != protocol; it++) { continue; } if (it == si.endpoints().end()) { std::stringstream ss; ss << "No " << protocol << " endpoint available for service:" << sr->name << " (id:" << sr->serviceId << ")"; qiLogVerbose() << ss.str(); sr->promise.setError(ss.str()); } } } qiLogDebug() << "Requesting socket from cache"; qi::Future<qi::TransportSocketPtr> fut = _socketCache->socket(result.value(), protocol); fut.connect(&Session_Service::onTransportSocketResult, this, _1, requestId); }
void onFutureFinished(qi::Future<std::string> future) { if (future.hasError()) gGlobalE = future.error(); else gGlobalS = future.value(); }
void onFutureFinished(qi::Future<int> future) { if (future.hasError()) gGlobalE = future.error(); else gGlobalI = future.value(); }
void consumer(qi::atomic<long> &gSuccess, qi::Future<int> fut) { //wont block thread on error ASSERT_TRUE(fut.wait(1000)); EXPECT_EQ(42, fut.value()); ++gSuccess; }