void WriteThread::internalWrite() { if(stopIt) return; //read one block if(theBlockList.size()<=0) { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"["+QString::number(id)+"] End detected of the file"); return; } else { QMutexLocker lock_mutex(&accessList); blockArray=theBlockList.first(); theBlockList.removeFirst(); } //write one block freeBlock.release(); if(stopIt) return; #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Write; #endif bytesWriten=file.write(blockArray); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif //mutex for stream this data if(CurentCopiedSize==0) { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Notice,"["+QString::number(id)+"] emit writeIsStarted()"); emit writeIsStarted(); } CurentCopiedSize+=bytesWriten; if(stopIt) return; if(file.error()!=QFile::NoError) { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"["+QString::number(id)+"] "+QString("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error())); errorString_internal=QString("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error()); stopIt=true; emit error(); return; } if(bytesWriten!=blockArray.size()) { ULTRACOPIER_DEBUGCONSOLE(DebugLevel_Warning,"["+QString::number(id)+"] "+QString("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size())); errorString_internal=QString("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size()); stopIt=true; emit error(); return; } lastGoodPosition+=bytesWriten; }
/// \brief do the fake writeIsStarted void WriteThread::fakeWriteIsStarted() { emit writeIsStarted(); }
void WriteThread::internalWrite() { #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT if(sequential) { multiForBigSpeed=0; QMutexLocker lock_mutex(&accessList); if(theBlockList.size()<numberOfBlock && !endDetected) return; } #endif bool haveBlock; do { if(putInPause) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Information,QStringLiteral("[")+QString::number(id)+QStringLiteral("] write put in pause")); if(stopIt) return; pauseMutex.acquire(); if(stopIt) return; } if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] stopIt")); return; } if(stopIt) return; //read one block { QMutexLocker lock_mutex(&accessList); if(theBlockList.isEmpty()) haveBlock=false; else { blockArray=theBlockList.first(); if(multiForBigSpeed>0) { if(blockArray.size()==blockSize) { theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); } else { blockArray.clear(); while(blockArray.size()!=blockSize) { //if larger if(theBlockList.first().size()>blockSize) { blockArray+=theBlockList.first().mid(0,blockSize); theBlockList.first().remove(0,blockSize); if(!sequential) { //do write in loop to finish the actual block emit internalStartWrite(); } break; } //if smaller else { blockArray+=theBlockList.first(); theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); if(theBlockList.isEmpty()) break; } } } haveBlock=!blockArray.isEmpty(); } else { theBlockList.removeFirst(); //if remove one block if(!sequential) writeFull.release(); } haveBlock=true; } } if(stopIt) return; if(!haveBlock) { if(sequential) { if(endDetected) internalEndOfFile(); else writeFull.release(); return; } ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] End detected of the file")); return; } #ifdef ULTRACOPIER_PLUGIN_SPEED_SUPPORT //wait for limitation speed if stop not query if(multiForBigSpeed>0) { numberOfBlockCopied++; if(sequential || (!sequential && writeFullBlocked)) { if(numberOfBlockCopied>=(multiForBigSpeed*2)) { numberOfBlockCopied=0; waitNewClockForSpeed.acquire(); if(stopIt) break; } } else { if(numberOfBlockCopied>=multiForBigSpeed) { numberOfBlockCopied=0; waitNewClockForSpeed.acquire(); if(stopIt) break; } } } #endif if(stopIt) return; #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Write; #endif bytesWriten=file.write(blockArray); #ifdef ULTRACOPIER_PLUGIN_DEBUG stat=Idle; #endif //mutex for stream this data if(lastGoodPosition==0) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,QStringLiteral("[")+QString::number(id)+QStringLiteral("] emit writeIsStarted()")); emit writeIsStarted(); } if(stopIt) return; if(file.error()!=QFile::NoError) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error())); errorString_internal=QStringLiteral("Error in writing: %1 (%2)").arg(file.errorString()).arg(file.error()); stopIt=true; emit error(); return; } if(bytesWriten!=blockArray.size()) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,QStringLiteral("[")+QString::number(id)+QStringLiteral("] ")+QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size())); errorString_internal=QStringLiteral("Error in writing, bytesWriten: %1, blockArray.size(): %2").arg(bytesWriten).arg(blockArray.size()); stopIt=true; emit error(); return; } lastGoodPosition+=bytesWriten; } while(sequential); }
void WriteThread::internalWrite() { const size_t blockSize=sizeof(blockArray); int32_t bytesWriten=0; ///< temp data for block writing, the bytes writen uint32_t blockArrayStop=this->blockArrayStop;//load value out of atomic uint32_t blockArrayStart=this->blockArrayStart;//load value out of atomic bool bytesWasWriten=false; if(blockArrayStart==blockArrayStop && !blockArrayIsFull) { if(!endDetected) readThread->callBack(); return; } do { if(stopIt) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] stopIt"); return; } if(stopIt) return; #ifdef ULTRACOPIER_PLUGIN_DEBUG status=Write; #endif errno=0; if(blockArrayStop>blockArrayStart) { void * ptr=blockArray+blockArrayStart; const size_t size=blockArrayStop-blockArrayStart; bytesWriten=fwrite(ptr,1,size,file); if(bytesWriten>0 && (errno==0 || errno==EAGAIN)) blockArrayStart+=bytesWriten; } else //if(blockArrayStart==blockSize || blockArrayStop<blockArrayStart)//and then blockArrayIsFull { void * ptr=blockArray+blockArrayStart; const size_t size=blockSize-blockArrayStart; bytesWriten=fwrite(ptr,1,size,file); if(bytesWriten>0 && (errno==0 || errno==EAGAIN)) blockArrayStart+=bytesWriten; } if(blockArrayStart==blockSize) blockArrayStart=0; #ifdef ULTRACOPIER_PLUGIN_DEBUG status=Idle; #endif if(lastGoodPosition==0) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"["+std::to_string(id)+"] emit writeIsStarted()"); emit writeIsStarted(); } lastGoodPosition+=bytesWriten; if(bytesWriten>0) bytesWasWriten=true; if(stopIt) return; if(errno!=0 && errno!=EAGAIN) { ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Warning,"["+std::to_string(id)+"] Error in writing: "+fileName+", errno: "+std::to_string(errno)); errorString_internal="Error in writing: "+fileName+" ("+std::string(strerror(errno))+", errno: "+std::to_string(errno)+")"; stopIt=true; emit error(); return; } } while(bytesWriten>0 && blockArrayStart!=blockArrayStop); if(bytesWasWriten) blockArrayIsFull=false; //is empty if(!endDetected) readThread->callBack(); //improve the performance due to drop block split /*if(blockArrayStart==blockArrayStop && !blockArrayIsFull) { blockArrayStart=BLOCKDEFAULTINITVAL; blockArrayStop=BLOCKDEFAULTINITVAL; } if manipulate the read thread var, need mutex and lower the performance*/ this->blockArrayStart=blockArrayStart; if(endDetected && bufferIsEmpty()) internalEndOfFile(); }