Index: jobthread.cpp
===================================================================
--- jobthread.cpp	(revision 7004)
+++ jobthread.cpp	(working copy)
@@ -24,6 +24,7 @@
 #include <qdir.h>
 #include <qapplication.h>
 #include <qdeepcopy.h>
+#include <qprocess.h>
 
 #include <mythtv/mythcontext.h>
 #include <mythtv/mythdbcon.h>
@@ -211,6 +212,63 @@
 ---------------------------------------------------------------------
 */
 
+namespace
+{
+    class MutexUnlocker
+    {
+      public:
+        MutexUnlocker(QMutex *mutex) : m_mutex(mutex)
+        {
+            if (!(m_mutex && m_mutex->locked()))
+            {
+                cerr << __FILE__ << ": Invalid mutext passed to MutexUnlocker"
+                        << endl;
+            }
+        }
+
+        ~MutexUnlocker()
+        {
+            m_mutex->unlock();
+        }
+
+      private:
+        QMutex *m_mutex;
+    };
+
+    template <typename HTYPE, typename CLEANF_RET = void>
+    class SmartHandle
+    {
+      private:
+        typedef CLEANF_RET (*clean_fun_t)(HTYPE);
+
+      public:
+        SmartHandle(HTYPE handle, clean_fun_t cleaner) : m_handle(handle), 
+                m_cleaner(cleaner)
+        {
+        }
+
+        ~SmartHandle() {
+            if (m_handle)
+            {
+                m_cleaner(m_handle);
+            }
+        }
+
+        HTYPE get()
+        {
+            return m_handle;
+        }
+
+        HTYPE operator->() {
+            return m_handle;
+        }
+
+      private:
+        HTYPE m_handle;
+        clean_fun_t m_cleaner;
+    };
+}
+
 DVDThread::DVDThread(MTD *owner, 
                      QMutex *drive_mutex, 
                      const QString &dvd_device, 
@@ -225,7 +283,6 @@
     dvd_device_location = dvd_device;
     dvd_title = track - 1;
     destination_file_string = dest_file;
-    ripfile = NULL;
     rip_name = name;
 }
 
@@ -269,10 +326,11 @@
         }
     }    
 
+    MutexUnlocker qmul(dvd_device_access);
+
     if(!keepGoing())
     {
         problem("abandoned job because master control said we need to shut down");
-        dvd_device_access->unlock();
         return false;
     }
 
@@ -284,17 +342,11 @@
     //  Lets open our destination file
     //
     
-    if(ripfile)
+    RipFile ripfile(to_location, extension, true);
+    if(!ripfile.open(IO_WriteOnly | IO_Raw | IO_Truncate, multiple_files))
     {
-        cerr << "jobthread.o: How is it that you already have a ripfile set?" << endl;
-        delete ripfile;
-    }
-    
-    ripfile = new RipFile(to_location, extension);
-    if(!ripfile->open(IO_WriteOnly | IO_Raw | IO_Truncate, multiple_files))
-    {
-        problem(QString("DVDPerfectThread could not open output file: %1").arg(ripfile->name()));
-        dvd_device_access->unlock();
+        problem(QString("DVDPerfectThread could not open output file: %1")
+                .arg(ripfile.name()));
         return false;
     }
 
@@ -305,27 +357,19 @@
     
     int angle = 0;  // Change that at some point
 
-    the_dvd = DVDOpen(dvd_device_location);
-    if(!the_dvd)
+    SmartHandle<dvd_reader_t *> the_dvd(DVDOpen(dvd_device_location),
+            DVDClose);
+    if(!the_dvd.get())
     {
         problem(QString("DVDPerfectThread could not access this dvd device: %1").arg(dvd_device_location));
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        dvd_device_access->unlock();
         return false;
     }
 
 
-    ifo_handle_t *vmg_file = ifoOpen( the_dvd, 0);
-    if(!vmg_file)
+    SmartHandle<ifo_handle_t *> vmg_file(ifoOpen(the_dvd.get(), 0), ifoClose);
+    if(!vmg_file.get())
     {
         problem("DVDPerfectThread could not open VMG info.");
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        DVDClose(the_dvd);
-        dvd_device_access->unlock();
         return false;
     }
     tt_srpt_t *tt_srpt = vmg_file->tt_srpt;
@@ -337,25 +381,15 @@
     if(title_number < 0 || title_number > tt_srpt->nr_of_srpts )
     {
         problem(QString("DVDPerfectThread could not open title number %1").arg(title_number + 1));
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        ifoClose(vmg_file);
-        DVDClose(the_dvd);
-        dvd_device_access->unlock();
         return false;
     }
 
