Esempio n. 1
0
void WriteThread::run()
{
        connect(this,SIGNAL(internalStartOpen()),               this,SLOT(internalOpen()),              Qt::QueuedConnection);
        connect(this,SIGNAL(internalStartReopen()),             this,SLOT(internalReopen()),            Qt::QueuedConnection);
        connect(this,SIGNAL(internalStartWrite()),              this,SLOT(internalWrite()),             Qt::QueuedConnection);
        connect(this,SIGNAL(internalStartClose()),              this,SLOT(internalClose()),             Qt::QueuedConnection);
	connect(this,SIGNAL(internalStartEndOfFile()),		this,SLOT(internalEndOfFile()),		Qt::QueuedConnection);
	connect(this,SIGNAL(internalStartFlushAndSeekToZero()), this,SLOT(internalFlushAndSeekToZero()),Qt::QueuedConnection);
	connect(this,SIGNAL(internalStartChecksum()),		this,SLOT(checkSum()),			Qt::QueuedConnection);
	exec();
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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();
}