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(); } }
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::onRemoteObjectComplete(qi::Future<void> future, long requestId) { qiLogDebug() << "Got metaobject"; boost::recursive_mutex::scoped_lock l(_requestsMutex); ServiceRequest *sr = serviceRequest(requestId); if (!sr) return; if (future.hasError()) { sr->promise.setError(future.error()); removeRequest(requestId); return; } { boost::recursive_mutex::scoped_lock sl(_remoteObjectsMutex); RemoteObjectMap::iterator it = _remoteObjects.find(sr->name); if (it != _remoteObjects.end()) { //another object have been registered before us, return it //the new socket will be closed when the request is deleted qiLogVerbose() << "A request for the service " << sr->name << " have been discarded, " << "the remoteobject on the service was already available."; sr->promise.setValue(it->second); } else { AnyObject o = makeDynamicAnyObject(sr->remoteObject); //register the remote object in the cache addService(sr->name, o); sr->promise.setValue(o); sr->remoteObject = 0; } } removeRequest(requestId); }
void serviceReady(qi::Future<void> fut, qi::Promise<unsigned int> result, unsigned int idx) { if (fut.hasError()) { result.setError(fut.error()); return; } result.setValue(idx); }
static void onEventConnected(RemoteObject* ro, qi::Future<SignalLink> fut, qi::Promise<SignalLink> prom, SignalLink id) { if (fut.hasError()) { prom.setError(fut.error()); return; } prom.setValue(id); }
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 ServiceDirectoryClient::onMetaObjectFetched(qi::Future<void> future, qi::Promise<void> promise) { if (future.hasError()) { qi::Future<void> fdc = onSocketDisconnected(future.error()); fdc.connect(&qi::Promise<void>::setError, promise, future.error()); return; } boost::function<void (unsigned int, std::string)> f; f = boost::bind<void>(&ServiceDirectoryClient::onServiceAdded, this, _1, _2); qi::Future<SignalLink> fut1 = _object.connect("serviceAdded", f); f = boost::bind<void>(&ServiceDirectoryClient::onServiceRemoved, this, _1, _2); qi::Future<SignalLink> fut2 = _object.connect("serviceRemoved", f); fut1.connect(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, true); fut2.connect(&ServiceDirectoryClient::onSDEventConnected, this, _1, promise, false); }
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 SessionPrivate::listenStandaloneCont(qi::Promise<void> p, qi::Future<void> f) { if (f.hasError()) p.setError(f.error()); else { _sdClient.setServiceDirectory(boost::static_pointer_cast<ServiceBoundObject>(_sd._serviceBoundObject)->object()); // _sdClient will trigger its connected, which will trigger our connected p.setValue(0); } }
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(); }