Exemplo n.º 1
0
void StrandPrivate::enqueue(boost::shared_ptr<Callback> cbStruct)
{
  qiLogDebug() << "Enqueueing job id " << cbStruct->id;
  bool shouldschedule = false;

  {
    boost::mutex::scoped_lock lock(_mutex);
    // the callback may have been canceled
    if (cbStruct->state == State_None)
    {
      _queue.push_back(cbStruct);
      cbStruct->state = State_Scheduled;
    }
    else
      qiLogDebug() << "Job is not schedulable, state " << (int)cbStruct->state;
    // if process was not scheduled yet, do it, there is work to do
    if (!_processing)
    {
      _processing = true;
      shouldschedule = true;
    }
  }

  if (shouldschedule)
  {
    qiLogDebug() << "StrandPrivate::process was not scheduled, doing it";
    _eventLoop.async(boost::bind(&StrandPrivate::process, shared_from_this()),
        qi::Duration(0));
  }
}
Exemplo n.º 2
0
 // Find out our async parent and add to it
 static bool insertAsyncParentTrace(CallList& l, CallData* d)
 {
   if (l.empty())
   {
     qiLogDebug() << "empty";
     return false;
   }
   qiLogDebug() << l.front()->tStart;
   // Get first entry that started after our post time.
   CallList::iterator it = std::upper_bound(l.begin(), l.end(), CallTime(d->tPost));
   if (it == l.begin())
   { // damm, first element is older than us
     qiLogInfo() << "No async parent can be found";
     return false;
   }
   --it;
   qiLogDebug() << "Child check";
   // try if a sync child is better placed than it
   bool wasInserted = insertAsyncParentTrace((*it)->children, d);
   if (wasInserted)
     return true;
   // was not inserted in children, insert here
   (*it)->asyncChildren.push_back(d);
   d->asyncParent = *it;
   return true;
 }
Exemplo n.º 3
0
  void RemoteObject::close(const std::string& reason, bool fromSignal)
  {
    qiLogDebug() << "Closing remote object";
    TransportSocketPtr socket;
    {
       boost::mutex::scoped_lock lock(_socketMutex);
       socket = _socket;
       _socket.reset();
    }
    if (socket)
    { // Do not hold any lock when invoking signals.
        qiLogDebug() << "Removing connection from socket " << (void*)socket.get();
        socket->messagePendingDisconnect(_service, TransportSocket::ALL_OBJECTS, _linkMessageDispatcher);
        if (!fromSignal)
          socket->disconnected.disconnect(_linkDisconnected);
    }
    std::map<int, qi::Promise<AnyReference> > promises;
    {
      boost::mutex::scoped_lock lock(_promisesMutex);
      promises = _promises;
      _promises.clear();
    }
    // Nobody should be able to add anything to promises at this point.
    std::map<int, qi::Promise<AnyReference> >::iterator it;
    for (it = promises.begin(); it != promises.end(); ++it)
    {
      qiLogVerbose() << "Reporting error for request " << it->first << "(" << reason << ")";
      it->second.setError(reason);
    }

    //@warning: remove connection are not removed
    //          not very important ATM, because RemoteObject
    //          cant be reconnected
  }
