From e059d69c2ce61b1ba1ae2e0b9c75eb53bb26f1bb Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Thu, 30 Mar 2006 23:32:28 +0000 Subject: [PATCH 1/1] add background file eraser class for asynchronous file deletion --- lib/components/Makefile.am | 2 +- lib/components/file_eraser.cpp | 83 ++++++++++++++++++++++++++++++++++ lib/components/file_eraser.h | 41 +++++++++++++++++ lib/python/enigma_python.i | 2 + lib/service/servicedvb.cpp | 23 +++++++++- 5 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 lib/components/file_eraser.cpp create mode 100644 lib/components/file_eraser.h diff --git a/lib/components/Makefile.am b/lib/components/Makefile.am index c25791a7..70bd8b6b 100644 --- a/lib/components/Makefile.am +++ b/lib/components/Makefile.am @@ -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 index 00000000..bc26bf7c --- /dev/null +++ b/lib/components/file_eraser.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +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 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 index 00000000..6cb13dda --- /dev/null +++ b/lib/components/file_eraser.h @@ -0,0 +1,41 @@ +#ifndef __lib_components_file_eraser_h +#define __lib_components_file_eraser_h + +#include +#include +#include + +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 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 diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 29294b12..eef5ec17 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -67,6 +67,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include #include #include #include @@ -182,6 +183,7 @@ typedef long time_t; %include %include %include +%include %include %include %include diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 6e2d9610..033d13d3 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -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::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