--- /dev/null
+/* Copyright (c) 2012-2017. The SimGrid Team.
+ * All rights reserved. */
+
+/* This program is free software; you can redistribute it and/or modify it
+ * under the terms of the license (GNU LGPL) which comes with this package. */
+
+#include "s4u_tracker.hpp"
+#include <xbt/RngStream.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_tracker, "Messages specific for the tracker");
+
+Tracker::Tracker(std::vector<std::string> args)
+{
+ // Checking arguments
+ xbt_assert(args.size() == 2, "Wrong number of arguments for the tracker.");
+ // Retrieving end time
+ try {
+ deadline = std::stod(args[1]);
+ } catch (std::invalid_argument& ia) {
+ throw std::invalid_argument(std::string("Invalid deadline:") + args[1].c_str());
+ }
+ xbt_assert(deadline > 0, "Wrong deadline supplied");
+
+ stream = simgrid::s4u::this_actor::getHost()->extension<HostBittorrent>()->getStream();
+
+ mailbox = simgrid::s4u::Mailbox::byName(TRACKER_MAILBOX);
+
+ XBT_INFO("Tracker launched.");
+}
+
+void Tracker::operator()()
+{
+ simgrid::s4u::CommPtr comm = nullptr;
+ while (simgrid::s4u::Engine::getClock() < deadline) {
+ void* received;
+ if (comm == nullptr)
+ comm = mailbox->get_async(&received);
+ if (comm->test()) {
+ // Retrieve the data sent by the peer.
+ TrackerQuery* tq = static_cast<TrackerQuery*>(received);
+
+ // Add the peer to our peer list, if not already known.
+ if (known_peers.find(tq->getPeerId()) == known_peers.end()) {
+ known_peers.insert(tq->getPeerId());
+ }
+
+ // Sending back peers to the requesting peer
+ TrackerAnswer* ta = new TrackerAnswer(TRACKER_QUERY_INTERVAL);
+ std::set<int>::iterator next_peer;
+ int nb_known_peers = known_peers.size();
+ int max_tries = MIN(MAXIMUM_PEERS, nb_known_peers);
+ int tried = 0;
+ while (tried < max_tries) {
+ do {
+ next_peer = known_peers.begin();
+ std::advance(next_peer, RngStream_RandInt(stream, 0, nb_known_peers - 1));
+ } while (ta->getPeers()->find(*next_peer) != ta->getPeers()->end());
+ ta->addPeer(*next_peer);
+ tried++;
+ }
+ tq->getReturnMailbox()->put_init(ta, TRACKER_COMM_SIZE)->detach();
+
+ delete tq;
+ comm = nullptr;
+ } else {
+ simgrid::s4u::this_actor::sleep_for(1);
+ }
+ }
+ // TODO See if some cleanup is needed
+ XBT_INFO("Tracker is leaving");
+}