1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Move file transfer in the core thread

Toxcore is not thread safe
This commit is contained in:
Tux3 / Mlkj / !Lev.uXFMLA 2014-08-28 21:56:55 +02:00
parent a75d1c5c6e
commit 3fc37d2d4c
2 changed files with 78 additions and 63 deletions

View File

@ -21,6 +21,7 @@
#include "widget/widget.h"
#include <ctime>
#include <functional>
#include <QDebug>
#include <QDir>
@ -45,8 +46,6 @@ Core::Core(Camera* cam, QThread *coreThread) :
toxTimer->setSingleShot(true);
//saveTimer = new QTimer(this);
//saveTimer->start(TOX_SAVE_INTERVAL);
//fileTimer = new QTimer(this);
//fileTimer->start(TOX_FILE_INTERVAL);
bootstrapTimer = new QTimer(this);
bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL);
connect(toxTimer, &QTimer::timeout, this, &Core::process);
@ -304,7 +303,10 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive
file->status = ToxFile::TRANSMITTING;
emit static_cast<Core*>(core)->fileTransferAccepted(*file);
qDebug() << "Core: File control callback, file accepted";
file->sendFuture = QtConcurrent::run(sendAllFileData, static_cast<Core*>(core), file);
file->sendTimer = new QTimer(static_cast<Core*>(core));
connect(file->sendTimer, &QTimer::timeout, std::bind(sendAllFileData,static_cast<Core*>(core), file));
file->sendTimer->setSingleShot(true);
file->sendTimer->start(TOX_FILE_INTERVAL);
}
else if (receive_send == 1 && control_type == TOX_FILECONTROL_KILL)
{
@ -312,7 +314,7 @@ void Core::onFileControlCallback(Tox* tox, int32_t friendnumber, uint8_t receive
.arg(file->fileNum).arg(file->friendId);
file->status = ToxFile::STOPPED;
emit static_cast<Core*>(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
file->sendFuture.waitForFinished(); // Wait for sendAllFileData to return before deleting the ToxFile
while (file->sendTimer) QThread::msleep(1); // Wait for sendAllFileData to return before deleting the ToxFile
removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum);
}
else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED)
@ -532,7 +534,7 @@ void Core::cancelFileSend(int friendId, int fileNum)
file->status = ToxFile::STOPPED;
emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0);
file->sendFuture.waitForFinished(); // Wait until sendAllFileData returns before deleting
while (file->sendTimer) QThread::msleep(1); // Wait until sendAllFileData returns before deleting
removeFileFromQueue(true, friendId, fileNum);
}
@ -961,16 +963,17 @@ void Core::removeFileFromQueue(bool sendQueue, int friendId, int fileId)
void Core::sendAllFileData(Core *core, ToxFile* file)
{
while (file->bytesSent < file->filesize)
{
if (file->status == ToxFile::PAUSED)
{
QThread::sleep(1);
continue;
file->sendTimer->start(TOX_FILE_INTERVAL);
return;
}
else if (file->status == ToxFile::STOPPED)
{
qWarning("Core::sendAllFileData: File is stopped");
file->sendTimer->disconnect();
delete file->sendTimer;
file->sendTimer = nullptr;
return;
}
emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING);
@ -994,31 +997,43 @@ void Core::sendAllFileData(Core *core, ToxFile* file)
{
qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString());
delete[] data;
QThread::msleep(5);
continue;
file->sendTimer->start(TOX_FILE_INTERVAL);
return;
}
else if (readSize == 0)
{
qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString());
delete[] data;
QThread::msleep(5);
continue;
file->sendTimer->start(TOX_FILE_INTERVAL);
return;
}
if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1)
{
//qWarning("Core::fileHeartbeat: Error sending data chunk");
//core->process();
delete[] data;
QThread::msleep(5);
continue;
QThread::msleep(1);
file->sendTimer->start(TOX_FILE_INTERVAL);
return;
}
delete[] data;
file->bytesSent += readSize;
//qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size());
if (file->bytesSent < file->filesize)
{
file->sendTimer->start(TOX_FILE_INTERVAL);
return;
}
qDebug("Core::fileHeartbeat: Transfer finished");
else
{
qDebug("Core: File transfer finished");
file->sendTimer->disconnect();
delete file->sendTimer;
file->sendTimer = nullptr;
tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_FINISHED, nullptr, 0);
emit core->fileTransferFinished(*file);
}
}
void Core::groupInviteFriend(int friendId, int groupId)

4
core.h
View File

@ -39,7 +39,7 @@
#define TOXAV_MAX_CALLS 16
#define GROUPCHAT_MAX_SIZE 32
#define TOX_SAVE_INTERVAL 30*1000
#define TOX_FILE_INTERVAL 20
#define TOX_FILE_INTERVAL 1
#define TOX_BOOTSTRAP_INTERVAL 10*1000
#define TOXAV_RINGING_TIME 15
@ -91,7 +91,7 @@ struct ToxFile
long long filesize;
FileStatus status;
FileDirection direction;
QFuture<void> sendFuture;
QTimer* sendTimer;
};
struct ToxCall