Exemplo n.º 4
0
TEST(Proxy, Property)
{
  boost::shared_ptr<Bar> bar(new Bar);
  qi::AnyObject gbar = qi::AnyReference::from(bar).toObject();
  ASSERT_TRUE(!!gbar);
  // The session must die before bar.
  TestSessionPair p;
  p.server()->registerService("bar", gbar);
  // we need that to force two clients
  p.server()->registerService("bar2", gbar);
  qi::AnyObject client = p.client()->service("bar");
  ASSERT_EQ(0, client.call<int>("sum"));

  qi::ProxyProperty<int> pp(client, "prop");
  bar->set(1);
  ASSERT_EQ(1, pp.get());
  pp.set(2);
  ASSERT_EQ(2, bar->get());
  // althoug PropertyProxy::set is itself synchronous, notify on remote end
  // may be asynchronous, so subscribe below may come too soon and catch
  // the pp.set above
  qi::os::msleep(100);
  qiLogDebug() << "subscribe";
  bar->subscribe();
  qi::os::msleep(100);
  qiLogDebug() << "set 3";
  pp.set(3);
  // this is an event, all notify are asychronous
  PERSIST_ASSERT(, bar->sum() == 3, 500);

  Bar bar2;
  qi::SignalLink l = pp.connect(boost::bind(&Bar::onProp, &bar2, _1));
  bar->set(4);
  // this one is async (remote notify of local property set)
  PERSIST_ASSERT(, bar2.sum() == 4, 500);
  pp.disconnect(l);
  bar->set(5); // we expect an async op *not* to happen, no choice but wait.
  qi::os::msleep(200);
  ASSERT_EQ(4, bar2.sum());
  // reconnect to see if disconnect did not break anything
  l = pp.connect(boost::bind(&Bar::onProp, &bar2, _1));
  bar->set(4);
  PERSIST_ASSERT(, bar2.sum() == 8, 500);

  // proxy-proxy
  qi::AnyObject client2 = p.client()->service("bar2");
  qi::ProxyProperty<int> pp2(client2, "prop");
  Bar bar3;
  pp2.connect(boost::bind(&Bar::onProp, &bar3, _1));
  qiLogDebug() << "set 2";
  pp.set(2);
  PERSIST(, bar3.sum() == 2, 1000);
  ASSERT_EQ(2, bar3.sum());
  PERSIST(, bar2.sum() == 10, 500);
  ASSERT_EQ(10, bar2.sum());
  qiLogDebug() << "set 3";
  pp2.set(3);
  PERSIST_ASSERT(, bar2.sum() == 13, 500);
  PERSIST_ASSERT(, bar3.sum() == 5, 500);
}
TEST(QiSession, GettingServiceWhileDisconnecting)
{
  qi::SessionPtr server = qi::makeSession();
  server->listenStandalone("tcp://0.0.0.0:0");

  qi::DynamicObjectBuilder builder;
  qi::AnyObject object(builder.object());

  std::string serviceName = "sarace";
  server->registerService(serviceName, object);

  qi::SessionPtr client = qi::makeSession();

  for(int i = 0; i < 1000; ++i)
  {
    client->connect(server->endpoints()[0]);
    qi::Future<void> closing = client->close().async();
    try
    {
      qi::AnyObject remoteObject = client->service(serviceName);
      bool remoteObjectWasFound = remoteObject;
      ASSERT_TRUE(remoteObjectWasFound);
    }
    catch(const qi::FutureException& e)
    {
      qiLogDebug() << "Got expected error: " << e.what();
    }
    catch(const std::exception& e)
    {
      qiLogDebug() << "Got standard error: " << e.what();
    }
    closing.wait();
  }
}
Exemplo n.º 6
0
  qi::Future<SignalLink> RemoteObject::metaConnect(unsigned int event, const SignalSubscriber& sub)
  {
    qi::Promise<SignalLink> prom(qi::FutureCallbackType_Sync);

    // Bind the subscriber locally.
    SignalLink uid = DynamicObject::metaConnect(event, sub);

    boost::recursive_mutex::scoped_lock _lock(_localToRemoteSignalLinkMutex);
    // maintain a map of localsignal -> remotesignal
    //(we only use one remotesignal, for many locals)
    LocalToRemoteSignalLinkMap::iterator it;
    RemoteSignalLinks& rsl = _localToRemoteSignalLink[event];
    rsl.localSignalLink.push_back(uid);

    if (rsl.remoteSignalLink == qi::SignalBase::invalidSignalLink)
    {
      /* Try to handle struct versionning.
      * Hypothesis: Everything in this address space uses the same struct
      * version. It makes sense since typesystem does not handle conflicting
      * definitions for the same type name (due to global typeid->typeinterface factory).
      *
      * So we use the very first subscriber to try to detect a version mismatch
      * between what the callback expects, and what the signal advertises.
      * If so we inform the remote end to try to convert for us.
      */
      Signature subSignature = sub.signature();
      float score = 1;
      if (subSignature.isValid())
      {
        const MetaSignal* ms = metaObject().signal(event);
        if (!ms)
          return makeFutureError<SignalLink>("Signal not found");
        score = ms->parametersSignature().isConvertibleTo(subSignature);
        qiLogDebug() << "Conversion score " << score << " " << ms->parametersSignature().toString() << " -> "
                     << subSignature.toString();
        if (!score)
        {
          std::ostringstream ss;
          ss << "Subscriber not compatible to signal signature: cannot convert " << ms->parametersSignature().toString()
             << " to " << subSignature.toString();
          return makeFutureError<SignalLink>(ss.str());
        }
      }
      rsl.remoteSignalLink = uid;
      qiLogDebug() << "connect() to " << event << " gave " << uid << " (new remote connection)";
      if (score >= 0.2)
        rsl.future = _self.async<SignalLink>("registerEvent", _service, event, uid);
      else // we might or might not be capable to convert, ask the remote end to try also
        rsl.future =
            _self.async<SignalLink>("registerEventWithSignature", _service, event, uid, subSignature.toString());
    }
    else
    {
      qiLogDebug() << "connect() to " << event << " gave " << uid << " (reusing remote connection)";
    }

    rsl.future.connect(boost::bind<void>(&onEventConnected, this, _1, prom, uid));
    return prom.future();
  }
