Reworked DoneHandler to avoid race conditions
authorMohammed Sameer <msameer@foolab.org>
Mon, 24 Dec 2012 15:32:13 +0000 (17:32 +0200)
committerMohammed Sameer <msameer@foolab.org>
Mon, 24 Dec 2012 15:32:13 +0000 (17:32 +0200)
If we start capturing the 2nd image before the first gets saved then we
accidentally try to rename the 1st image to the 2nd image.

We now only try to rename if we have a temporarily file name and a mode file name.
Since video mode only sets tempFileName then we should be fine as we don't really
allow recording a new video before the old one gets saved.

For images, we simply use the filename from the structure for the saved() signal
and fall back to the mode fileName if it's empty without overwriting the members
of QtCamModePrivate

lib/qtcammode.cpp
lib/qtcammode_p.h

index 1b9fc75..d49e5dc 100644 (file)
@@ -91,26 +91,27 @@ public:
   }
 
   virtual void handleMessage(GstMessage *message) {
+    // If we have a temp file then we rename it:
+    if (!mode->tempFileName.isEmpty() && !mode->fileName.isEmpty()) {
+      if (!QFile::rename(mode->tempFileName, mode->fileName)) {
+       qCritical() << "Failed to rename" << mode->tempFileName << "to" << mode->fileName;
+      }
+    }
+
+    QString fileName;
     const GstStructure *s = gst_message_get_structure(message);
     if (gst_structure_has_field(s, "filename")) {
       const char *str = gst_structure_get_string(s, "filename");
       if (str) {
-       mode->tempFileName = QString::fromUtf8(str);
+       fileName = QString::fromUtf8(str);
       }
     }
 
-    if (mode->fileName.isEmpty()) {
-      mode->fileName = mode->tempFileName;
-    }
-
-    if (!mode->tempFileName.isEmpty() && !mode->fileName.isEmpty() &&
-       mode->tempFileName != mode->fileName) {
-      if (!QFile::rename(mode->tempFileName, mode->fileName)) {
-       qCritical() << "Failed to rename" << mode->tempFileName << "to" << mode->fileName;
-      }
+    if (fileName.isEmpty()) {
+      fileName = mode->fileName;
     }
 
-    QMetaObject::invokeMethod(mode->q_ptr, "saved", Q_ARG(QString, mode->fileName));
+    QMetaObject::invokeMethod(mode->q_ptr, "saved", Q_ARG(QString, fileName));
   }
 
   QtCamModePrivate *mode;
index ae02e56..4fc5f52 100644 (file)
@@ -180,6 +180,7 @@ public:
   void setFileName(const QString& file) {
     fileName = file;
   }
+
   void setTempFileName(const QString& file) {
     tempFileName = file;
   }