add background file eraser class for asynchronous file deletion
[enigma2.git] / lib / components / file_eraser.cpp
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");