Exemplo n.º 7
0
qi::Buffer replyBuf(const qi::Buffer& buf)
{
  qiLogDebug() << "enter";
  if (msDelay)
    qi::os::msleep(msDelay);
  qi::Buffer res = qi::Buffer(buf);
  qiLogDebug() << "leave";
  return res;
}
Exemplo n.º 8
0
 /// The number of records.
 size_t recordCount() const
 {
   qiLogDebug("qi.signalspy") << "Getting record count "
                              << (strand()->isInThisContext() ? "from strand" : "from outside");
   return async([this]
   {
     qiLogDebug("qi.signalspy") << "Getting record count";
     return _records.size();
   }).value();
 }
Exemplo n.º 9
0
  qi::FutureSync<void> ServiceDirectoryClient::onSocketDisconnected(std::string error) {
    qi::Future<void> fut;
    {
      qi::TransportSocketPtr socket;
      { // can't hold lock while disconnecting signals, so swap _sdSocket.
        boost::mutex::scoped_lock lock(_mutex);
        std::swap(socket, _sdSocket);
      }

      if (!socket)
        return qi::Future<void>(0);
      // We just manually triggered onSocketDisconnected, so unlink
      // from socket signal before disconnecting it.
      socket->disconnected.disconnect(_sdSocketDisconnectedSignalLink);
      // Manually trigger close on our remoteobject or it will be called
      // asynchronously from socket.disconnected signal, and we would need to
      // wait fo it.
      _remoteObject.close();
      fut = socket->disconnect();

      // Hold the socket shared ptr alive until the future returns.
      // otherwise, the destructor will block us until disconnect terminates
      // Nasty glitch: socket is reusing promises, so this future hook will stay
      // So pass shared pointer by pointer: that way a single delete statement
      // will end all copies.
      fut.connect(&sharedPtrHolder, new TransportSocketPtr(socket));
    }

    qi::SignalLink add=0, remove=0;
    qi::AnyObject object;
    {
      boost::mutex::scoped_lock lock(_mutex);
      std::swap(add, _addSignalLink);
      std::swap(remove, _removeSignalLink);
    }
    try {
      if (add != 0)
      {
        _object.disconnect(add);
      }
    } catch (std::runtime_error &e) {
      qiLogDebug() << "Cannot disconnect SDC::serviceAdded: " << e.what();
    }
    try {
      if (remove != 0)
      {
        _object.disconnect(remove);
      }
    } catch (std::runtime_error &e) {
        qiLogDebug() << "Cannot disconnect SDC::serviceRemoved: " << e.what();
    }
    disconnected(error);

    return fut;
  }
Exemplo n.º 10
0
  /// Direct access to a record, by order of arrival.
  Record record(size_t index) const
  {
    qiLogDebug("qi.signalspy") << "Getting record #" << index << " "
                               << (strand()->isInThisContext() ? "from strand" : "from outside");

    return async([this, index]
    {
      qiLogDebug("qi.signalspy") << "Getting record #" << index;
      return _records[index];
    }).value();
  }
Exemplo n.º 11
0
void TimelinePrivate::stop(bool join)
{
  qiLogDebug() << "Stopping timeline " << _name;
  _executer->stopExecuter(join);

  {
    boost::unique_lock<boost::recursive_mutex> lock(_methodMonitor);

    killMotionOrders();
  }

  qiLogDebug() << "Timeline " << _name << " stopped";
}
Exemplo n.º 12
0
  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;
  }