-    ifo_handle_t *vts_file = ifoOpen(the_dvd, tt_srpt->title[title_number].title_set_nr);
-    if(!vts_file)
+    SmartHandle<ifo_handle_t *> vts_file(
+            ifoOpen(the_dvd.get(), tt_srpt->title[title_number].title_set_nr),
+            ifoClose);
+    if(!vts_file.get())
     {
         problem("DVDPerfectThread could not open the title's info file");
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        ifoClose(vmg_file);
-        DVDClose(the_dvd);
-        dvd_device_access->unlock();
         return false;
     }
 
@@ -388,19 +422,14 @@
     //  OK ... now actually open
     //    
     
-    title = DVDOpenFile(the_dvd, 
-                        tt_srpt->title[ title_number ].title_set_nr, 
-                        DVD_READ_TITLE_VOBS );
-    if(!title)
+    SmartHandle<dvd_file_t *> title(
+            DVDOpenFile(the_dvd.get(),
+                    tt_srpt->title[title_number].title_set_nr,
+                    DVD_READ_TITLE_VOBS),
+            DVDCloseFile);
+    if(!title.get())
     {
         problem("DVDPerfectThread could not open the title's actual VOB(s)");
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        ifoClose(vts_file);
-        ifoClose(vmg_file);
-        DVDClose(the_dvd);
-        dvd_device_access->unlock();
         return false;
     }
     
@@ -408,6 +437,8 @@
 
     QTime job_time;
     job_time.start();
+
+    unsigned char video_data[ 1024 * DVD_VIDEO_LB_LEN ];
     
     int next_cell = start_cell;    
     for(int cur_cell = start_cell; next_cell < cur_pgc->nr_of_cells; )
@@ -445,18 +476,10 @@
             //  Read the NAV packet.
             //            
             
-            int len = DVDReadBlocks( title, (int) cur_pack, 1, video_data );
+            int len = DVDReadBlocks(title.get(), (int) cur_pack, 1, video_data);
             if( len != 1)
             {
                 problem(QString("DVDPerfectThread read failed for block %1").arg(cur_pack));
-                ifoClose(vts_file);
-                ifoClose(vmg_file);
-                DVDCloseFile( title );
-                DVDClose(the_dvd);
-                dvd_device_access->unlock();
-                ripfile->remove();
-                delete ripfile;
-                ripfile = NULL;
                 return false;
             }
             
@@ -496,21 +519,14 @@
             //  Read in and output cursize packs
             //
             
-            len = DVDReadBlocks( title, (int)cur_pack, cur_output_size, video_data );
+            len = DVDReadBlocks(title.get(), (int)cur_pack, cur_output_size,
+                    video_data);
             if( len != (int) cur_output_size )
             {
                 problem(QString("DVDPerfectThread read failed for %1 blocks at %2") 
                         .arg(cur_output_size)
                         .arg(cur_pack)
                        );
-                ripfile->remove();
-                delete ripfile;
-                ripfile = NULL;
-                ifoClose(vts_file);
-                ifoClose(vmg_file);
-                DVDCloseFile( title );
-                DVDClose(the_dvd);
-                dvd_device_access->unlock();
                 return false;
             }
             
@@ -518,17 +534,10 @@
             overall_progress = subjob_progress * sub_to_overall_multiple;
             updateSubjobString(job_time.elapsed() / 1000, 
                                QObject::tr("Ripping to file ~"));
-            if(!ripfile->writeBlocks(video_data, cur_output_size * DVD_VIDEO_LB_LEN))
+            if(!ripfile.writeBlocks(video_data,
+                            cur_output_size * DVD_VIDEO_LB_LEN))
             {
                 problem("Couldn't write blocks during a rip. Filesystem size exceeded? Disc full?");
-                ripfile->remove();
-                delete ripfile;
-                ripfile = NULL;
-                DVDCloseFile( title );
-                ifoClose(vts_file);
-                ifoClose(vmg_file);
-                DVDClose(the_dvd);
-                dvd_device_access->unlock();
                 return false;
             }
 
@@ -544,14 +553,6 @@
             if(!keepGoing())
             {
                 problem("abandoned job because master control said we need to shut down");
-                ripfile->remove();
-                delete ripfile;
-                ripfile = NULL;
-                DVDCloseFile( title );
-                ifoClose(vts_file);
-                ifoClose(vmg_file);
-                DVDClose(the_dvd);
-                dvd_device_access->unlock();
                 return false;
             }
         }
@@ -561,22 +562,13 @@
     //  Wow, we're done.
     //
 
