Beispiel #1
0
void
Clock::sleep_for(const Clock& reltime)
{
#if defined(HAVE_POSIX_TIMERS) && !defined(ANDROID) && !defined(__hpux)
  struct timespec ts = ClockPosix::toTimespec(reltime.getNSec());
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
  clock_nanosleep(ClockPosix::getClockId(), 0, &ts, 0);
#else
  clock_nanosleep(CLOCK_REALTIME, 0, &ts, 0);
#endif
#else
  if (reltime == Clock::max())
    poll(0, 0, -1);
  else
    poll(0, 0, ClockPosix::toIntMSec(reltime.getNSec()));
#endif
}
  virtual bool execJoined(rti1516::RTIambassador& ambassador)
  {
    rti1516::InteractionClassHandle requestHandle;
    try {
      requestHandle = ambassador.getInteractionClassHandle(L"Request");
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    rti1516::ParameterHandle requestTypeHandle;
    try {
      requestTypeHandle = ambassador.getParameterHandle(requestHandle, L"requestType");
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    try {
      interactionClassHandle0 = ambassador.getInteractionClassHandle(L"InteractionClass0");
      interactionClassHandle1 = ambassador.getInteractionClassHandle(L"InteractionClass1");
      interactionClassHandle2 = ambassador.getInteractionClassHandle(L"InteractionClass2");
      interactionClassHandle3 = ambassador.getInteractionClassHandle(L"InteractionClass3");
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    try {
      class0Parameter0Handle = ambassador.getParameterHandle(interactionClassHandle0, L"parameter0");
      class1Parameter0Handle = ambassador.getParameterHandle(interactionClassHandle1, L"parameter0");
      class1Parameter1Handle = ambassador.getParameterHandle(interactionClassHandle1, L"parameter1");
      class2Parameter0Handle = ambassador.getParameterHandle(interactionClassHandle2, L"parameter0");
      class2Parameter1Handle = ambassador.getParameterHandle(interactionClassHandle2, L"parameter1");
      class2Parameter2Handle = ambassador.getParameterHandle(interactionClassHandle2, L"parameter2");
      class3Parameter0Handle = ambassador.getParameterHandle(interactionClassHandle3, L"parameter0");
      class3Parameter1Handle = ambassador.getParameterHandle(interactionClassHandle3, L"parameter1");
      class3Parameter3Handle = ambassador.getParameterHandle(interactionClassHandle3, L"parameter3");
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    try {
      ambassador.publishInteractionClass(requestHandle);
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    try {
      ambassador.subscribeInteractionClass(interactionClassHandle0);
      ambassador.subscribeInteractionClass(interactionClassHandle1);
      ambassador.subscribeInteractionClass(interactionClassHandle2);
      ambassador.subscribeInteractionClass(interactionClassHandle3);
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    if (!waitForAllFederates(ambassador))
      return false;

    double t = 0;
    for (unsigned i = 0; i < 100; ++i) {

      Clock clock = Clock::now();

      try {
        rti1516::ParameterHandleValueMap parameterValues;
        rti1516::VariableLengthData tag = toVariableLengthData("parameter0");
        parameterValues[requestTypeHandle] = toVariableLengthData(unsigned(Interaction1));
        ambassador.sendInteraction(requestHandle, parameterValues, tag);

      } catch (const rti1516::Exception& e) {
        std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
        return false;
      } catch (...) {
        std::wcout << L"Unknown Exception!" << std::endl;
        return false;
      }

      try {
        _receivedInteraction = false;
        Clock timeout = Clock::now() + Clock::fromSeconds(10);
        while (!_receivedInteraction) {
          if (ambassador.evokeCallback(10.0))
            continue;
          if (timeout < Clock::now()) {
            std::wcout << L"Timeout waiting for response!" << std::endl;
            return false;
          }
        }

      } catch (const rti1516::Exception& e) {
        std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
        return false;
      } catch (...) {
        std::wcout << L"Unknown Exception!" << std::endl;
        return false;
      }

      clock = Clock::now() - clock;
      t += 1e-9*clock.getNSec();
    }

    std::cout << t / 100 << std::endl;

    try {
      rti1516::ParameterHandleValueMap parameterValues;
      rti1516::VariableLengthData tag = toVariableLengthData("parameter0");
      parameterValues[requestTypeHandle] = toVariableLengthData(unsigned(Finished));
      ambassador.sendInteraction(requestHandle, parameterValues, tag);

    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    if (!waitForAllFederates(ambassador))
      return false;

    try {
      ambassador.unpublishInteractionClass(requestHandle);
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    try {
      ambassador.unsubscribeInteractionClass(interactionClassHandle0);
      ambassador.unsubscribeInteractionClass(interactionClassHandle1);
      ambassador.unsubscribeInteractionClass(interactionClassHandle2);
      ambassador.unsubscribeInteractionClass(interactionClassHandle3);
    } catch (const rti1516::Exception& e) {
      std::wcout << L"rti1516::Exception: \"" << e.what() << L"\"" << std::endl;
      return false;
    } catch (...) {
      std::wcout << L"Unknown Exception!" << std::endl;
      return false;
    }

    return true;
  }
  int exec(SocketEventDispatcher& dispatcher, const Clock& absclock)
  {
    int retv = 0;

    while (!dispatcher._done) {
      _fdVector.resize(0);
      _socketEventVector.resize(0);
      _timerSocketEventVector.resize(0);

      Clock timeout = absclock;

      struct pollfd pfd;
      std::memset(&pfd, 0, sizeof(pfd));
      for (SocketEventList::const_iterator i = dispatcher._socketEventList.begin(); i != dispatcher._socketEventList.end(); ++i) {
        AbstractSocketEvent* socketEvent = i->get();
        bool included = false;
        Socket* abstractSocket = socketEvent->getSocket();
        if (abstractSocket) {
          int fd = abstractSocket->_privateData->_fd;
          if (fd != -1) {
            pfd.fd = fd;
            pfd.events = 0;
            if (socketEvent->getEnableRead())
              pfd.events |= POLLRDNORM;
            if (socketEvent->getEnableWrite())
              pfd.events |= POLLWRNORM;

            if (pfd.events) {
              included = true;
              _fdVector.push_back(pfd);
              _socketEventVector.push_back(socketEvent);
            }
          }
        }

        if (socketEvent->getTimeout() != Clock::max()) {
          timeout = std::min(timeout, socketEvent->getTimeout());
          if (!included)
            _timerSocketEventVector.push_back(socketEvent);
        }
      }
      // The wakeup event is always put at the end and does *not* have a
      // corresponding _socketEventVector entry!
      pfd.fd = _wakeupReadFd;
      pfd.events = POLLRDNORM;
      _fdVector.push_back(pfd);

      int count;
      if (timeout < Clock::max()) {
        uint64_t now = ClockPosix::now();
        if (timeout.getNSec() < now) {
          count = 0;
        } else {
          count = ::poll(&_fdVector[0], _fdVector.size(), ClockPosix::toIntMSec(timeout.getNSec() - now));
        }
      } else {
        count = ::poll(&_fdVector[0], _fdVector.size(), -1);
      }
      if (count == -1) {
        int errorNumber = errno;
        if (errorNumber != EINTR && errorNumber != EAGAIN) {
          retv = -1;
          break;
        } else {
          count = 0;
        }
      }
      // Timeout
      uint64_t now = ClockPosix::now();
      if (absclock.getNSec() <= now) {
        retv = 0;
        break;
      }

      // We know the last one is from _fdVector is the wakup fd. Hence the _socketEventVector size is the one to walk.
      for (SocketEventVector::size_type i = 0; i < _socketEventVector.size(); ++i) {
        SharedPtr<AbstractSocketEvent> socketEvent;
        socketEvent.swap(_socketEventVector[i]);
        Socket* abstractSocket = socketEvent->getSocket();
        if (abstractSocket) {
          int fd = abstractSocket->_privateData->_fd;
          if (fd != -1) {
            OpenRTIAssert(fd == _fdVector[i].fd);
            short revents = _fdVector[i].revents;
            if (revents & POLLRDNORM)
              dispatcher.read(socketEvent);
            if (revents & POLLWRNORM)
              dispatcher.write(socketEvent);
          }
        }
        if (socketEvent->getTimeout().getNSec() <= now)
          dispatcher.timeout(socketEvent);
      }

      for (SocketEventVector::size_type i = 0; i < _timerSocketEventVector.size(); ++i) {
        SharedPtr<AbstractSocketEvent> socketEvent;
        socketEvent.swap(_timerSocketEventVector[i]);
        if (socketEvent->getTimeout().getNSec() <= now)
          dispatcher.timeout(socketEvent);
      }

      OpenRTIAssert(!_fdVector.empty());
      if (_fdVector.back().revents & POLLRDNORM) {
        char dummy[64];
        while (0 < ::read(_wakeupReadFd, dummy, sizeof(dummy)));
        if (!_wokenUp.compareAndExchange(1, 0, Atomic::MemoryOrderAcqRel))
          Log(Network, Warning) << "Having something to read from the wakeup pipe, but the flag is not set?" << std::endl;
        retv = 0;
        break;
      }
    }

    _fdVector.resize(0);
    _socketEventVector.resize(0);
    _timerSocketEventVector.resize(0);

    return retv;
  }