diff options
| author | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2006-03-30 23:32:28 +0000 |
|---|---|---|
| committer | Andreas Monzner <andreas.monzner@multimedia-labs.de> | 2006-03-30 23:32:28 +0000 |
| commit | e059d69c2ce61b1ba1ae2e0b9c75eb53bb26f1bb (patch) | |
| tree | 52afd355bcf306ab0a39034148fb9f07c54c8a38 | |
| parent | 0c9e75c44d610465017a08874a5e2f585bc554aa (diff) | |
| download | enigma2-e059d69c2ce61b1ba1ae2e0b9c75eb53bb26f1bb.tar.gz enigma2-e059d69c2ce61b1ba1ae2e0b9c75eb53bb26f1bb.zip | |
add background file eraser class for asynchronous file deletion
| -rw-r--r-- | lib/components/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/components/file_eraser.cpp | 83 | ||||
| -rw-r--r-- | lib/components/file_eraser.h | 41 | ||||
| -rw-r--r-- | lib/python/enigma_python.i | 2 | ||||
| -rw-r--r-- | lib/service/servicedvb.cpp | 23 |
5 files changed, 149 insertions, 2 deletions
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 <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 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 <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 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 <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> 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 <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"); |