-    ifoClose(vts_file);
-    ifoClose(vmg_file);
-    DVDCloseFile( title );
-    DVDClose(the_dvd);
-    ripfile->close();
-    dvd_device_access->unlock();
+    ripfile.close();
     sendLoggingEvent("job thread finished ripping dvd title");
     return true;
 }
 
 DVDThread::~DVDThread()
 {
-    if(ripfile);
-    {
-        delete ripfile;
-    }
 }
 
 /*
@@ -645,31 +637,27 @@
         }
     }
 
+    MutexUnlocker qmul(dvd_device_access);
     if(!keepGoing())
     {
         problem("abandoned job because master control said we need to shut down");
-        dvd_device_access->unlock();
         return false;
     }
 
-    ripfile = new RipFile(destination_file_string, ".iso");
-    if(!ripfile->open(IO_WriteOnly | IO_Raw | IO_Truncate, false))
+    RipFile ripfile(destination_file_string, ".iso", true);
+    if(!ripfile.open(IO_WriteOnly | IO_Raw | IO_Truncate, false))
     {
-        problem(QString("DVDISOCopyThread could not open output file: %1").arg(ripfile->name()));
-        dvd_device_access->unlock();
+        problem(QString("DVDISOCopyThread could not open output file: %1")
+                .arg(ripfile.name()));
         return false;
     }
 
-    sendLoggingEvent(QString("ISO DVD image copy to: %1").arg(ripfile->name()));
+    sendLoggingEvent(QString("ISO DVD image copy to: %1").arg(ripfile.name()));
 
     int file = open( dvd_device_location, O_RDONLY );
     if(file == -1)
     {
         problem(QString("DVDISOCopyThread could not open dvd device: %1").arg(dvd_device_location));
-        ripfile->remove();
-        delete ripfile;
-        ripfile = NULL;
-        dvd_device_access->unlock();
         return false;
     }
 
@@ -690,13 +678,6 @@
         {
             perror("read");
             problem(QString("DVDISOCopyThread dvd device read error"));
-            ripfile->remove();
-            if (ripfile)
-            {
-                delete ripfile;
-                ripfile = NULL;
-            }
-            dvd_device_access->unlock();
             return false;
         }
         if(bytes_read == 0)
@@ -704,16 +685,9 @@
             break;
         }
 
-        if(!ripfile->writeBlocks(buffer, bytes_read))
+        if(!ripfile.writeBlocks(buffer, bytes_read))
         {
             problem(QString("DVDISOCopyThread rip file write error"));
-            ripfile->remove();
-            if (ripfile)
-            {
-                delete ripfile;
-                ripfile = NULL;
-            }                
-            dvd_device_access->unlock();
             return false;
         }
 
@@ -732,24 +706,11 @@
         if(!keepGoing())
         {
             problem("abandoned job because master control said we need to shut down");
-            ripfile->remove();
-            if (ripfile)
-            {
-                delete ripfile;
-                ripfile = NULL;
-            }                
-            dvd_device_access->unlock();
             return false;
         }
     }
 
-    ripfile->close();
-    if (ripfile)
-    {
-        delete ripfile;
-        ripfile = NULL;
-    }        
-    dvd_device_access->unlock();
+    ripfile.close();
     sendLoggingEvent("job thread finished copying ISO image");
     return true;
 }
@@ -1451,16 +1412,6 @@
     //
     if(working_directory)
     {
-        if(ripfile)
-        {
-            ripfile->remove();
-            if (ripfile)
-            {
-                delete ripfile;
-                ripfile = NULL;
-            }                
-        }
-            
         if(two_pass)
         {
             working_directory->remove("twopass.log");
@@ -1495,10 +1446,4 @@
     {
         delete tc_process;
     }
-    
-    if(ripfile)
-    {
-        delete ripfile;
-    }
 }
-
Index: dvdprobe.cpp
===================================================================
--- dvdprobe.cpp	(revision 7004)
+++ dvdprobe.cpp	(working copy)
@@ -21,6 +21,7 @@
 #include <mythtv/mythcontext.h>
 #include <mythtv/mythdbcon.h>
 
+#include <dvdread/ifo_read.h>
 
 DVDSubTitle::DVDSubTitle(int subtitle_id, const QString &a_language)
 {
Index: jobthread.h
===================================================================
--- jobthread.h	(revision 7004)
+++ jobthread.h	(working copy)
@@ -12,12 +12,6 @@
 
 #include <qthread.h>
 #include <qstringlist.h>
-#include <qfile.h>
-#include <qprocess.h>
-#include <dvdread/dvd_reader.h>
-#include <dvdread/ifo_types.h>
-#include <dvdread/ifo_read.h>
-#include <dvdread/nav_read.h>
 
 #include "fileobs.h"
 
@@ -113,14 +107,10 @@
                           const QString &extension,
                           bool multiple_files);
   
-    RipFile      *ripfile;
     QMutex       *dvd_device_access;
     QString      dvd_device_location;
     QString      destination_file_string;
     int          dvd_title;
-    dvd_reader_t *the_dvd;
-    dvd_file_t   *title;
-    unsigned char video_data[ 1024 * DVD_VIDEO_LB_LEN ];
     QString      rip_name;
 };
 
@@ -216,7 +206,7 @@
     int          quality;
     QDir         *working_directory;
     QStringList  tc_arguments;
-    QProcess     *tc_process;
+    class QProcess     *tc_process;
     bool         two_pass;
     int          audio_track;
     int          length_in_seconds;
Index: dvdprobe.h
===================================================================
--- dvdprobe.h	(revision 7004)
+++ dvdprobe.h	(working copy)
@@ -13,8 +13,7 @@
 #include <qstring.h>
 #include <qptrlist.h>
 
-#include <dvdread/dvd_reader.h>
-#include <dvdread/ifo_read.h>
+#include <dvdread/ifo_types.h>
 
 class DVDSubTitle
 {
Index: serversocket.cpp
===================================================================
--- serversocket.cpp	(revision 7004)
+++ serversocket.cpp	(working copy)
@@ -8,6 +8,8 @@
 
 */
 
