libzypp  17.28.8
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 {
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 
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 those signals
45  zyppng::blockSignalsForCurrentThread( { SIGTERM, SIGINT, SIGPIPE, } );
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 {
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)
void remove_if(LockSet &lockset_r, TPredicate pred_r)
Definition: Locks.cc:46
static CleanerData & instance()
std::condition_variable _cv
std::vector< pid_t > _watchedPIDs
std::mutex _m