Results 1 to 6 of 6

Thread: QUrlOperator::copy sends two finished signals

  1. #1
    Join Date
    Mar 2006
    Posts
    74
    Thanks
    1
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows

    Default QUrlOperator::copy sends two finished signals

    I am using QUrlOperator::copy to copy files as part of setting up user configuration information the first time the app is run. I had this setup as part of the main() function and was running it before I started any dialogs. Since QUrlOperator::copy runs asynchronously I have been concerned that it might be possible that the files might not have been copied by the time the first dialog opens. In the past there were 4 fairly small files being copied and it has not been an issue. But current development code now has 6 files and soon another 2 will be added. Some users testing with current development code are now starting to experience problems with this and I am in the process of setting this up so that the first dialog blocks before it needs the files until the file copy operation is complete.

    I have this working but I am seeing some strange problems that I don't understand. The basic issue is that I am seeing 2 finished signals for each copy operation and not 1 like I had expected.

    My code looks like this:

    Globals

    Qt Code:
    1. static QUrlOperator urlOpTempFile;
    2. static QMutex mutexTempFile;
    3. static int copyNumTempFile = 0;
    To copy to clipboard, switch view to plain text mode 

    Slot to handle finished signal

    Qt Code:
    1. void lprofMain::templateFileCopied( QNetworkOperation *op )
    2. {
    3. mutexTempFile.lock();
    4. if ( !op )
    5. return;
    6. if ( op->state() == QNetworkProtocol::StFailed )
    7. {
    8. QMessageBox::critical( this, tr( "ERROR" ), op->protocolDetail() );
    9. }
    10. else if(op->state() == QNetworkProtocol::StDone)
    11. {
    12. copyNumTempFile = copyNumTempFile - 1;
    13. }
    14. mutexTempFile.unlock();
    15. }
    To copy to clipboard, switch view to plain text mode 

    Routine that starts the copy operations with a "fix"

    Qt Code:
    1. void lprofMain::Create_Config_Dir(const QString data_path)
    2. {
    3.  
    4. // Copy the template files into the users config directory
    5. QDir d (data_path + QString("/template/"));
    6. d.setFilter(QDir::Files | QDir::Hidden);
    7. const QFileInfoList *list = d.entryInfoList();
    8. QFileInfoListIterator it( *list );
    9. QFileInfo *fi;
    10. while ( (fi = it.current()) != 0 )
    11. {
    12. ++it;
    13. if (fi->fileName().contains("ITX", FALSE))
    14. {
    15. mutexTempFile.lock();
    16. copyNumTempFile = copyNumTempFile + 1;
    17. urlOpTempFile.copy( data_path + QString("/template/") +
    18. fi->fileName(), dir->homeDirPath() +
    19. QString("/.lprof/templates/") );
    20. // next line is the "fix"
    21. copyNumTempFile = copyNumTempFile + 1;
    22. mutexTempFile.unlock();
    23. }
    24. }
    25. }
    26. }
    To copy to clipboard, switch view to plain text mode 

    main dialog creation code

    Qt Code:
    1. lprofMain::lprofMain( QWidget* parent)
    2. : lprofMainBase( parent, "", 0,)
    3. {
    4. QObject::connect( &urlOpTempFile, SIGNAL( finished( QNetworkOperation *) ), this, SLOT( templateFileCopied( QNetworkOperation * ) ) );
    5.  
    6. Create_Config_Dir(QDir::currentDirPath());
    7.  
    8. while (copyNumTempFile>0)
    9. {
    10. lprofApp -> processEvents();
    11. }
    12. }
    To copy to clipboard, switch view to plain text mode 

    I am running Qt 3.3.8 on a Linux box. Anyone seen this type of thing before or have any ideas about what could be causing this? The code above works but my main concern is that it does not look right to me and I am concerned that I may be "fixing" something that is really a problem with the particular version of Qt I am running.

  2. #2
    Join Date
    Mar 2006
    Posts
    74
    Thanks
    1
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUrlOperator::copy sends two finished signals

    Bump. Sorry I didn't intend this to stump the band.

  3. #3
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QUrlOperator::copy sends two finished signals

    Quote Originally Posted by hvengel View Post
    Anyone seen this type of thing before or have any ideas about what could be causing this?
    As the docs say:
    ... a move or copy operation consists of multiple operations (get(), put() and maybe remove()), this function doesn't return a single QNetworkOperation, but rather a list of them. They are in the order: get(), put() and (if applicable) remove().
    So it looks like finished() is emitted for each of those operations.

    You could try something like this:
    Qt Code:
    1. ...
    2. QPtrList<QNetworkOperation> list = urlOpTempFile.copy( ... );
    3. lastOp = list.last();
    4. ...
    5.  
    6. void lprofMain::templateFileCopied( QNetworkOperation *op )
    7. {
    8. if ( !op )
    9. return;
    10. if ( op->state() == QNetworkProtocol::StFailed )
    11. {
    12. QMessageBox::critical( this, tr( "ERROR" ), op->protocolDetail() );
    13. }
    14. else if( op == lastOp && op->state() == QNetworkProtocol::StDone )
    15. {
    16. QMutexLocker locker( & mutexTempFile );
    17. copyNumTempFile = copyNumTempFile - 1;
    18. }
    19. }
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Mar 2006
    Posts
    74
    Thanks
    1
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUrlOperator::copy sends two finished signals

    I think the important things is that that there are more than on finished signal for each QUrlOperator::copy. Likely one for get() and put() so having two signals looks like it is correct.

    I don't think your code will work however since there a likely more than one of these QUrlOperator::copy threads running at a given time and the finished events will not happen in a known order. Your proposed fix assumes that these are ordered and as a result could fail.

    Since it appears that two finished signals is normal for a QUrlOperator::copy then it looks to me like my algorithms are basically correct.

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QUrlOperator::copy sends two finished signals

    Quote Originally Posted by hvengel View Post
    Since it appears that two finished signals is normal for a QUrlOperator::copy then it looks to me like my algorithms are basically correct.
    Yes, they are and I never wrote that they're wrong (actually I simply overlooked that "fix" line in your code). The only thing is that the meaning of copyNumTempFile changes a bit, but it doesn't seem to be a problem.

    Although there is an error in lprofMain::templateFileCopied() --- check what happens with the mutex if that slot was for some reason invoked with a null parameter.

    Quote Originally Posted by hvengel View Post
    I don't think your code will work however since there a likely more than one of these QUrlOperator::copy threads running at a given time and the finished events will not happen in a known order. Your proposed fix assumes that these are ordered and as a result could fail.
    If Qt 3 could use more than one thread to handle those operations, then of course you would be right. Unfortunately all network related classes in Qt 3 are not thread safe, so one can assume that QNetworkProtocol doesn't change the order of network operations.

  6. #6
    Join Date
    Mar 2006
    Posts
    74
    Thanks
    1
    Qt products
    Qt3
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QUrlOperator::copy sends two finished signals (solved)

    You are right it would not release the lock and this would cause a deadlock condition. Thanks for pointing that out.

    After doing more research I now have this working the way it should. The signal handler has been changed to look like this:

    Qt Code:
    1. void lprofMain::templateFileCopied( QNetworkOperation *op )
    2. {
    3. if ( !op )
    4. return;
    5.  
    6. if ( op->state() == QNetworkProtocol::StFailed )
    7. {
    8. QMessageBox::critical( this, tr( "ERROR" ), op->protocolDetail() );
    9. }
    10. else if(op->operation () == QNetworkProtocol::OpPut )
    11. {
    12. mutexTempFile.lock();
    13. copyNumTempFile = copyNumTempFile - 1;
    14. mutexTempFile.unlock();
    15. }
    16.  
    17. }
    To copy to clipboard, switch view to plain text mode 

    So it now only decrements the counter if it is a put operation that has finished. And in the code where I start the QUrlOperator::copy running I only increment the counter one time for each QUrlOperator::copy thread. I have also reduced the scope of the QMutex lock so that it only protects the counter operations.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Qt is a trademark of The Qt Company.