examples/network/torrrent: port to QBasicTimer

Instead of using raw timer IDs. QBasicTimer is a value class with
sizeof(int), so not much overhead, and easier to use API. Examples
should show best practices.

Change-Id: I5b9efe47ced69c0067eac891398185be7e87bd0e
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2024-08-30 20:44:29 +03:00
parent 81e3d10ca5
commit 2226581b0b
5 changed files with 37 additions and 55 deletions

View File

@ -22,14 +22,14 @@ static const char ProtocolIdSize = 19;
PeerWireClient::PeerWireClient(const QByteArray &peerId, QObject *parent)
: QTcpSocket(parent), pendingBlockSizes(0),
pwState(ChokingPeer | ChokedByPeer), receivedHandShake(false), gotPeerId(false),
sentHandShake(false), nextPacketLength(-1), pendingRequestTimer(0), invalidateTimeout(false),
keepAliveTimer(0), torrentPeer(nullptr)
sentHandShake(false), nextPacketLength(-1), invalidateTimeout(false),
torrentPeer(nullptr)
{
memset(uploadSpeedData, 0, sizeof(uploadSpeedData));
memset(downloadSpeedData, 0, sizeof(downloadSpeedData));
transferSpeedTimer = startTimer(PeerRateControlTimerDelay);
timeoutTimer = startTimer(ConnectTimeout);
transferSpeedTimer.start(PeerRateControlTimerDelay, this);
timeoutTimer.start(ConnectTimeout, this);
peerIdString = peerId;
connect(this, &PeerWireClient::readyRead,
@ -103,8 +103,7 @@ void PeerWireClient::unchokePeer()
write(message, sizeof(message));
pwState &= ~ChokingPeer;
if (pendingRequestTimer)
killTimer(pendingRequestTimer);
pendingRequestTimer.stop();
}
// Sends a "keep-alive" message to prevent the peer from closing
@ -126,9 +125,7 @@ void PeerWireClient::sendInterested()
// After telling the peer that we're interested, we expect to get
// unchoked within a certain timeframe; otherwise we'll drop the
// connection.
if (pendingRequestTimer)
killTimer(pendingRequestTimer);
pendingRequestTimer = startTimer(PendingRequestTimeout);
pendingRequestTimer.start(PendingRequestTimeout, this);
}
// Sends a "not interested" message, informing the peer that it does
@ -200,9 +197,7 @@ void PeerWireClient::requestBlock(qint32 piece, qint32 offset, qint32 length)
// After requesting a block, we expect the block to be sent by the
// other peer within a certain number of seconds. Otherwise, we
// drop the connection.
if (pendingRequestTimer)
killTimer(pendingRequestTimer);
pendingRequestTimer = startTimer(PendingRequestTimeout);
pendingRequestTimer.start(PendingRequestTimeout, this);
}
// Cancels a request for a block.
@ -347,7 +342,7 @@ void PeerWireClient::diconnectFromHost()
void PeerWireClient::timerEvent(QTimerEvent *event)
{
if (event->timerId() == transferSpeedTimer) {
if (event->id() == transferSpeedTimer.id()) {
// Rotate the upload / download records.
for (int i = 6; i >= 0; --i) {
uploadSpeedData[i + 1] = uploadSpeedData[i];
@ -355,7 +350,7 @@ void PeerWireClient::timerEvent(QTimerEvent *event)
}
uploadSpeedData[0] = 0;
downloadSpeedData[0] = 0;
} else if (event->timerId() == timeoutTimer) {
} else if (event->id() == timeoutTimer.id()) {
// Disconnect if we timed out; otherwise the timeout is
// restarted.
if (invalidateTimeout) {
@ -364,9 +359,9 @@ void PeerWireClient::timerEvent(QTimerEvent *event)
abort();
emit infoHashReceived(QByteArray());
}
} else if (event->timerId() == pendingRequestTimer) {
} else if (event->id() == pendingRequestTimer.id()) {
abort();
} else if (event->timerId() == keepAliveTimer) {
} else if (event->id() == keepAliveTimer.id()) {
sendKeepAlive();
}
QTcpSocket::timerEvent(event);
@ -378,9 +373,7 @@ void PeerWireClient::sendHandShake()
sentHandShake = true;
// Restart the timeout
if (timeoutTimer)
killTimer(timeoutTimer);
timeoutTimer = startTimer(ClientTimeout);
timeoutTimer.start(ClientTimeout, this);
// Write the 68 byte PeerWire handshake.
write(&ProtocolIdSize, 1);
@ -440,8 +433,8 @@ void PeerWireClient::processIncomingData()
}
// Initialize keep-alive timer
if (!keepAliveTimer)
keepAliveTimer = startTimer(KeepAliveInterval);
if (!keepAliveTimer.isActive())
keepAliveTimer.start(KeepAliveInterval, this);
do {
// Find the packet length
@ -482,8 +475,7 @@ void PeerWireClient::processIncomingData()
// We have been choked.
pwState |= ChokedByPeer;
incoming.clear();
if (pendingRequestTimer)
killTimer(pendingRequestTimer);
pendingRequestTimer.stop();
emit choked();
break;
case UnchokePacket:
@ -546,11 +538,8 @@ void PeerWireClient::processIncomingData()
// The peer sends a block.
emit blockReceived(index, begin, packet.mid(9));
// Kill the pending block timer.
if (pendingRequestTimer) {
killTimer(pendingRequestTimer);
pendingRequestTimer = 0;
}
// Stop the pending block timer.
pendingRequestTimer.stop();
break;
}
case CancelPacket: {

View File

@ -4,6 +4,7 @@
#ifndef PEERWIRECLIENT_H
#define PEERWIRECLIENT_H
#include <QBasicTimer>
#include <QBitArray>
#include <QList>
#include <QTcpSocket>
@ -150,13 +151,13 @@ private:
// Upload/download speed records
qint64 uploadSpeedData[8];
qint64 downloadSpeedData[8];
int transferSpeedTimer;
QBasicTimer transferSpeedTimer;
// Timeout handling
int timeoutTimer;
int pendingRequestTimer;
QBasicTimer timeoutTimer;
QBasicTimer pendingRequestTimer;
bool invalidateTimeout;
int keepAliveTimer;
QBasicTimer keepAliveTimer;
// Checksum, peer ID and set of available pieces
QByteArray infoHash;

View File

@ -67,7 +67,7 @@ public:
void callScheduler();
bool connectingToClients;
void callPeerConnector();
int uploadScheduleTimer;
QBasicTimer uploadScheduleTimer;
// Pieces
QMap<qint32, PeerWireClient *> readIds;
@ -83,7 +83,7 @@ public:
qint64 uploadedBytes;
int downloadRate[RateControlWindowLength];
int uploadRate[RateControlWindowLength];
int transferRateTimer;
QBasicTimer transferRateTimer;
TorrentClient *q;
};
@ -97,14 +97,12 @@ TorrentClientPrivate::TorrentClientPrivate(TorrentClient *qq)
stateString = QT_TRANSLATE_NOOP(TorrentClient, "Idle");
schedulerCalled = false;
connectingToClients = false;
uploadScheduleTimer = 0;
lastProgressValue = -1;
pieceCount = 0;
downloadedBytes = 0;
uploadedBytes = 0;
memset(downloadRate, 0, sizeof(downloadRate));
memset(uploadRate, 0, sizeof(uploadRate));
transferRateTimer = 0;
}
void TorrentClientPrivate::setError(TorrentClient::Error errorCode)
@ -414,11 +412,7 @@ void TorrentClient::stop()
State oldState = d->state;
d->setState(Stopping);
// Stop the timer
if (d->transferRateTimer) {
killTimer(d->transferRateTimer);
d->transferRateTimer = 0;
}
d->transferRateTimer.stop();
// Abort all existing connections
for (PeerWireClient *client : std::as_const(d->connections)) {
@ -461,13 +455,13 @@ void TorrentClient::setPaused(bool paused)
void TorrentClient::timerEvent(QTimerEvent *event)
{
if (event->timerId() == d->uploadScheduleTimer) {
if (event->id() == d->uploadScheduleTimer.id()) {
// Update the state of who's choked and who's not
scheduleUploads();
return;
}
if (event->timerId() != d->transferRateTimer) {
if (event->id() != d->transferRateTimer.id()) {
QObject::timerEvent(event);
return;
}
@ -492,8 +486,7 @@ void TorrentClient::timerEvent(QTimerEvent *event)
// Stop the timer if there is no activity.
if (downloadBytesPerSecond == 0 && uploadBytesPerSecond == 0) {
killTimer(d->transferRateTimer);
d->transferRateTimer = 0;
d->transferRateTimer.stop();
}
}
@ -534,7 +527,7 @@ void TorrentClient::fullVerificationDone()
++it;
}
d->uploadScheduleTimer = startTimer(UploadScheduleInterval);
d->uploadScheduleTimer.start(UploadScheduleInterval, this);
// Start the server
TorrentServer *server = TorrentServer::instance();
@ -1009,8 +1002,8 @@ void TorrentClient::blockReceived(qint32 pieceIndex, qint32 begin, const QByteAr
void TorrentClient::peerWireBytesWritten(qint64 size)
{
if (!d->transferRateTimer)
d->transferRateTimer = startTimer(RateControlTimerDelay);
if (!d->transferRateTimer.isActive())
d->transferRateTimer.start(RateControlTimerDelay, this);
d->uploadRate[0] += size;
d->uploadedBytes += size;
@ -1019,8 +1012,8 @@ void TorrentClient::peerWireBytesWritten(qint64 size)
void TorrentClient::peerWireBytesReceived(qint64 size)
{
if (!d->transferRateTimer)
d->transferRateTimer = startTimer(RateControlTimerDelay);
if (!d->transferRateTimer.isActive())
d->transferRateTimer.start(RateControlTimerDelay, this);
d->downloadRate[0] += size;
d->downloadedBytes += size;

View File

@ -45,7 +45,7 @@ void TrackerClient::stop()
void TrackerClient::timerEvent(QTimerEvent *event)
{
if (event->timerId() == requestIntervalTimer) {
if (event->id() == requestIntervalTimer.id()) {
fetchPeerList();
} else {
QObject::timerEvent(event);
@ -151,9 +151,7 @@ void TrackerClient::httpRequestDone(QNetworkReply *reply)
if (dict.contains("interval")) {
// Mandatory item
if (requestIntervalTimer != -1)
killTimer(requestIntervalTimer);
requestIntervalTimer = startTimer(std::chrono::seconds(dict.value("interval").toInt()));
requestIntervalTimer.start(std::chrono::seconds(dict.value("interval").toInt()), this);
}
if (dict.contains("peers")) {

View File

@ -4,6 +4,7 @@
#ifndef TRACKERCLIENT_H
#define TRACKERCLIENT_H
#include <QBasicTimer>
#include <QByteArray>
#include <QList>
#include <QObject>
@ -51,7 +52,7 @@ private slots:
private:
TorrentClient *torrentDownloader;
int requestIntervalTimer = -1;
QBasicTimer requestIntervalTimer;
QNetworkAccessManager http;
MetaInfo metaInfo;
QByteArray trackerId;