Прежде чем реализовать это, я хотел бы проверить, приведет ли это к неопределенному поведению или условиям гонки.
При загрузке файлов в asure это нужно делать блоками. Я хочу загрузить 5 блоков параллельно, и все они получают свои данные из одного и того же файла. Это произойдет следующим образом:
char *currentDataChunk;
int currentDataChunkSize;
connect(_blobStorageProvider, SIGNAL(putBlockSucceded(int)), this, SLOT(finalizeAndUploadNextBlock(int)));
int parallelUploads = ((_item->size() / MAX_BLOCK_SIZE) >= MAX_PARALLEL_BLOCKUPLOADS) ? MAX_PARALLEL_BLOCKUPLOADS : (_item->size() / MAX_BLOCK_SIZE);
_latestProcessedBlockId = (parallelUploads - 1);
for(int i = 0; i < parallelUploads; i++) {
currentDataChunkSize = _item->read(currentDataChunk, MAX_BLOCK_SIZE);
...
uploader->putBlock(_container, _blobName, currentDataChunk, i);
}
В функции putBlock в загрузчике он вызывает QNetworkAccessManager с вызовом. Когда это будет сделано, он отправляет обратно сигнал, если он не прошел, успешно или был отменен, вместе с blockId, чтобы я знал, какой из блоков был загружен.
void BigBlobUploader::finalizeAndUploadNextBlock(int blockId) {
// FINALIZE BY ADDING SUCCESSFUL BLOCK TO FUTURE BLOCKLIST
QByteArray temp;
for(int i = 0; i != sizeof(blockId); i++) {
temp.append((char)(blockId >> (i * 8)));
}
_uploadedBlockIds.insert(blockId, QString(temp.toBase64()));
this->uploadNextBlock();
}
void BigBlobUploader::uploadNextBlock() {
char *newDataChunk;
int newDataChunkSize = _item->read(newDataChunk, MAX_BLOCK_SIZE);
...
_latestProcessedBlockId++;
uploader->putBlock(_container, _blobName, newDataChunk, _latestProcessedBlockId);
}
Мой план сейчас состоит в том, чтобы получить эти сигналы в слот, который должен принять к сведению, что этот блок был загружен (поместите его в список, чтобы иметь возможность поместить список блоков для завершения этого блоба), увеличить индекс на единицу (который начинается с 5 ), получить новый фрагмент данных и повторить весь процесс.
Моя проблема сейчас в том, что, если два из них закончатся в ТОЧНОЕ время? Я не имею здесь дело с потоками, но поскольку HTTP-запросы по умолчанию разделены на потоки, в чем здесь дело? Сигналы поставлены в очередь (или мне следует использовать QueuedConnection)? Можно ли вызывать слот параллельно? Есть ли лучший способ сделать это?