initial version of the sleeping ControlSender

This commit is contained in:
Stephen Birarda 2015-07-27 12:21:27 -07:00
parent 507592b088
commit b0e7c208ac
4 changed files with 119 additions and 1 deletions

View file

@ -0,0 +1,40 @@
//
// ControlSender.cpp
// libraries/networking/src/udt
//
// Created by Stephen Birarda on 2015-07-27.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <chrono>
#include <thread>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include "ControlSender.h"
using namespace udt;
void ControlSender::loop() {
while (!_isStopped) {
// grab the time now
auto start = std::chrono::high_resolution_clock::now();
// for each of the connections managed by the udt::Socket, we need to ask for the ACK value to send
// since we're infinitely looping, give the thread a chance to process events
QCoreApplication::processEvents();
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::micro> elapsed = end - start;
int timeToSleep = _synInterval - (int) elapsed.count();
// based on how much time it took us to process, let's figure out how much time we have need to sleep
std::this_thread::sleep_for(std::chrono::microseconds(timeToSleep));
}
}

View file

@ -0,0 +1,39 @@
//
// ControlSender.h
// libraries/networking/src/udt
//
// Created by Stephen Birarda on 2015-07-27.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#pragma once
#ifndef hifi_ControlSender_h
#define hifi_ControlSender_h
#include <QtCore/QObject>
namespace udt {
// Handles the sending of periodic control packets for all active UDT reliable connections
// Currently the interval for all connections is the same, so one thread is sufficient to manage all
class ControlSender : public QObject {
Q_OBJECT
public:
ControlSender(QObject* parent = 0) : QObject(parent) {};
public slots:
void loop(); // infinitely loops and sleeps to manage rate of control packet sending
void stop() { _isStopped = true; } // stops the loop
private:
int _synInterval = 10 * 1000;
bool _isStopped { false };
};
}
#endif // hifi_ControlSender_h

View file

@ -11,7 +11,10 @@
#include "Socket.h"
#include <QtCore/QThread>
#include "../NetworkLogging.h"
#include "ControlSender.h"
#include "Packet.h"
using namespace udt;
@ -20,6 +23,38 @@ Socket::Socket(QObject* parent) :
QObject(parent)
{
connect(&_udpSocket, &QUdpSocket::readyRead, this, &Socket::readPendingDatagrams);
// make a QThread for the ControlSender to live on
QThread* controlThread = new QThread(this);
// setup the ControlSender and parent it
_controlSender = new ControlSender;
// move the ControlSender to its thread
_controlSender->moveToThread(controlThread);
// start the ControlSender once the thread is started
connect(controlThread, &QThread::started, _controlSender, &ControlSender::loop);
// make sure the control thread is named so we can identify it
controlThread->setObjectName("UDT Control Thread");
// start the control thread
controlThread->start();
}
Socket::~Socket() {
if (_controlSender) {
QThread* controlThread = _controlSender->thread();
// tell the control sender to stop and be deleted so we can wait on its thread
QMetaObject::invokeMethod(_controlSender, "stop");
_controlSender->deleteLater();
// make sure the control thread goes down
controlThread->quit();
controlThread->wait();
}
}
void Socket::rebind() {

View file

@ -24,8 +24,9 @@
#include "SeqNum.h"
namespace udt {
class BasePacket;
class ControlSender;
class Packet;
using PacketFilterOperator = std::function<bool(const Packet&)>;
@ -37,6 +38,7 @@ class Socket : public QObject {
Q_OBJECT
public:
Socket(QObject* object = 0);
~Socket();
quint16 localPort() const { return _udpSocket.localPort(); }
@ -68,6 +70,8 @@ private:
std::unordered_map<HifiSockAddr, BasePacketHandler> _unfilteredHandlers;
std::unordered_map<HifiSockAddr, SeqNum> _packetSequenceNumbers;
ControlSender* _controlSender { nullptr };
};
} // namespace udt