Logo Search packages:      
Sourcecode: ultracopier version File versions  Download package

void WriteThread::run (  ) [protected]

Warning:
crash here, because the var is destructed by other thread

Definition at line 200 of file WriteThread.cpp.

References accessList, actionAfterUnlock, copyHadBegin, endOfSource, errorOnFile(), keepDate, movingMode, needSkipTheCurrentFile, preallocation, stopIt, stopThreadWhenFinish, theBlockList, and theCurrentStat.

{
      DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","start");
      QByteArray blockArray;
      //For this file only reset this variable
      qint64 positionInDestination=0,bytesWriten=0;
      do
      {
            DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","enter in wait mode");
            //block in the stopped mode
            theCurrentStat    = WriteThread::Stopped;
                DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","waitOneFile");
            waitOneFile.acquire();
                #if (DEBUG_ULTRACOPIER>0)
            haveBeenStarted=true;
                if(stopIt)
                    DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","stopIt=true");
                else if(stopThreadWhenFinish)
                    DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","stopThreadWhenFinish=true");
                #endif
            //stop this thread for urgence or end of copy
            if(stopIt || stopThreadWhenFinish)
                  break;
            DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","leave wait mode");
            //the destination should be open here
            if(!destination.isOpen() || theItem.id==0)
            {
                  DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","bug, destination should by open here");
                  stopIt=true;
                  break;
            }
            //start write the data stream
            theCurrentStat    = WriteThread::Running;
            if(!stopIt && !stopThreadWhenFinish)
            {
                  copyHadBegin      = true;
                  errorStringDef    = "Unknown error";
                  //never uncomment it, it product bug in this case (with semaphore should not have this bug):
                  //if source have finish to read and endOfSourceDetected() is call before this thread have leave wait mode do few on top by controlMutexF.wait(&mutexWaitControlF);
                  //endOfSource     = false;
                  if(preallocation)
                  {
                        DEBUGCONSOLE(90,"copyThread::run","resize destination to "+QString::number(source.size())+"...");
                        retryResizeFirst:
                        if(!destination.resize(source.size()))
                        {
                              actionAfterUnlock=-1;
                                        DEBUGCONSOLE(90,"copyThread::run",destination.fileName()+", cannot be resized: "+destination.errorString()+" at: "+QString::number(source.size()));
                              errorOnFile(ERROR_DEF_ALL,destination.fileName(),translationErrorResize+destination.errorString(),theItem.id);
                              if(stopIt || actionAfterUnlock==ERRORACTION_CLOSE)
                                    goto SkipFile;
                              if(actionAfterUnlock==ERRORACTION_RETRY)
                                    goto retryResizeFirst;
                              else if(actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF)
                                    goto SkipFile;
                              else
                              {
                                    DEBUGCONSOLE(10,"copyThread::run","Unknow action at set right ("+QString::number(actionAfterUnlock)+")");
                                    goto SkipFile;
                              }
                        }
                        DEBUGCONSOLE(90,"copyThread::run","resize done");
                  }

                  DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","start loop");
                  do
                  {
                        retryUsedBlock:
                        usedBlock.acquire();
                        //read one block
                        if(!theBlockList.size())
                              goto retryUsedBlock;
                        else
                        {
                              QMutexLocker lock_mutex(&accessList);
                              blockArray=theBlockList.first();
                              theBlockList.removeFirst();
                              sizeList--;
                              #if (DEBUG_ULTRACOPIER>0)
                              debugWcount+=blockArray.size();
                              #endif
                        }
                        //write one block
                        freeBlock->release();
                        if(!stopIt && !blockArray.isEmpty())
                        {
                              positionInDestination=destination.pos();
                              retryWriteThisBlock:
                              bytesWriten=destination.write(blockArray);
                              if((destination.error()!=QFile::NoError || bytesWriten!=blockArray.size()) && !stopIt)
                              {
                                    retrySeekDestination:
                                    actionAfterUnlock=-1;
                                    DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","Error in writing: "+destination.errorString()+" and destination->error(): "+QString::number((int)destination.error()));
                                    DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","bytesWriten("+QString::number(bytesWriten)+")!=blockArray.size("+QString::number(blockArray.size())+")");
                                    errorOnFile(ERROR_DEF_ALL,destination.fileName(),translationErrorWriting+destination.errorString(),theItem.id);
                                    if(stopIt)
                                          goto SkipFile;
                                    if(actionAfterUnlock==ERRORACTION_RETRY)
                                    {
                                          if(!destination.seek(positionInDestination))
                                                goto retrySeekDestination;
                                          goto retryWriteThisBlock;
                                    }
                                    else if(actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF)
                                          goto SkipFile;
                                    else if(actionAfterUnlock==ERRORACTION_CLOSE)
                                          goto SkipFile;
                                    else
                                    {
                                          DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","Unknow action at destination write error ("+QString::number(actionAfterUnlock)+")");
                                          goto SkipFile;
                                    }
                              }
                        }
                  }
                  while(!blockArray.isEmpty() && bytesWriten==blockArray.size() && !stopIt && (sizeList || !endOfSource));
                  DEBUGCONSOLE(70,"id: "+QString::number(id)+", "+"WriteThread::run","blockArray.isEmpty(): "+QString::number(blockArray.isEmpty()));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","bytesWriten: "+QString::number(bytesWriten));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","blockArray.size(): "+QString::number(blockArray.size()));
                  DEBUGCONSOLE(70,"id: "+QString::number(id)+", "+"WriteThread::run","stopIt: "+QString::number(stopIt));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","theBlockList.size(): "+QString::number(theBlockList.size()));
                  DEBUGCONSOLE(70,"id: "+QString::number(id)+", "+"WriteThread::run","endOfSource: "+QString::number(endOfSource));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","debugRcount: "+QString::number(debugRcount));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","debugWcount: "+QString::number(debugWcount));
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","CurentCopiedSize: "+QString::number(CurentCopiedSize));

                  if(!stopIt)
                  {
                        #if (DEBUG_ULTRACOPIER>0)
                        if(endOfSource)
                              DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","End of source detected: usedBlock->acquire()");
                        else
                              DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","End of source not detected and no stopIt but finish!");
                        #endif
                        DEBUGCONSOLE(90,"copyThread::run","resize destination to "+QString::number(source.size())+"...");
                        retryResizeLast:
                        if(!destination.resize(CurentCopiedSize))
                        {
                              actionAfterUnlock=-1;
                                        DEBUGCONSOLE(90,"copyThread::run","destination file exist: "+QString::number(destination.exists())+", is writable: "+QString::number(destination.isWritable())+", is open: "+QString::number(destination.isOpen()));
                                        DEBUGCONSOLE(90,"copyThread::run",destination.fileName()+", cannot be resized: "+destination.errorString()+" at: "+QString::number(CurentCopiedSize));
                              errorOnFile(ERROR_DEF_ALL,destination.fileName(),translationErrorResize+destination.errorString(),theItem.id);
                              if(stopIt || actionAfterUnlock==ERRORACTION_CLOSE)
                                    goto SkipFile;
                              if(actionAfterUnlock==ERRORACTION_RETRY)
                                    goto retryResizeLast;
                              else if(actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF)
                                    goto SkipFile;
                              else
                              {
                                    DEBUGCONSOLE(10,"copyThread::run","Unknow action at set right ("+QString::number(actionAfterUnlock)+")");
                                    goto SkipFile;
                              }
                        }
                        DEBUGCONSOLE(90,"copyThread::run","resizing done");
                  }

                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","closing source done");
                  /// \warning crash here, because the var is destructed by other thread
                  if(destination.isOpen())
                        destination.close();
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","closing destination done");
      
                  //set the time if no write thread used
                  if(keepDate)
                  {
                        retrySetDate:
                        DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","set date...");
                        if(!changeFileDateTime(destination.fileName(),source.fileName()))
                        {
                              actionAfterUnlock=-1;
                              DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","Date cannot be modified!");
                              errorOnFile(ERROR_DEF_ALL,source.fileName(),translationErrorDate,theItem.id);
                              if(stopIt)
                                    goto SkipFile;
                              if(actionAfterUnlock==ERRORACTION_RETRY)
                                    goto retrySetDate;
                              else if(actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF)
                                    goto SkipFile;
                              else if(actionAfterUnlock==ERRORACTION_CLOSE)
                                    goto SkipFile;
                              else
                              {
                                    DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","Unknow action at change file time ("+QString::number(actionAfterUnlock)+")");
                                    goto SkipFile;
                              }
                        }
                        DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","set date done");
                  }
      
                  //if query to stop, directly go to SkipFile
                  if(stopIt)
                        goto SkipFile;
      
                  //remove source in moving mode
                  if(movingMode)
                  {
                        DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","try remove source...");
                        if(destination.exists())
                        {
                              if(!source.remove())
                              {
                                    actionAfterUnlock=-1;
                                    DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","source.errorString():\""+source.errorString()+"\" while removing the source");
                                    errorOnFile(ERROR_DEF_ALL,source.fileName(),translationErrorRemove+source.errorString(),theItem.id);
                                    if(stopIt)
                                          goto SkipFile;
                                    if(actionAfterUnlock==ERRORACTION_RETRY)
                                          goto retrySetDate;
                                    else if(actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF)
                                          goto SkipFile;
                                    else if(actionAfterUnlock==ERRORACTION_CLOSE)
                                          goto SkipFile;
                                    else
                                    {
                                          DEBUGCONSOLE(10,"id: "+QString::number(id)+", "+"WriteThread::run","Unknow action at remove source file ("+QString::number(actionAfterUnlock)+")");
                                          goto SkipFile;
                                    }
                              }
                        }
                        else
                        {
                              DEBUGCONSOLE(10,"copyThread::run","try remove source but destination not exists!");
                        }
                        DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","try remove source done");
                  }
      
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","now is in SkipFile point!");
                  SkipFile:

                  //close file
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","closing destination...");
                  if(destination.isOpen())
                        destination.close();
                  DEBUGCONSOLE(90,"id: "+QString::number(id)+", "+"WriteThread::run","closing destination done");
      
                  if((actionAfterUnlock==ERRORACTION_SKIP || actionAfterUnlock==ERRORACTION_ENDOF || actionAfterUnlock==ERRORACTION_CLOSE || stopIt) && destination.exists() && source.exists() && copyHadBegin)
                  {
                        DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","try remove destination: "+destination.fileName());
                        destination.remove();
                  }
                  if(needSkipTheCurrentFile)
                        stopIt=false;
                  source.setFileName("");
                  destination.setFileName("");
                  theItem.id  = 0;
                  copyHadBegin      = false;

                        //reset all the var by default stat
                        CurentCopiedSize=0;
                        #if (DEBUG_ULTRACOPIER>0)
                        debugRcount = 0;
                        debugWcount = 0;
                        #endif
                        DEBUGCONSOLE(50,"id: "+QString::number(id)+", "+"WriteThread::run","endOfSource=false");
                        endOfSource = false;
                        theBlockList.clear();
                        usedBlock.acquire(usedBlock.available());
                        while(freeBlock->available()>LISTBLOCKSIZE)
                                freeBlock->acquire();
                        while(freeBlock->available()<LISTBLOCKSIZE)
                                freeBlock->release();

                  emit haveFinishFileOperation();
            }
      } while(!stopIt && !stopThreadWhenFinish);
      theCurrentStat    = WriteThread::Stopped;
      DEBUGCONSOLE(30,"id: "+QString::number(id)+", "+"WriteThread::run","stop the loop! And destroy the object!");
}

Here is the call graph for this function:


Generated by  Doxygen 1.6.0   Back to index