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 onEventConnected(RemoteObject* ro, qi::Future<SignalLink> fut, qi::Promise<SignalLink> prom, SignalLink id) { if (fut.hasError()) { prom.setError(fut.error()); return; } prom.setValue(id); }
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 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 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 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); }
/** * \brief Adds the future to the barrier. * \return Whether the future could be added. * * \verbatim * This adds the future to the barrier. It means barrier's future won't return * until this one returns. It will also be added to the resulting vector. * * When :cpp:func:`qi::FutureBarrier::future()` has been called, this function * will throw. * \endverbatim */ void addFuture(qi::Future<T> fut) { // Can't add future from closed qi::FutureBarrier. if (*_p->_closed) throw std::runtime_error("Adding future to closed barrier"); ++(_p->_count); fut.connect(boost::bind<void>(&detail::FutureBarrierPrivate<T>::onFutureFinish, _p)); _p->_futures.push_back(fut); }
void PeriodicTaskPrivate::_trigger(qi::Future<void> future) { // if future was not canceled, the task already ran, don't retrigger if (!future.isCanceled()) return; // else, start the task now if we are still triggering if (_state.setIfEquals(Task_Triggering, Task_Rescheduling)) _reschedule(0); }
void slowDisconnect(qi::Promise<void> ready, qi::Promise<void> done, qi::Future<void> wait, qi::AnyObject obj, boost::shared_ptr<qi::SignalLink> link) { ready.setValue(0); wait.wait(); try { obj.disconnect(*link); } catch (...) {} done.setValue(0); }
void PeriodicTaskPrivate::_reschedule(qi::Duration delay) { qiLogDebug() << "rescheduling in " << qi::to_string(delay); if (_scheduleCallback) _task = _scheduleCallback(boost::bind(&PeriodicTaskPrivate::_wrap, shared_from_this()), delay); else _task = getEventLoop()->asyncDelay(boost::bind(&PeriodicTaskPrivate::_wrap, shared_from_this()), delay); _state = TaskState::Scheduled; _task.connect(boost::bind( &PeriodicTaskPrivate::_onTaskFinished, shared_from_this(), _1)); }
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); }
void PeriodicTaskPrivate::_onTaskFinished(const qi::Future<void>& fut) { if (fut.isCanceled()) { qiLogDebug() << "run canceled"; boost::mutex::scoped_lock l(_mutex); if (_state == TaskState::Stopping) _state = TaskState::Stopped; else if (_state == TaskState::Triggering) _state = TaskState::TriggerReady; else { QI_ASSERT(false && "state is not stopping nor triggering"); } _cond.notify_all(); } }
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(); }
// 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 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; }