Exemplo n.º 13
0
 void *Buffer::read(size_t off, size_t length) const
 {
   if (!_p)
   {
     qiLogDebug("qi.buffer") << "read on empty buffer";
     return 0;
   }
   if (off + length > _p->used)
   {
     qiLogDebug("qi.buffer") << "Attempt to read " << off+length
      <<" on buffer of size " << _p->used;
     return 0;
   }
   return (char*)_p->data() + off;
 }
Exemplo n.º 14
0
  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;
  }
Exemplo n.º 15
0
 RemoteObject::~RemoteObject()
 {
   qiLogDebug() << "~RemoteObject " << this;
   //close may already have been called. (by Session_Service.close)
   close("RemoteObject destroyed");
   destroy();
 }
Exemplo n.º 16
0
    void *dlopen(const char *filename, int flag) {
      g_LastError.reset();
      std::string fullName = path::findLib(filename);
      if (fullName.empty())
      {
        qiLogVerbose() << "Could not locate library " << filename;
        fullName = filename; // Do not return here, let sys call fails and set errno.
        if (fullName.empty())
        {
          // do not allow dlopen(""), it will return a valid handler to the
          // current process
          g_LastError.reset(const_cast<char*>("trying to dlopen empty filename"));
          return NULL;
        }
      }
      void *handle = NULL;
      boost::filesystem::path fname(fullName, qi::unicodeFacet());
      qiLogDebug() << "opening " << fname;
#ifdef _WIN32
      handle = LoadLibraryW(fname.wstring(qi::unicodeFacet()).c_str());
#else
      if (flag == -1)
        flag = RTLD_NOW;
      handle = ::dlopen(fname.string(qi::unicodeFacet()).c_str(), flag);
#endif
      return handle;
    }
Exemplo n.º 17
0
void TimelinePrivate::startFlowdiagramAsync(int index)
{
  qiLogDebug() << "Start Flowdiagram, frames : " << index;
  boost::thread* t = new boost::thread(boost::bind(&TimelinePrivate::startFlowdiagram, this, index));

  _flowdiagrams.push_back(t);
}
Exemplo n.º 18
0
void TransportSocketCache::close()
{
  qiLogDebug() << "TransportSocketCache is closing";
  ConnectionMap map;
  std::list<TransportSocketPtr> pending;
  {
    boost::mutex::scoped_lock lock(_socketMutex);
    _dying = true;
    std::swap(map, _connections);
    std::swap(pending, _allPendingConnections);
  }
  for (ConnectionMap::iterator mIt = map.begin(), mEnd = map.end(); mIt != mEnd; ++mIt)
  {
    for (std::map<Url, ConnectionAttemptPtr>::iterator uIt = mIt->second.begin(), uEnd = mIt->second.end();
         uIt != uEnd;
         ++uIt)
    {
      TransportSocketPtr endpoint = uIt->second->endpoint;

      // Disconnect any valid socket we were holding.
      if (endpoint)
      {
        endpoint->disconnect();
      }
      else
      {
        uIt->second->state = State_Error;
        uIt->second->promise.setError("TransportSocketCache is closing.");
      }
    }
  }
  for (std::list<TransportSocketPtr>::iterator it = pending.begin(), end = pending.end(); it != end; ++it)
    (*it)->disconnect();
}
Exemplo n.º 19
0
 void PeriodicTaskPrivate::_reschedule(qi::int64_t delay)
 {
   qiLogDebug() << _name <<" rescheduling in " << delay;
   _task = getEventLoop()->async(boost::bind(&PeriodicTaskPrivate::_wrap, shared_from_this()), delay);
   if (!_state.setIfEquals(Task_Rescheduling, Task_Scheduled))
     qiLogError() << "PeriodicTask forbidden state change while rescheduling " << *_state;
 }
Exemplo n.º 20
0
  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);
  }
Exemplo n.º 21
0
  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);
  }
Exemplo n.º 22
0
void TimelinePrivate::goTo(int pFrame)
{
  qiLogDebug() << "goto timeline with : " << pFrame;
  boost::unique_lock<boost::recursive_mutex> lock(_methodMonitor);
  _currentFrame = pFrame;
  killMotionOrders();
  update();
}
Exemplo n.º 23
0
 Node::Node(NodeKind kind, NodeType type, const Location& loc, const std::string& comment)
   : _kind(kind)
   , _type(type)
   , _loc(loc)
   , _comment(comment)
 {
   qiLogDebug() << "new node(" << _kind << ", " << _type << ")";
 }
