From 7c15db185f22fe0a035733a82c4c37eecf9dfcd0 Mon Sep 17 00:00:00 2001 From: martii Date: Wed, 27 Nov 2013 20:08:32 +0100 Subject: [PATCH] add thread for determining free hdd (recording dir) space, enable hdd usage icons on vfd (untested) Conflicts: data/locale/deutsch.locale data/locale/english.locale src/driver/simple_display.cpp src/gui/hdd_menu.cpp src/gui/infoviewer_bb.cpp src/gui/infoviewer_bb.h src/gui/moviebrowser.cpp src/gui/record_setup.cpp src/neutrino.cpp src/system/ytcache.h --- data/locale/deutsch.locale | 6 +- data/locale/english.locale | 4 ++ src/driver/lcdd.h | 1 + src/gui/infoviewer_bb.cpp | 39 +++--------- src/gui/infoviewer_bb.h | 7 +-- src/gui/moviebrowser.cpp | 2 + src/gui/osd_setup.cpp | 15 ++++- src/gui/record_setup.cpp | 2 + src/neutrino.cpp | 3 + src/system/Makefile.am | 1 + src/system/hddstat.cpp | 124 +++++++++++++++++++++++++++++++++++++ src/system/hddstat.h | 55 ++++++++++++++++ src/system/locals.h | 4 ++ src/system/locals_intern.h | 4 ++ src/system/settings.h | 2 + 15 files changed, 231 insertions(+), 38 deletions(-) create mode 100644 src/system/hddstat.cpp create mode 100644 src/system/hddstat.h diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 2c85b4cf7..03f8dfc1d 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -689,7 +689,10 @@ hdd_set_recdir Diesen Datenträger für die Aufnahme nutzen? hdd_settings Laufwerke hdd_sleep Ausschalten nach... hdd_slow Langsam -hdd_umount Unmount +hdd_statfs Füllstands-Abfrage +hdd_statfs_always immer +hdd_statfs_recording nur während Aufnahme +hdd_umount Aushängen hdd_umount_warn Laufwerk aushängen hdd_umounted Laufwerk entfernt imageinfo.creator Ersteller: @@ -946,6 +949,7 @@ menu.hint_hdd_fmt Wählen Sie das Datenträgerformat aus menu.hint_hdd_format Erstellt eine Partition auf dem Datenträger und formatiert diese menu.hint_hdd_noise Setzen Sie Parameter für das Automatic Acoustic Management.\nNicht alle Laufwerke unterstützen diese Funktion menu.hint_hdd_sleep Dieser Wert definiert, nach wieviel Minuten die Festplatte bei Inaktivität in den Sleep-Modus geschaltet wird +menu.hint_hdd_statfs Legen Sie fest, wann die Aufnahmeverzeichnis-Füllstandsanzeige im InfoViewer (und ggf. am VFD-Display) aktualisiert werden darf menu.hint_hdd_tools Formatieren Sie die gefundenen Datenträger bzw. überprüfen Sie deren Dateisystem menu.hint_head_back Ändern Sie die Titel-Hintergrundfarbe menu.hint_head_textcolor Ändern Sie die Titel-Textfarbe diff --git a/data/locale/english.locale b/data/locale/english.locale index 66f52b9d7..834545596 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -689,6 +689,9 @@ hdd_set_recdir Use device for recording ? hdd_settings Data Storage hdd_sleep Switch off after... hdd_slow Slow +hdd_statfs Fill level query +hdd_statfs_always always +hdd_statfs_recording while recording only hdd_umount Unmount hdd_umount_warn unmount device hdd_umounted Device removed @@ -946,6 +949,7 @@ menu.hint_hdd_fmt Select the data storage format menu.hint_hdd_format Create HDD partition and format it menu.hint_hdd_noise Set Automatic Acoustic Management\nnot all drives support this menu.hint_hdd_sleep Select time to stop hdd on inactivity +menu.hint_hdd_statfs Specify when the recording directory fill level in infoviewer and, if available, on VFD, may be updated menu.hint_hdd_tools Initialize HDD, check filesystem menu.hint_head_back Change GUI title background color menu.hint_head_textcolor Change GUI window title text color diff --git a/src/driver/lcdd.h b/src/driver/lcdd.h index 6689a79de..92871e253 100644 --- a/src/driver/lcdd.h +++ b/src/driver/lcdd.h @@ -178,6 +178,7 @@ class CLCD void setMode(const MODES m, const char * const title = ""); MODES getMode() { return mode; }; + void setHddUsage(int perc); void showServicename(const std::string name, const bool perform_wakeup = true); // UTF-8 void setEPGTitle(const std::string title); diff --git a/src/gui/infoviewer_bb.cpp b/src/gui/infoviewer_bb.cpp index 87e2e9d51..d4ce67366 100644 --- a/src/gui/infoviewer_bb.cpp +++ b/src/gui/infoviewer_bb.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -80,9 +81,8 @@ CInfoViewerBB::CInfoViewerBB() pthread_detach(scrambledT); } #endif - hddpercent = 0; - hddperT = 0; - hddperTflag = false; + hddscale = NULL; + sysscale = NULL; bbIconInfo[0].x = 0; bbIconInfo[0].h = 0; BBarY = 0; @@ -108,13 +108,6 @@ void CInfoViewerBB::Init() bbButtonInfo[i].x = -1; } - // get HDD info in a separate thread - if (g_settings.infobar_show_sysfs_hdd && !hddperTflag) { - hddperTflag=true; - pthread_create(&hddperT, NULL, hddperThread, (void*) this); - pthread_detach(hddperT); - } - InfoHeightY_Info = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight() + 5; setBBOffset(); @@ -127,11 +120,10 @@ CInfoViewerBB::~CInfoViewerBB() pthread_cancel(scrambledT); scrambledT = 0; } - if(hddperTflag) { - pthread_cancel(hddperT); - hddperT = 0; - hddperTflag = false; - } + if (hddscale) + delete hddscale; + if (sysscale) + delete sysscale; } CInfoViewerBB* CInfoViewerBB::getInstance() @@ -653,25 +645,10 @@ void CInfoViewerBB::showSysfsHdd() percent = (int)((u * 100ULL) / t); showBarSys(percent); - if (check_dir(g_settings.network_nfs_recordingdir.c_str()) == 0) - showBarHdd(hddpercent); - else - showBarHdd(-1); + showBarHdd(cHddStat::getInstance()->getPercent()); } } -void* CInfoViewerBB::hddperThread(void *arg) -{ - CInfoViewerBB *infoViewerBB = (CInfoViewerBB*) arg; - uint64_t t, u; - if (get_fs_usage(g_settings.network_nfs_recordingdir.c_str(), t, u)) - infoViewerBB->hddpercent = (int)((u * 100ULL) / t); - else - infoViewerBB->hddpercent = 0; - infoViewerBB->hddperTflag=false; - pthread_exit(NULL); -} - void CInfoViewerBB::showBarSys(int percent) { if (is_visible){ diff --git a/src/gui/infoviewer_bb.h b/src/gui/infoviewer_bb.h index d0e42f7b8..831e2d793 100644 --- a/src/gui/infoviewer_bb.h +++ b/src/gui/infoviewer_bb.h @@ -40,6 +40,7 @@ #include #include #include +#include #include "widget/menue.h" #include #include @@ -125,13 +126,9 @@ class CInfoViewerBB void showBarSys(int percent = 0); void showBarHdd(int percent = 0); - int hddpercent; - pthread_t hddperT; - static void* hddperThread(void *arg); - bool hddperTflag; + CInfoViewerBB(); public: - CInfoViewerBB(); ~CInfoViewerBB(); static CInfoViewerBB* getInstance(); void Init(void); diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 0c8445f4b..27b3b491d 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -66,6 +66,7 @@ #include #include +#include extern CPictureViewer * g_PicViewer; static CProgressBar *timescale; @@ -2520,6 +2521,7 @@ void CMovieBrowser::updateDir(void) if(!g_settings.network_nfs_recordingdir.empty()) { addDir(g_settings.network_nfs_recordingdir, &m_settings.storageDirRecUsed); + cHddStat::getInstance()->statOnce(); } for(int i = 0; i < MB_MAX_DIRS; i++) diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 49e96e938..f8d99fdce 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -877,6 +877,14 @@ void COsdSetup::showOsdMenusSetup(CMenuWidget *menu_menus) submenu_menus->addItem(mc); } +#define HDD_STATFS_OPTION_COUNT 3 +const CMenuOptionChooser::keyval HDD_STATFS_OPTIONS[HDD_STATFS_OPTION_COUNT] = +{ + { SNeutrinoSettings::HDD_STATFS_OFF, LOCALE_OPTIONS_OFF }, + { SNeutrinoSettings::HDD_STATFS_ALWAYS, LOCALE_HDD_STATFS_ALWAYS }, + { SNeutrinoSettings::HDD_STATFS_RECORDING, LOCALE_HDD_STATFS_RECORDING } +}; + //infobar void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) { @@ -915,6 +923,11 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) mc->setHint("", LOCALE_MENU_HINT_INFOBAR_FILESYS); menu_infobar->addItem(mc); + // hdd update + mc = new CMenuOptionChooser(LOCALE_HDD_STATFS, &g_settings.hdd_statfs_mode, HDD_STATFS_OPTIONS, HDD_STATFS_OPTION_COUNT, true); + mc->setHint("", LOCALE_MENU_HINT_HDD_STATFS); + menu_infobar->addItem(mc); + // resolution mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_INFOBAR_SHOW_RES, &g_settings.infobar_show_res, INFOBAR_SHOW_RES_MODE_OPTIONS, INFOBAR_SHOW_RES_MODE_OPTION_COUNT, true); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_RES); @@ -952,7 +965,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) // radiotext mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_RADIOTEXT, &g_settings.radiotext_enable, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, this); mc->setHint("", LOCALE_MENU_HINT_INFOBAR_RADIOTEXT); - menu_infobar->addItem(mc); + menu_infobar->addItem(mc); } //channellist diff --git a/src/gui/record_setup.cpp b/src/gui/record_setup.cpp index 924a7e007..c45d515d7 100644 --- a/src/gui/record_setup.cpp +++ b/src/gui/record_setup.cpp @@ -54,6 +54,7 @@ #include #include +#include CRecordSetup::CRecordSetup() { @@ -99,6 +100,7 @@ int CRecordSetup::exec(CMenuTarget* parent, const std::string &actionKey) printf("New timeshift dir: %s\n", timeshiftDir.c_str()); CRecordManager::getInstance()->SetTimeshiftDirectory(timeshiftDir); } + cHddStat::getInstance()->setDir(g_settings.network_nfs_recordingdir); } return res; } diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 7f4c91943..2e0e4f1d3 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -421,6 +421,7 @@ int CNeutrinoApp::loadSetup(const char * fname) g_settings.hdd_fs = configfile.getInt32( "hdd_fs", 0); g_settings.hdd_sleep = configfile.getInt32( "hdd_sleep", 120); g_settings.hdd_noise = configfile.getInt32( "hdd_noise", 254); + g_settings.hdd_statfs_mode = configfile.getInt32( "hdd_statfs_mode", SNeutrinoSettings::HDD_STATFS_RECORDING); g_settings.shutdown_real = configfile.getBool("shutdown_real" , false ); g_settings.shutdown_real_rcdelay = configfile.getBool("shutdown_real_rcdelay", false ); @@ -987,6 +988,7 @@ void CNeutrinoApp::saveSetup(const char * fname) configfile.setInt32( "hdd_fs", g_settings.hdd_fs); configfile.setInt32( "hdd_sleep", g_settings.hdd_sleep); configfile.setInt32( "hdd_noise", g_settings.hdd_noise); + configfile.setInt32( "hdd_statfs_mode", g_settings.hdd_statfs_mode); configfile.setBool("shutdown_real" , g_settings.shutdown_real ); configfile.setBool("shutdown_real_rcdelay", g_settings.shutdown_real_rcdelay); configfile.setInt32("shutdown_count" , g_settings.shutdown_count); @@ -2121,6 +2123,7 @@ TIMER_START(); delete hintBox; cSysLoad::getInstance(); + cHddStat::getInstance(); TIMER_STOP("################################## after all ##################################"); RealRun(personalize.getWidget(0)/**main**/); diff --git a/src/system/Makefile.am b/src/system/Makefile.am index bee2e4350..bd9dd233b 100644 --- a/src/system/Makefile.am +++ b/src/system/Makefile.am @@ -36,6 +36,7 @@ libneutrino_system_a_SOURCES = \ debug.cpp \ flashtool.cpp \ fsmounter.cpp \ + hddstat.cpp \ httptool.cpp \ lastchannel.cpp \ localize.cpp \ diff --git a/src/system/hddstat.cpp b/src/system/hddstat.cpp new file mode 100644 index 000000000..37318e795 --- /dev/null +++ b/src/system/hddstat.cpp @@ -0,0 +1,124 @@ +/* + Neutrino-HD + + License: GPL + + (C) 2013 martii + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __USE_FILE_OFFSET64 +#define __USE_FILE_OFFSET64 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hddstat.h" +#include +//#include +#include +#include +#include + +static cHddStat *instance = NULL; + +cHddStat *cHddStat::getInstance(void) +{ + if (!instance) + instance = new cHddStat; + return instance; +} + +void cHddStat::setDir(std::string &_dir) +{ + pthread_mutex_lock(&mutex); + dir = _dir; + pthread_mutex_unlock(&mutex); +} + +void *cHddStat::Run(void *arg) +{ + set_threadname("hddstat"); + class cHddStat *caller = (class cHddStat *)arg; + + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + long long oldperc = -2; + caller->once = g_settings.hdd_statfs_mode != SNeutrinoSettings::HDD_STATFS_OFF; + while (caller->running) { + std::string _dir; + pthread_mutex_lock(&caller->mutex); + _dir = caller->dir; + pthread_mutex_unlock(&caller->mutex); + long long perc = -1; + + if (caller->once || (g_settings.hdd_statfs_mode == SNeutrinoSettings::HDD_STATFS_ALWAYS) + || (g_settings.hdd_statfs_mode == SNeutrinoSettings::HDD_STATFS_RECORDING && (CRecordManager::getInstance()->RecordingStatus() /* || cYTCache::getInstance()->isActive() */ ))) { + caller->once = false; + struct statfs st; + if (statfs(_dir.c_str(), &st) || !st.f_blocks) + perc = -1; + else + perc = 100 * (long long)(st.f_blocks - st.f_bfree) / (long long) st.f_blocks; + } else + perc = oldperc; + + if (oldperc != perc) { + oldperc = perc; + caller->percent = (int) perc; + //CVFD::getInstance()->setHddUsage(perc); + } + ts.tv_sec += caller->period; + sem_timedwait(&caller->sem, &ts); + } + pthread_exit(NULL); +} + +cHddStat::cHddStat(void) +{ + dir = g_settings.network_nfs_recordingdir; + period = 60; + percent = -1; + running = true; + sem_init(&sem, 0, 0); + pthread_mutex_init(&mutex, NULL); + if (pthread_create(&thr, NULL, Run, this)) + running = false; +} + +cHddStat::~cHddStat(void) +{ + if (running) { + running = false; + sem_post(&sem); + pthread_join(thr, NULL); + } + sem_destroy(&sem); +} + +void cHddStat::statOnce(void) +{ + once = true; + sem_post(&sem); +} diff --git a/src/system/hddstat.h b/src/system/hddstat.h new file mode 100644 index 000000000..caa6f7e8d --- /dev/null +++ b/src/system/hddstat.h @@ -0,0 +1,55 @@ +/* + Neutrino-HD + + License: GPL + + (C) 2013 martii + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __SYSTEM_HDDSTAT__H_ +#define __SYSTEM_HDDSTAT__H_ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +class cHddStat +{ + private: + pthread_t thr; + std::string dir; + static void* Run(void *); + cHddStat(); + public: + unsigned int period; + bool running; + bool once; + int percent; + + sem_t sem; + pthread_mutex_t mutex; + ~cHddStat(void); + static cHddStat *getInstance(void); + void setDir(std::string &_dir); + void setPeriod(unsigned int _period) { period = _period; } + int getPercent(void) { return percent; } + void statOnce(void); +}; +#endif diff --git a/src/system/locals.h b/src/system/locals.h index 4374d780b..f183b5071 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -716,6 +716,9 @@ typedef enum LOCALE_HDD_SETTINGS, LOCALE_HDD_SLEEP, LOCALE_HDD_SLOW, + LOCALE_HDD_STATFS, + LOCALE_HDD_STATFS_ALWAYS, + LOCALE_HDD_STATFS_RECORDING, LOCALE_HDD_UMOUNT, LOCALE_HDD_UMOUNT_WARN, LOCALE_HDD_UMOUNTED, @@ -973,6 +976,7 @@ typedef enum LOCALE_MENU_HINT_HDD_FORMAT, LOCALE_MENU_HINT_HDD_NOISE, LOCALE_MENU_HINT_HDD_SLEEP, + LOCALE_MENU_HINT_HDD_STATFS, LOCALE_MENU_HINT_HDD_TOOLS, LOCALE_MENU_HINT_HEAD_BACK, LOCALE_MENU_HINT_HEAD_TEXTCOLOR, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index 9dbab2f22..96142db6f 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -716,6 +716,9 @@ const char * locale_real_names[] = "hdd_settings", "hdd_sleep", "hdd_slow", + "hdd_statfs", + "hdd_statfs_always", + "hdd_statfs_recording", "hdd_umount", "hdd_umount_warn", "hdd_umounted", @@ -973,6 +976,7 @@ const char * locale_real_names[] = "menu.hint_hdd_format", "menu.hint_hdd_noise", "menu.hint_hdd_sleep", + "menu.hint_hdd_statfs", "menu.hint_hdd_tools", "menu.hint_head_back", "menu.hint_head_textcolor", diff --git a/src/system/settings.h b/src/system/settings.h index 35c6f965b..732062209 100644 --- a/src/system/settings.h +++ b/src/system/settings.h @@ -662,6 +662,8 @@ struct SNeutrinoSettings int hdd_sleep; int hdd_noise; int hdd_fs; + enum { HDD_STATFS_OFF = 0, HDD_STATFS_ALWAYS, HDD_STATFS_RECORDING }; + int hdd_statfs_mode; int zap_cycle; int sms_channel; std::string font_file;