void Message::setValue(const AutoAnyReference &value, const Signature& sig, ObjectHost* context, StreamContext* streamContext) { cow(); Signature effective = value.type()->signature(); if (effective != sig) { TypeInterface* ti = TypeInterface::fromSignature(sig); if (!ti) qiLogWarning() << "setValue(): cannot construct type for signature " << sig.toString(); std::pair<AnyReference, bool> conv = value.convert(ti); if (!conv.first.type()) { std::stringstream ss; ss << "Setvalue(): failed to convert effective value " << value.type()->signature().toString() << " to expected type " << sig.toString() << '(' << ti->infoString() << ')'; qiLogWarning() << ss.str(); setType(qi::Message::Type_Error); setError(ss.str()); } else encodeBinary(&_p->buffer, conv.first, boost::bind(serializeObject, _1, context), streamContext); if (conv.second) conv.first.destroy(); } else if (value.type()->kind() != qi::TypeKind_Void) { encodeBinary(&_p->buffer, value, boost::bind(serializeObject, _1, context), streamContext); } }
TEST(QiSession, multipleConnectSuccess) { qi::Session session, sd; sd.listenStandalone("tcp://127.0.0.1:0"); qiLogVerbose() <<"connect"; qi::Future<void> f = session.connect(sd.url()); qiLogVerbose() <<"wait"; f.wait(); if (f.hasError()) qiLogWarning() << f.error(); EXPECT_FALSE(f.hasError()); qiLogVerbose() <<"close"; session.close(); qiLogVerbose() <<"connect"; f = session.connect(sd.url()); qiLogVerbose() <<"wait"; f.wait(); if (f.hasError()) qiLogWarning() << f.error(); EXPECT_FALSE(f.hasError()); qiLogVerbose() <<"close"; session.close(); qiLogVerbose() <<"connect"; f = session.connect(sd.url()); qiLogVerbose() <<"wait"; f.wait(); if (f.hasError()) qiLogWarning() << f.error(); EXPECT_FALSE(f.hasError()); qiLogVerbose() <<"close"; session.close(); }
TailFileLogHandler::TailFileLogHandler(const std::string& filePath) : _private(new PrivateTailFileLogHandler) { _private->_file = NULL; _private->_writeSize = 0; _private->_fileName = filePath; boost::filesystem::path fPath(_private->_fileName); // Create the directory! try { if (!boost::filesystem::exists(fPath.make_preferred().parent_path())) boost::filesystem::create_directories(fPath.make_preferred().parent_path()); } catch (boost::filesystem::filesystem_error &e) { qiLogWarning("qi.log.tailfileloghandler") << e.what() << std::endl; } // Open the file. FILE* file = qi::os::fopen(fPath.make_preferred().string().c_str(), "w+"); if (file) _private->_file = file; else qiLogWarning("qi.log.tailfileloghandler") << "Cannot open " << filePath << std::endl; }
void RemoteObject::onFutureCancelled(unsigned int originalMessageId) { qiLogDebug() << "Cancel request for message " << originalMessageId; TransportSocketPtr sock; { boost::mutex::scoped_lock lock(_socketMutex); sock = _socket; } Message cancelMessage; if (!sock) { qiLogWarning() << "Tried to cancel a call, but the socket to service " << _service << " is disconnected."; return; } if (!sock->sharedCapability<bool>("RemoteCancelableCalls", false)) { qiLogWarning() << "Remote end does not support cancelable calls."; return; } cancelMessage.setService(_service); cancelMessage.setType(Message::Type_Cancel); cancelMessage.setValue(AnyReference::from(originalMessageId), "I"); cancelMessage.setObject(_object); sock->send(cancelMessage); }
std::string Translator::translate(const std::string &msg, const std::string &domain, const std::string &locale, const std::string &context) { boost::mutex::scoped_lock l(_p->mutex); if (_p->currentDomain.empty() && domain.empty()) { qiLogWarning() << "You must call setDefaultDomain first!"; return msg; } std::string loc; if (locale.empty()) { if (_p->currentLocale.empty()) { qiLogWarning() << "You must call setDefaultLocale first!"; return msg; } else { loc = _p->currentLocale; } } else { loc = locale; } std::string dom; if (domain.empty()) { if (_p->currentDomain.empty()) { qiLogWarning() << "You must call setDefaultDomain first!"; return msg; } else { dom = _p->currentDomain; } } else { _p->generator.add_messages_domain(domain); dom = domain; } if (loc.find(".UTF-8") == std::string::npos) loc += ".UTF-8"; if (domain.empty()) return boost::locale::translate(context, msg).str(_p->generator(loc)); else return boost::locale::translate(context, msg).str(_p->generator(loc), dom); }
/** * Function used to run behaviors that should attract child's attention */ void attractAttention(std::string action) { if(action=="Sound") { qiLogWarning("Logger") << "Attracting attention with sound" << std::endl; } else if(action=="LEDs") { qiLogWarning("Logger") << "Attracting attention with LEDs" << std::endl; } else if(action=="Motion") { qiLogWarning("Logger") << "Attracting attention with motion" << std::endl; } }
void ServiceDirectory::onSocketDisconnected(TransportSocketPtr socket, std::string error) { boost::recursive_mutex::scoped_lock lock(mutex); // clean from idxToSocket for (std::map<unsigned int, TransportSocketPtr>::iterator it = idxToSocket.begin(), iend = idxToSocket.end(); it != iend;) { std::map<unsigned int, TransportSocketPtr>::iterator next = it; ++next; if (it->second == socket) idxToSocket.erase(it); it = next; } // if services were connected behind the socket std::map<TransportSocketPtr, std::vector<unsigned int> >::iterator it; it = socketToIdx.find(socket); if (it == socketToIdx.end()) { return; } // Copy the vector, iterators will be invalidated. std::vector<unsigned int> ids = it->second; // Always start at the beginning since we erase elements on unregisterService // and mess up the iterator for (std::vector<unsigned int>::iterator it2 = ids.begin(); it2 != ids.end(); ++it2) { qiLogInfo() << "Service #" << *it2 << " disconnected"; try { unregisterService(*it2); } catch (std::runtime_error &) { qiLogWarning() << "Cannot unregister service #" << *it2; } } socketToIdx.erase(it); }
TEST(TestStrand, AggressiveCancel) { boost::mutex mutex; std::vector<qi::Future<void> > futures; qi::Strand strand(*qi::getEventLoop()); boost::atomic<unsigned int> i(0); for (unsigned int j = 0; j < STRAND_NB_TRIES; ++j) { qi::Future<void> f1 = strand.async(boost::bind<void>(&increment, boost::ref(mutex), 1, boost::ref(i))); futures.push_back(f1); f1 = strand.async(boost::bind<void>(&increment, boost::ref(mutex), 50, boost::ref(i))); futures.push_back(f1); } BOOST_FOREACH(qi::Future<void>& future, futures) future.cancel(); unsigned int successCount = 0; BOOST_FOREACH(qi::Future<void>& future, futures) { if (future.wait() != qi::FutureState_Canceled) successCount++; } if (i == futures.size() || i == 0) qiLogWarning() << "i = " << i << ", this test is meaningless, you should do something about that"; ASSERT_EQ(successCount, i); }
Signature SignalSubscriber::signature() const { if (handler) { if (handler.functionType() == dynamicFunctionTypeInterface()) return Signature(); // no arity checking is possible else return handler.parametersSignature(); } else if (target) { AnyObject locked = target->lock(); if (!locked) return Signature(); const MetaMethod* ms = locked.metaObject().method(method); if (!ms) { qiLogWarning() << "Method " << method <<" not found."; return Signature(); } else return ms->parametersSignature(); } else return Signature(); }
bool ParameterModel::addChoice(ChoiceModelPtr choice) { qiLogDebug() << "addChoice function" << std::endl; Signature signature(_p->_metaProperty.signature()); //if false choice and parameter are the same type if(Signature(choice->value().signature()).isConvertibleTo(signature) < 1.0f ) { qiLogWarning() << "choice.type (i.e " << choice->value().signature().toString() << ") != parameter.type (i.e " << _p->_defaultValue.signature().toString() <<")" << std::endl; return false; } //If choice.value is not in [parameter.min, paramater.max] then the choice //is incorrect if(!_p->inInterval(choice->value(), _p->_min, _p->_max) ) { qiLogInfo() << "Choice : is not in interval" << std::endl; return false; } _p->_choices.push_front(choice); return true; }
/* * Returns the last socket that sent a message to this object. * Considering the volatility of this operation, Users of currentSocket() * must set _callType to Direct, otherwise behavior is undefined. Calling * currentSocket multiple times in a row in the same context should be * avoided: call it once and use the return value, unless you know what * you're doing. */ inline qi::TransportSocketPtr currentSocket() const { #ifndef NDEBUG if (_callType != MetaCallType_Direct) qiLogWarning("qimessaging.boundobject") << " currentSocket() used but callType is not direct"; #endif boost::recursive_mutex::scoped_lock lock(_mutex); return _currentSocket; }
Location makeLocation(const yy::location& loc) { if (loc.begin.filename) return Location(loc.begin.line, loc.begin.column, loc.end.line, loc.end.column, *loc.begin.filename); else { qiLogWarning() << "missing filename for location"; return Location(loc.begin.line, loc.begin.column, loc.end.line, loc.end.column); } }
qi::Future<void> RemoteObject::metaDisconnect(SignalLink linkId) { unsigned int event = linkId >> 32; //disconnect locally qi::Future<void> fut = DynamicObject::metaDisconnect(linkId); if (fut.hasError()) { std::stringstream ss; ss << "Disconnection failure for " << linkId << ", error:" << fut.error(); qiLogWarning() << ss.str(); return qi::makeFutureError<void>(ss.str()); } boost::recursive_mutex::scoped_lock _lock(_localToRemoteSignalLinkMutex); LocalToRemoteSignalLinkMap::iterator it; it = _localToRemoteSignalLink.find(event); if (it == _localToRemoteSignalLink.end()) { qiLogWarning() << "Cant find " << event << " in the localtoremote signal map"; return fut; } qi::SignalLink toDisco = qi::SignalBase::invalidSignalLink; { RemoteSignalLinks &rsl = it->second; std::vector<SignalLink>::iterator vslit; vslit = std::find(rsl.localSignalLink.begin(), rsl.localSignalLink.end(), linkId); if (vslit != rsl.localSignalLink.end()) { rsl.localSignalLink.erase(vslit); } else { qiLogWarning() << "Cant find " << linkId << " in the remote signal vector (event:" << event << ")"; } //only drop the remote connection when no more local connection are registered if (rsl.localSignalLink.size() == 0) { toDisco = rsl.remoteSignalLink; _localToRemoteSignalLink.erase(it); } } if (toDisco != qi::SignalBase::invalidSignalLink) { TransportSocketPtr sock = _socket; if (sock && sock->isConnected()) return _self.async<void>("unregisterEvent", _service, event, toDisco); } return fut; }
TranslatorPrivate(const std::string &name) { if (name.empty()) { qiLogWarning() << "You forget to set qi::Application name or to generate a translator with a name!"; } addDomainPath(name); }
AL::ALImage * getFrameBuffer() { // TODO: Mark access using mutex if (img) { qiLogWarning("FGrab") << "Concurrent access to the FGrab image buffer." << std::endl; } else { img = static_cast<AL::ALImage *>(cameraProxy->getDirectRawImageLocal(nameId)); } return img; }
void Message::setError(const std::string &error) { if (type() != Type_Error) { qiLogWarning() << "called setError on a non Type_Error message"; return; } // Error message is of type m (dynamic) AnyValue v(AnyReference::from(error), false, false); setValue(AnyReference::from(v), "m"); }
void TimelinePrivate::goTo(const std::string& pFrame) { qiLogDebug() << "goto timeline with : " << pFrame; std::map<std::string, int>::iterator iter = _framesFlagsMapRev.find(pFrame); if (iter == _framesFlagsMapRev.end()) { qiLogWarning() << "Unknown frame to go to: " << pFrame; return; } goTo(iter->second); }
TEST(QiSession, connectOnSecondAttempt) { qi::Session session; qi::Future<void> f = session.connect("tcp://127.0.0.1:1234"); f.wait(); EXPECT_TRUE(f.hasError()); qi::Session s2; s2.listenStandalone("tcp://127.0.0.1:0"); f = session.connect(s2.url()); f.wait(); if (f.hasError()) qiLogWarning() << f.error(); EXPECT_FALSE(f.hasError()); }
void operator() () { try { { SignalSubscriberPtr s; boost::mutex::scoped_lock sl((*sub)->mutex); // verify-enabled-then-register-active op must be locked if (!(*sub)->enabled) { s = *sub; // delay destruction until after we leave the scoped_lock delete sub; params->destroy(); delete params; return; } (*sub)->addActive(false); } // end mutex-protected scope (*sub)->handler(*params); } catch(const qi::PointerLockException&) { qiLogDebug() << "PointerLockFailure excepton, will disconnect"; } catch(const std::exception& e) { qiLogWarning() << "Exception caught from signal subscriber: " << e.what(); } catch (...) { qiLogWarning() << "Unknown exception caught from signal subscriber"; } (*sub)->removeActive(true); params->destroy(); delete params; delete sub; }
unsigned int ServiceDirectory::registerService(const ServiceInfo &svcinfo) { boost::shared_ptr<ServiceBoundObject> sbo = serviceBoundObject.lock(); if (!sbo) throw std::runtime_error("ServiceBoundObject has expired."); TransportSocketPtr socket = sbo->currentSocket(); boost::recursive_mutex::scoped_lock lock(mutex); std::map<std::string, unsigned int>::iterator it; it = nameToIdx.find(svcinfo.name()); if (it != nameToIdx.end()) { std::stringstream ss; ss << "Service \"" << svcinfo.name() << "\" (#" << it->second << ") is already registered. " << "Rejecting conflicting registration attempt."; qiLogWarning() << ss.str(); throw std::runtime_error(ss.str()); } unsigned int idx = ++servicesCount; nameToIdx[svcinfo.name()] = idx; // Do not add serviceDirectory on the map (socket() == null) if (idx != qi::Message::Service_ServiceDirectory) socketToIdx[socket].push_back(idx); pendingServices[idx] = svcinfo; pendingServices[idx].setServiceId(idx); idxToSocket[idx] = socket; std::stringstream ss; ss << "Registered Service \"" << svcinfo.name() << "\" (#" << idx << ")"; if (! svcinfo.name().empty() && svcinfo.name()[0] == '_') { // Hide services whose name starts with an underscore qiLogDebug() << ss.str(); } else { qiLogInfo() << ss.str(); } qi::UrlVector::const_iterator jt; for (jt = svcinfo.endpoints().begin(); jt != svcinfo.endpoints().end(); ++jt) { qiLogDebug() << "Service \"" << svcinfo.name() << "\" is now on " << jt->str(); } return idx; }
FileLogHandler::FileLogHandler(const std::string& filePath) : _p(new PrivateFileLogHandler) { _p->_file = NULL; boost::filesystem::path fPath(filePath); // Create the directory! try { if (!boost::filesystem::exists(fPath.make_preferred().parent_path())) boost::filesystem::create_directories(fPath.make_preferred().parent_path()); } catch (const boost::filesystem::filesystem_error& e) { qiLogWarning() << e.what(); } // Open the file. FILE* file = qi::os::fopen(fPath.make_preferred().string().c_str(), "w+"); if (file) _p->_file = file; else qiLogWarning() << "Cannot open " << filePath; }
static void updateDisconnectInfos(C& disconnectInfos, const MessageSocketPtr& socket) { // TODO: Replace `using` by `auto` in lambda when C++14 is available. using Value = typename C::value_type; const auto it = boost::find_if(disconnectInfos, [&](const Value& d) { return d.socket == socket; }); if (it == disconnectInfos.end()) { qiLogWarning() << "Disconnected socket not found in disconnect infos."; return; } auto promise = (*it).promiseSocketRemoved; disconnectInfos.erase(it); promise.setValue(0); }
inline void setState(qi::Atomic<int>& state, TaskState from, TaskState to, TaskState from2, TaskState to2) { for (unsigned i=0; i<1000; ++i) if (state.setIfEquals(from, to) || state.setIfEquals(from2, to2)) return; while (true) { for (unsigned i=0; i<1000; ++i) { if (state.setIfEquals(from, to) || state.setIfEquals(from2, to2)) return; qi::os::msleep(1); // TODO: 1ms is probably too long } qiLogWarning() << "PeriodicTask is stuck " << from << ' ' << to << ' ' << from2 << ' ' << to2 << ' '<< *state; } }
unsigned int MetaObjectPrivate::addProperty(const std::string& name, const qi::Signature& sig, int id) { boost::recursive_mutex::scoped_lock sl(_propertiesMutex); for (MetaObject::PropertyMap::iterator it = _properties.begin(); it != _properties.end(); ++it) { if (it->second.name() == name) { qiLogWarning() << "Property already exists: " << name; return it->second.uid() ; } } if (id == -1) id = ++_index; _properties[id] = MetaProperty(id, name, sig); _dirtyCache = true; return id; }
unsigned int MetaObjectPrivate::addMethod(MetaMethodBuilder& builder, int uid) { boost::recursive_mutex::scoped_lock sl(_methodsMutex); qi::MetaMethod method = builder.metaMethod(); NameToIdx::iterator it = _methodsNameToIdx.find(method.toString()); if (it != _methodsNameToIdx.end()) { qiLogWarning() << "Method("<< it->second << ") already defined (and overriden): " << method.toString(); return it->second; } if (uid == -1) uid = ++_index; builder.setUid(uid); _methods[uid] = builder.metaMethod(); _methodsNameToIdx[method.toString()] = uid; _dirtyCache = true; return uid; }
/* getMachineId will return an uuid as a string. * If the uuid is not created yet, it will generate it and store it * in machine_id file. * Otherwise it will read the file to retrieve the uuid and cache it * for further uses. * If the file is removed, a new file with a different uuid will be * created. */ std::string getMachineId() { static bool initialized = false; static std::string idString; if (initialized) return idString; static boost::mutex mutex; boost::mutex::scoped_lock lock(mutex); if (initialized) return idString; const qi::Path idFilePath(qi::path::userWritableConfPath("qimessaging", "machine_id")); boost::filesystem::ifstream idFile(idFilePath); if (idFile) { idFile >> idString; idFile.close(); initialized = true; if (!idString.empty()) { return idString; } //else machine id is empty... qiLogWarning() << "machine_id is empty, generating a new one"; } boost::filesystem::ofstream newIdFile(idFilePath); idString = generateUuid(); if (newIdFile) { newIdFile << idString; newIdFile.close(); initialized = true; } else { qiLogError() << "Unable to create file: '" << idFilePath << "'"; } return idString; }
unsigned int MetaObjectPrivate::addSignal(const std::string &name, const Signature &signature, int uid) { #ifndef NDEBUG std::vector<std::string> split = signatureSplit(name); if (name != split[1]) throw std::runtime_error("Unexpected full signature " + name); #endif boost::recursive_mutex::scoped_lock sl(_eventsMutex); NameToIdx::iterator it = _eventsNameToIdx.find(name); if (it != _eventsNameToIdx.end()) { MetaSignal &ms = _events[it->second]; qiLogWarning() << "Signal("<< it->second << ") already defined (and overriden): " << ms.toString() << "instead of requested: " << name; return it->second; } if (uid == -1) uid = ++_index; MetaSignal ms(uid, name, signature); _events[uid] = ms; _eventsNameToIdx[name] = uid; _dirtyCache = true; return uid; }
void SessionPrivate::addSdSocketToCache(Future<void> f, const qi::Url& url, qi::Promise<void> p) { qiLogDebug() << "addSocketToCache processing"; if (f.hasError()) { qiLogDebug() << "addSdSocketToCache: connect reported failure"; _serviceHandler.removeService("ServiceDirectory"); p.setError(f.error()); return; } // Allow the SD process to use the existing socket to talk to our services _serverObject.registerSocket(_sdClient.socket()); /* Allow reusing the SD socket for communicating with services. * To do this, we must add it to our socket cache, and for this we need * to know the sd machineId */ std::string mid; try { mid = _sdClient.machineId(); } catch (const std::exception& e) { // Provide a nice message for backward compatibility qiLogVerbose() << e.what(); qiLogWarning() << "Failed to obtain machineId, connection to service directory will not be reused for other services."; p.setValue(0); return; } TransportSocketPtr s = _sdClient.socket(); qiLogVerbose() << "Inserting sd to cache for " << mid <<" " << url.str() << std::endl; _socketsCache.insert(mid, s->remoteEndpoint(), s); p.setValue(0); }
// Find and open a library, and create an instance of a module in that library bool CreateModule(std::string libName, std::string moduleName, boost::shared_ptr<AL::ALBroker> broker, bool verb, bool find) { std::string library; if (find) { // Find the desired library if (verb) std::cout << bold_on << "Finding " << libName << "..." << bold_off << std::endl; library = qi::path::findLib(libName.c_str()); } else { // Use libName as library path library = libName; } // Open the library if(verb) std::cout << bold_on << "Loading " << library << "..." << bold_off << std::endl; void* handle = qi::os::dlopen(library.c_str()); if (!handle) { qiLogWarning(moduleName.c_str()) << "Could not load library:" << qi::os::dlerror() << std::endl; return -1; } // Load the create symbol if(verb) std::cout << bold_on << "Loading _createModule symbol..." << bold_off << std::endl; int(*createModule)(boost::shared_ptr<AL::ALBroker>) = (int(*)(boost::shared_ptr<AL::ALBroker>))(qi::os::dlsym(handle, "_createModule")); if (!createModule) { qiLogWarning(moduleName.c_str()) << "Could not load symbol _createModule: " << qi::os::dlerror() << std::endl; return -1; } // Check if module is already present if(verb) { std::cout << bold_on << "Module " << moduleName << " is "; if (!(broker->isModulePresent(moduleName))) { std::cout << "not "; } std::cout << "present" << bold_off << std::endl; } // Create an instance of the desired module if(verb) std::cout << bold_on << "Creating " << moduleName << " instance..." << bold_off << std::endl; createModule(broker); // Check for module creation if(verb) { std::cout << bold_on << "Module " << moduleName.c_str() << " is "; if (!(broker->isModulePresent(moduleName))) { std::cout << "not "; } std::cout << "present" << bold_off << std::endl; } if (broker->isModulePresent(moduleName)) return true; else return false; }
void SignalSubscriber::call(const GenericFunctionParameters& args, MetaCallType callType) { // this is held alive by caller if (handler) { bool async = true; if (threadingModel != MetaCallType_Auto) async = (threadingModel == MetaCallType_Queued); else if (callType != MetaCallType_Auto) async = (callType == MetaCallType_Queued); qiLogDebug() << "subscriber call async=" << async <<" ct " << callType <<" tm " << threadingModel; if (async) { GenericFunctionParameters* copy = new GenericFunctionParameters(args.copy()); // We will check enabled when we will be scheduled in the target // thread, and we hold this SignalSubscriber alive, so no need to // explicitly track the asynccall // courtesy-check of el, but it should be kept alive longuer than us qi::EventLoop* el = getEventLoop(); if (!el) // this is an assert basicaly, no sense trying to do something clever. throw std::runtime_error("Event loop was destroyed"); el->post(FunctorCall(copy, new SignalSubscriberPtr(shared_from_this()))); } else { // verify-enabled-then-register-active op must be locked { boost::mutex::scoped_lock sl(mutex); if (!enabled) return; addActive(false); } //do not throw bool mustDisconnect = false; try { handler(args); } catch(const qi::PointerLockException&) { qiLogDebug() << "PointerLockFailure excepton, will disconnect"; mustDisconnect = true; } catch(const std::exception& e) { qiLogWarning() << "Exception caught from signal subscriber: " << e.what(); } catch (...) { qiLogWarning() << "Unknown exception caught from signal subscriber"; } removeActive(true); if (mustDisconnect) source->disconnect(linkId); } } else if (target) { AnyObject lockedTarget = target->lock(); if (!lockedTarget) { source->disconnect(linkId); } else // no need to keep anything locked, whatever happens this is not used lockedTarget.metaPost(method, args); } }