+#include <qsocket.h>
+
 #include <stdlib.h>
 #include <iostream>
 using namespace std;
Index: fileobs.cpp
===================================================================
--- fileobs.cpp	(revision 7004)
+++ fileobs.cpp	(working copy)
@@ -17,11 +17,11 @@
 #include "fileobs.h"
 #include "qdir.h"
 
-RipFile::RipFile(const QString &a_base, const QString &an_extension)
+RipFile::RipFile(const QString &a_base, const QString &an_extension,
+        bool auto_remove_bad) : base_name(a_base), extension(an_extension),
+                                   auto_remove_bad_rips(auto_remove_bad)
 {
     filesize = gContext->GetNumSetting("MTDRipSize", 0) * 1024 * 1024;
-    base_name = a_base;
-    extension = an_extension;
     active_file = NULL;
     files.clear();
     files.setAutoDelete(true);
@@ -46,6 +46,7 @@
 
 void RipFile::close()
 {
+    auto_remove_bad_rips = false;
     if(active_file)
     {
         active_file->close();
@@ -155,7 +156,9 @@
 
 RipFile::~RipFile()
 {
+    if (active_file && auto_remove_bad_rips)
+    {
+        remove();
+    }
     files.clear();
 }
-
-
Index: mtd.cpp
===================================================================
--- mtd.cpp	(revision 7004)
+++ mtd.cpp	(working copy)
@@ -11,6 +11,7 @@
 #include <qstringlist.h>
 #include <qregexp.h>
 #include <qdir.h>
+#include <qtimer.h>
 
 #include <mythtv/util.h>
 #include <mythtv/mythcontext.h>
Index: serversocket.h
===================================================================
--- serversocket.h	(revision 7004)
+++ serversocket.h	(working copy)
@@ -10,11 +10,10 @@
 
 */
 
-#include <qsocket.h>
 #include <qserversocket.h>
 
+class QSocket;
 
-
 class MTDServerSocket : public QServerSocket
 {
 
Index: fileobs.h
===================================================================
--- fileobs.h	(revision 7004)
+++ fileobs.h	(working copy)
@@ -21,7 +21,8 @@
 
   public:
   
-    RipFile(const QString &a_base, const QString &an_extension);
+    RipFile(const QString &a_base, const QString &an_extension,
+            bool auto_remove_bad);
     ~RipFile();
     
     bool    open(int mode, bool multiple_files);
@@ -40,6 +41,7 @@
     int             access_mode;
     QPtrList<QFile> files;
     bool            use_multiple_files;
+    bool            auto_remove_bad_rips;
 };
 
 #endif  // fileobs_h_
Index: mtd.h
===================================================================
--- mtd.h	(revision 7004)
+++ mtd.h	(working copy)
@@ -11,9 +11,7 @@
 */
 
 #include <qobject.h>
-#include <qstringlist.h>
 #include <qptrlist.h>
-#include <qtimer.h>
 
 #include "logging.h"
 #include "serversocket.h"
@@ -21,6 +19,9 @@
 #include "dvdprobe.h"
 #include "threadevents.h"
 
+class QStringList;
+class QTimer;
+
 class DiscCheckingThread : public QThread
 {
 
Index: logging.h
===================================================================
--- logging.h	(revision 7004)
+++ logging.h	(working copy)
@@ -9,14 +9,10 @@
 	Headers for logging object of the myth transcoding daemon
 
 */
-#include <unistd.h>
-#include <iostream>
-using namespace std;
 
 #include <qobject.h>
 #include <qstring.h>
 #include <qfile.h>
-#include <qtextstream.h>
 
 
 class MTDLogger : public QObject
