libzypp 17.37.10

CleanerThread.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
11
12#include <zypp-core/base/CleanerThread_p.h>
13#include <zypp-core/zyppng/base/private/threaddata_p.h>
14#include <zypp-core/zyppng/base/private/linuxhelpers_p.h>
15#include <algorithm>
16#include <thread>
17#include <mutex>
18#include <condition_variable>
19#include <chrono>
20#include <vector>
21#include <sys/types.h>
22#include <sys/wait.h>
23
24 struct CleanerData
25{
26 static CleanerData &instance ()
27 {
28 // C++11 requires that this is thread safe "magic statics"
29 // this is a intentional leak and will live until the application exits
30 static CleanerData *data( new CleanerData );
31 return *data;
32 }
33
34 CleanerData ()
35 {
36 std::thread t ( [&](){
37 this->run();
38 } );
39 t.detach(); //we will control the thread otherwise
40 }
41
42 void run ()
43 {
44 // force the kernel to pick another thread to handle signals
45 zyppng::blockAllSignalsForCurrentThread();
46
47 zyppng::ThreadData::current().setName("Zypp-Cleaner");
48
49 std::unique_lock<std::mutex> lk( _m );
50
51 while ( true )
52 {
53 auto filter = []( pid_t pid ){
54 int status = 0;
55 int res = waitpid( pid, &status, WNOHANG );
56 // we either got an error, or the child has exited, remove it from list
57 bool removeMe = ( res == -1 || res == pid );
58 return removeMe;
59 };
60 _watchedPIDs.erase( std::remove_if( _watchedPIDs.begin(), _watchedPIDs.end(), filter ), _watchedPIDs.end() );
61
62 if ( _watchedPIDs.size() )
63 _cv.wait_for( lk, std::chrono::milliseconds(100) );
64 else
65 _cv.wait( lk );
66 }
67 }
68
69 std::mutex _m; // < locks all data in CleanerData, do not access it without owning the mutex
70 std::condition_variable _cv;
71
72 std::vector<pid_t> _watchedPIDs;
73};
74
75
76 void zypp::CleanerThread::watchPID( pid_t pid_r )
77{
78 CleanerData &data = CleanerData::instance();
79 {
80 std::lock_guard<std::mutex> guard( data._m );
81 data._watchedPIDs.push_back( pid_r );
82 }
83 //wake the thread up
84 data._cv.notify_one();
85}
CleanerThread_p.h
zypp::CleanerThread::watchPID
static void watchPID(pid_t pid_r)
Definition CleanerThread.cc:76
linuxhelpers_p.h
zyppng::blockAllSignalsForCurrentThread
bool blockAllSignalsForCurrentThread()
Definition linuxhelpers.cc:15
CleanerData
Definition CleanerThread.cc:25
CleanerData::_cv
std::condition_variable _cv
Definition CleanerThread.cc:70
CleanerData::_watchedPIDs
std::vector< pid_t > _watchedPIDs
Definition CleanerThread.cc:72
CleanerData::run
void run()
Definition CleanerThread.cc:42
CleanerData::CleanerData
CleanerData()
Definition CleanerThread.cc:34
CleanerData::instance
static CleanerData & instance()
Definition CleanerThread.cc:26
CleanerData::_m
std::mutex _m
Definition CleanerThread.cc:69
zyppng::ThreadData::setName
void setName(T &&name)
Definition threaddata_p.h:18
zyppng::ThreadData::current
static ZYPP_API ThreadData & current()
Definition threaddata.cc:16
threaddata_p.h