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:
parent
a75d1c5c6e
commit
3fc37d2d4c
137
core.cpp
137
core.cpp
|
@ -21,6 +21,7 @@
|
||||||
#include "widget/widget.h"
|
#include "widget/widget.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
@ -45,8 +46,6 @@ Core::Core(Camera* cam, QThread *coreThread) :
|
||||||
toxTimer->setSingleShot(true);
|
toxTimer->setSingleShot(true);
|
||||||
//saveTimer = new QTimer(this);
|
//saveTimer = new QTimer(this);
|
||||||
//saveTimer->start(TOX_SAVE_INTERVAL);
|
//saveTimer->start(TOX_SAVE_INTERVAL);
|
||||||
//fileTimer = new QTimer(this);
|
|
||||||
//fileTimer->start(TOX_FILE_INTERVAL);
|
|
||||||
bootstrapTimer = new QTimer(this);
|
bootstrapTimer = new QTimer(this);
|
||||||
bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL);
|
bootstrapTimer->start(TOX_BOOTSTRAP_INTERVAL);
|
||||||
connect(toxTimer, &QTimer::timeout, this, &Core::process);
|
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;
|
file->status = ToxFile::TRANSMITTING;
|
||||||
emit static_cast<Core*>(core)->fileTransferAccepted(*file);
|
emit static_cast<Core*>(core)->fileTransferAccepted(*file);
|
||||||
qDebug() << "Core: File control callback, file accepted";
|
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)
|
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);
|
.arg(file->fileNum).arg(file->friendId);
|
||||||
file->status = ToxFile::STOPPED;
|
file->status = ToxFile::STOPPED;
|
||||||
emit static_cast<Core*>(core)->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
|
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);
|
removeFileFromQueue((bool)receive_send, file->friendId, file->fileNum);
|
||||||
}
|
}
|
||||||
else if (receive_send == 1 && control_type == TOX_FILECONTROL_FINISHED)
|
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;
|
file->status = ToxFile::STOPPED;
|
||||||
emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
|
emit fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
|
||||||
tox_file_send_control(tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0);
|
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);
|
removeFileFromQueue(true, friendId, fileNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,64 +963,77 @@ void Core::removeFileFromQueue(bool sendQueue, int friendId, int fileId)
|
||||||
|
|
||||||
void Core::sendAllFileData(Core *core, ToxFile* file)
|
void Core::sendAllFileData(Core *core, ToxFile* file)
|
||||||
{
|
{
|
||||||
while (file->bytesSent < file->filesize)
|
if (file->status == ToxFile::PAUSED)
|
||||||
{
|
{
|
||||||
if (file->status == ToxFile::PAUSED)
|
file->sendTimer->start(TOX_FILE_INTERVAL);
|
||||||
{
|
return;
|
||||||
QThread::sleep(1);
|
}
|
||||||
continue;
|
else if (file->status == ToxFile::STOPPED)
|
||||||
}
|
{
|
||||||
else if (file->status == ToxFile::STOPPED)
|
qWarning("Core::sendAllFileData: File is stopped");
|
||||||
{
|
file->sendTimer->disconnect();
|
||||||
qWarning("Core::sendAllFileData: File is stopped");
|
delete file->sendTimer;
|
||||||
return;
|
file->sendTimer = nullptr;
|
||||||
}
|
return;
|
||||||
emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING);
|
}
|
||||||
qApp->processEvents();
|
emit core->fileTransferInfo(file->friendId, file->fileNum, file->filesize, file->bytesSent, ToxFile::SENDING);
|
||||||
long long chunkSize = tox_file_data_size(core->tox, file->friendId);
|
qApp->processEvents();
|
||||||
if (chunkSize == -1)
|
long long chunkSize = tox_file_data_size(core->tox, file->friendId);
|
||||||
{
|
if (chunkSize == -1)
|
||||||
qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send");
|
{
|
||||||
file->status = ToxFile::STOPPED;
|
qWarning("Core::fileHeartbeat: Error getting preffered chunk size, aborting file send");
|
||||||
emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
|
file->status = ToxFile::STOPPED;
|
||||||
tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0);
|
emit core->fileTransferCancelled(file->friendId, file->fileNum, ToxFile::SENDING);
|
||||||
removeFileFromQueue(true, file->friendId, file->fileNum);
|
tox_file_send_control(core->tox, file->friendId, 0, file->fileNum, TOX_FILECONTROL_KILL, nullptr, 0);
|
||||||
return;
|
removeFileFromQueue(true, file->friendId, file->fileNum);
|
||||||
}
|
return;
|
||||||
//qDebug() << "chunkSize: " << chunkSize;
|
}
|
||||||
chunkSize = std::min(chunkSize, file->filesize);
|
//qDebug() << "chunkSize: " << chunkSize;
|
||||||
uint8_t* data = new uint8_t[chunkSize];
|
chunkSize = std::min(chunkSize, file->filesize);
|
||||||
file->file->seek(file->bytesSent);
|
uint8_t* data = new uint8_t[chunkSize];
|
||||||
int readSize = file->file->read((char*)data, chunkSize);
|
file->file->seek(file->bytesSent);
|
||||||
if (readSize == -1)
|
int readSize = file->file->read((char*)data, chunkSize);
|
||||||
{
|
if (readSize == -1)
|
||||||
qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString());
|
{
|
||||||
delete[] data;
|
qWarning() << QString("Core::sendAllFileData: Error reading from file: %1").arg(file->file->errorString());
|
||||||
QThread::msleep(5);
|
delete[] data;
|
||||||
continue;
|
file->sendTimer->start(TOX_FILE_INTERVAL);
|
||||||
}
|
return;
|
||||||
else if (readSize == 0)
|
}
|
||||||
{
|
else if (readSize == 0)
|
||||||
qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString());
|
{
|
||||||
delete[] data;
|
qWarning() << QString("Core::sendAllFileData: Nothing to read from file: %1").arg(file->file->errorString());
|
||||||
QThread::msleep(5);
|
delete[] data;
|
||||||
continue;
|
file->sendTimer->start(TOX_FILE_INTERVAL);
|
||||||
}
|
return;
|
||||||
if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1)
|
}
|
||||||
{
|
if (tox_file_send_data(core->tox, file->friendId, file->fileNum, data, readSize) == -1)
|
||||||
//qWarning("Core::fileHeartbeat: Error sending data chunk");
|
{
|
||||||
//core->process();
|
//qWarning("Core::fileHeartbeat: Error sending data chunk");
|
||||||
delete[] data;
|
//core->process();
|
||||||
QThread::msleep(5);
|
delete[] data;
|
||||||
continue;
|
QThread::msleep(1);
|
||||||
}
|
file->sendTimer->start(TOX_FILE_INTERVAL);
|
||||||
delete[] data;
|
return;
|
||||||
file->bytesSent += readSize;
|
}
|
||||||
//qDebug() << QString("Core::fileHeartbeat: sent %1/%2 bytes").arg(file->bytesSent).arg(file->fileData.size());
|
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;
|
||||||
|
}
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
qDebug("Core::fileHeartbeat: Transfer finished");
|
|
||||||
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)
|
void Core::groupInviteFriend(int friendId, int groupId)
|
||||||
|
|
4
core.h
4
core.h
|
@ -39,7 +39,7 @@
|
||||||
#define TOXAV_MAX_CALLS 16
|
#define TOXAV_MAX_CALLS 16
|
||||||
#define GROUPCHAT_MAX_SIZE 32
|
#define GROUPCHAT_MAX_SIZE 32
|
||||||
#define TOX_SAVE_INTERVAL 30*1000
|
#define TOX_SAVE_INTERVAL 30*1000
|
||||||
#define TOX_FILE_INTERVAL 20
|
#define TOX_FILE_INTERVAL 1
|
||||||
#define TOX_BOOTSTRAP_INTERVAL 10*1000
|
#define TOX_BOOTSTRAP_INTERVAL 10*1000
|
||||||
#define TOXAV_RINGING_TIME 15
|
#define TOXAV_RINGING_TIME 15
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ struct ToxFile
|
||||||
long long filesize;
|
long long filesize;
|
||||||
FileStatus status;
|
FileStatus status;
|
||||||
FileDirection direction;
|
FileDirection direction;
|
||||||
QFuture<void> sendFuture;
|
QTimer* sendTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ToxCall
|
struct ToxCall
|
||||||
|
|
Loading…
Reference in New Issue
Block a user