libzypp 17.31.23
CleanerThread.cc
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8\---------------------------------------------------------------------*/
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
25{
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
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
77{
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}
static void watchPID(pid_t pid_r)
std::condition_variable _cv
std::vector< pid_t > _watchedPIDs
static CleanerData & instance()
std::mutex _m