Exemplo n.º 24
0
TEST(TestJSONDecoder, StructWithDifferentSizedFields)
{
  Qiqi val;
  val.ffloat = 3.14f;
  val.fdouble = 5.5555;
  val.fint = 44;

  std::cout << qi::AnyValue(val).signature().toString() << std::endl;

  std::string json = qi::encodeJSON(val);
  qiLogDebug() << json << std::endl;
  qi::AnyValue res_any = qi::decodeJSON(json);
  qiLogDebug() << res_any.signature().toString() << std::endl;
  Qiqi res = res_any.to<Qiqi>();
  EXPECT_EQ(val,
            res) << qi::encodeJSON(val) << "\n" << qi::encodeJSON(res);
}
Exemplo n.º 25
0
 unsigned int Message::function() const
 {
   if (type() == Type_Event)
   {
     qiLogDebug() << "called function() on Type_Event message";
   }
   return _p->header.action;
 }
Exemplo n.º 26
0
 size_t Buffer::read(void* buffer, size_t off, size_t length) const
 {
   if (!_p)
   {
     qiLogDebug("qi.buffer") << "read on empty buffer";
     return -1;
   }
   if (off > _p->used)
   {
     qiLogDebug("qi.buffer") << "Attempt to read " << off+length
     <<" on buffer of size " << _p->used;
     return -1;
   }
   size_t copy = std::min(length, _p->used - off);
   memcpy(buffer, (char*)_p->data()+off, copy);
   return copy;
 }
Exemplo n.º 27
0
 unsigned int Message::event() const
 {
   if (type() != Type_Event)
   {
     qiLogDebug() << "called event() on non Type_Event message";
   }
   return _p->header.action;
 }
Exemplo n.º 28
0
 /* Events can reach us in basically random orders.
 * Synchronous hierarchy is constructed when an event arrives (it places
 * itself as deep as it can, but only goes as a child if it is sures
 * the decision is correct), and when an event is completed (end time
 * received, then it recheck following events to check if they were
 * actually children of his).
 *
 * Async hierarchy is double-checked the same way: When a new event inserts
 * itself, it tries to steal async children from its parents. And it
 * inserts itself as async child of the best correct match
 *
 *
 * Assumes end event is reached after start event for same id
 */
 static void insertTrace(CallList& l, CallData* d, CallData* parent = 0)
 {
   qiLogDebug() << "insertTrace " << d->uid;
   // Get first entry that started after us.
   CallList::iterator it = std::upper_bound(l.begin(), l.end(), CallTime(d));
   qiLogDebug() << "upperBoud " << ((it == l.end())? -1 : (int)(*it)->uid) << ' ' << (it == l.begin());
   if (it == l.begin())
   { // We are first
     l.insert(it, d);
     d->parent = parent;
   }
   else
   {
     // try to steal async children from entry above us
     CallList::iterator iprev = it;
     --iprev;
     CallData* prev = *iprev;
     for (unsigned i=0; i<prev->asyncChildren.size(); ++i)
     {
       CallData* child = prev->asyncChildren[i];
       if (child->tPost > d->tStart)
       { // This child was misplaced and is ours
         d->asyncChildren.push_back(child);
         prev->asyncChildren[i] = prev->asyncChildren.back();
         prev->asyncChildren.pop_back();
         child->asyncParent = d;
       }
     }
     // Check if we are child of it
     QI_ASSERT(prev->tStart <= d->tStart);
     if (prev->tEnd >= d->tStart)
     {
       qiLogDebug() << "Insert to child " << d->tStart << ' ' << d->tEnd
        << ' ' << prev->tStart << ' ' << prev->tEnd;
       insertTrace(prev->children, d, prev); // we start within it interval: we are its chilrend
     }
     else
     {
       l.insert(it, d);
       d->parent = parent;
     }
   }
   // if "it" was not completed, it will check following elements again
   // when tEnd will be available
 }
Exemplo n.º 29
0
 void Session_Service::addService(const std::string& name, const qi::AnyObject &obj) {
   boost::recursive_mutex::scoped_lock sl(_remoteObjectsMutex);
   RemoteObjectMap::iterator it = _remoteObjects.find(name);
   qiLogDebug() << "Adding remoteobject:" << name << " :" << &obj;
   if (it == _remoteObjects.end())
     _remoteObjects[name] = obj;
   else
     throw std::runtime_error("Service already in cache: " + name);
 }
Exemplo n.º 30
0
  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);
  }