add background file eraser class for asynchronous file deletion
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 30 Mar 2006 23:32:28 +0000 (23:32 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Thu, 30 Mar 2006 23:32:28 +0000 (23:32 +0000)
lib/components/Makefile.am
lib/components/file_eraser.cpp [new file with mode: 0644]
lib/components/file_eraser.h [new file with mode: 0644]
lib/python/enigma_python.i
lib/service/servicedvb.cpp

index c25791a744f7df9a7296baa23ef8ab42e7e55a7d..70bd8b6b5427ee4ec5b0beaca5e34faa1ea07dc7 100644 (file)
@@ -3,5 +3,5 @@ INCLUDES = \
 
 noinst_LIBRARIES = libenigma_components.a
 
-libenigma_components_a_SOURCES = scan.cpp listboxepg.cpp
+libenigma_components_a_SOURCES = scan.cpp listboxepg.cpp file_eraser.cpp
        
\ No newline at end of file
diff --git a/lib/components/file_eraser.cpp b/lib/components/file_eraser.cpp
new file mode 100644 (file)
index 0000000..bc26bf7
--- /dev/null
@@ -0,0 +1,83 @@
+#include <lib/components/file_eraser.h>
+#include <lib/base/eerror.h>
+#include <lib/base/init.h>
+#include <lib/base/init_num.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+
+eBackgroundFileEraser *eBackgroundFileEraser::instance;
+
+eBackgroundFileEraser::eBackgroundFileEraser()
+       :messages(this,1), stop_thread_timer(this)
+{
+       if (!instance)
+               instance=this;
+       CONNECT(messages.recv_msg, eBackgroundFileEraser::gotMessage);
+       CONNECT(stop_thread_timer.timeout, eBackgroundFileEraser::idle);
+}
+
+void eBackgroundFileEraser::idle()
+{
+       quit(0);
+}
+
+eBackgroundFileEraser::~eBackgroundFileEraser()
+{
+       messages.send(Message::quit);
+       if ( thread_running() )
+               kill();
+       if (instance==this)
+               instance=0;
+}
+
+void eBackgroundFileEraser::thread()
+{
+       nice(5);
+       reset();
+       runLoop();
+       stop_thread_timer.stop();
+}
+
+void eBackgroundFileEraser::erase(const char *filename)
+{
+       if (filename)
+       {
+               char buf[255];
+               snprintf(buf, 255, "%s.$$$", filename);
+               if (rename(filename, buf)<0)
+                       ;/*perror("rename file failed !!!");*/
+               else
+               {
+                       messages.send(Message(Message::erase, strdup(buf)));
+                       if (!thread_running())
+                               run();
+               }
+       }
+}
+
+void eBackgroundFileEraser::gotMessage(const Message &msg )
+{
+       switch (msg.type)
+       {
+               case Message::erase:
+                       if ( msg.filename )
+                       {
+                               if ( ::unlink(msg.filename) < 0 )
+                                       eDebug("remove file %s failed (%m)", msg.filename);
+                               else
+                                       eDebug("file %s erased", msg.filename);
+                               free((char*)msg.filename);
+                       }
+                       stop_thread_timer.start(2000, true); // stop thread in two seconds
+                       break;
+               case Message::quit:
+                       quit(0);
+                       break;
+               default:
+                       eDebug("unhandled thread message");
+       }
+}
+
+eAutoInitP0<eBackgroundFileEraser> init_eBackgroundFilEraser(eAutoInitNumbers::configuration+1, "Background File Eraser");
diff --git a/lib/components/file_eraser.h b/lib/components/file_eraser.h
new file mode 100644 (file)
index 0000000..6cb13dd
--- /dev/null
@@ -0,0 +1,41 @@
+#ifndef __lib_components_file_eraser_h
+#define __lib_components_file_eraser_h
+
+#include <lib/base/thread.h>
+#include <lib/base/message.h>
+#include <lib/base/ebase.h>
+
+class eBackgroundFileEraser: public eMainloop, private eThread, public Object
+{
+       struct Message
+       {
+               int type;
+               const char *filename;
+               enum
+               {
+                       erase,
+                       quit
+               };
+               Message(int type=0, const char *filename=0)
+                       :type(type), filename(filename)
+               {}
+       };
+       eFixedMessagePump<Message> messages;
+       static eBackgroundFileEraser *instance;
+       void gotMessage(const Message &message);
+       void thread();
+       void idle();
+       eTimer stop_thread_timer;
+#ifndef SWIG
+public:
+#endif
+       eBackgroundFileEraser();
+       ~eBackgroundFileEraser();
+#ifdef SWIG
+public:
+#endif
+       void erase(const char * filename);
+       static eBackgroundFileEraser *getInstance() { return instance; }
+};
+
+#endif
index 29294b120f0ea3635acd441d9d9a7dde7cb2f369..eef5ec17b45a0774a1fd7600bc4257d46095617a 100644 (file)
@@ -67,6 +67,7 @@ is usually caused by not marking PSignals as immutable.
 #include <lib/service/listboxservice.h>
 #include <lib/components/scan.h>
 #include <lib/components/listboxepg.h>
+#include <lib/components/file_eraser.h>
 #include <lib/nav/pcore.h>
 #include <lib/actions/action.h>
 #include <lib/gdi/gfont.h>
@@ -182,6 +183,7 @@ typedef long time_t;
 %include <lib/service/listboxservice.h>
 %include <lib/components/scan.h>
 %include <lib/components/listboxepg.h>
+%include <lib/components/file_eraser.h>
 %include <lib/nav/pcore.h>
 %include <lib/actions/action.h>
 %include <lib/gdi/gfont.h>
index 6e2d9610dbbaf1c94cf6065aa68ff99bd16bb896..033d13d3906702be1a6fb0ae843a59a1a6e162c6 100644 (file)
@@ -10,6 +10,7 @@
 #include <lib/dvb/db.h>
 #include <lib/dvb/decoder.h>
 
+#include <lib/components/file_eraser.h>
 #include <lib/service/servicedvbrecord.h>
 #include <lib/service/event.h>
 #include <lib/dvb/metaparser.h>
@@ -233,11 +234,18 @@ RESULT eDVBPVRServiceOfflineOperations::deleteFromDisk(int simulate)
                if (getListOfFilenames(res))
                        return -1;
                
+               eBackgroundFileEraser *eraser = eBackgroundFileEraser::getInstance();
+               if (!eraser)
+                       eDebug("FATAL !! can't get background file eraser");
+               
                                /* TODO: deferred removing.. */
                for (std::list<std::string>::iterator i(res.begin()); i != res.end(); ++i)
                {
                        eDebug("Removing %s...", i->c_str());
-                       ::unlink(i->c_str());
+                       if (eraser)
+                               eraser->erase(i->c_str());
+                       else
+                               ::unlink(i->c_str());
                }
                
                return 0;
@@ -248,6 +256,19 @@ RESULT eDVBPVRServiceOfflineOperations::getListOfFilenames(std::list<std::string
 {
        res.clear();
        res.push_back(m_ref.path);
+
+// handling for old splitted recordings (enigma 1)
+       char buf[255];
+       int slice=1;
+       while(true)
+       {
+               snprintf(buf, 255, "%s.%03d", m_ref.path.c_str(), slice++);
+               struct stat s;
+               if (stat(buf, &s) < 0)
+                       break;
+               res.push_back(buf);
+       }       
+
        res.push_back(m_ref.path + ".meta");
        res.push_back(m_ref.path + ".ap");
        res.push_back(m_ref.path + ".cuts");