ewmscp  ..
Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Private Attributes | Static Private Attributes | List of all members
runnerType Class Reference
Collaboration diagram for runnerType:
[legend]

Public Member Functions

 runnerType (dirQueueType &dirQueue)
 
void sum (counterType &other)
 
unsigned int getDirsDone () const
 
void process (dirQueueType &dirQueue)
 

Static Public Member Functions

static std::forward_list< runnerType > & runners ()
 
static void newWorker (dirQueueType &dirQueue)
 
static void finish (counterType &sumCounter, bool verbose)
 

Public Attributes

std::thread worker
 

Static Public Attributes

static unsigned int nWorkers
 

Private Attributes

counterType counter
 
unsigned int dirsDone
 

Static Private Attributes

static std::mutex listMutex
 
static std::condition_variable cv
 
static std::atomic< unsigned int > nActiveWorkers
 

Detailed Description

Definition at line 148 of file dirCount.cpp.

Constructor & Destructor Documentation

◆ runnerType()

runnerType::runnerType ( dirQueueType dirQueue)
inline

Definition at line 161 of file dirCount.cpp.

161  : dirsDone(0) {
162  worker = std::thread(&runnerType::process, this, std::ref(dirQueue));
163  }

References process(), and worker.

Here is the call graph for this function:

Member Function Documentation

◆ finish()

static void runnerType::finish ( counterType sumCounter,
bool  verbose 
)
inlinestatic

Definition at line 173 of file dirCount.cpp.

173  {
174  std::unique_lock<decltype(listMutex)> lock(listMutex);
175  cv.wait(lock, [] {return nActiveWorkers == 0;});
176  for (auto& runner : runners()) {
177  runner.worker.join();
178  runner.sum(sumCounter);
179  }
180  if (verbose) {
181  unsigned int realizedThreads(0);
182  unsigned int unusedThreads(0);
183  for (auto& runner : runners()) {
184  realizedThreads++;
185  if (runner.getDirsDone() == 0) {
186  unusedThreads++;
187  }
188  }
189  std::cerr << "of " << realizedThreads << " threads " << unusedThreads << " were not used\n";
190  }
191  }

References cv, listMutex, nActiveWorkers, runners(), and verbose.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getDirsDone()

unsigned int runnerType::getDirsDone ( ) const
inline

Definition at line 198 of file dirCount.cpp.

198  {
199  return dirsDone;
200  }

References dirsDone.

◆ newWorker()

static void runnerType::newWorker ( dirQueueType dirQueue)
inlinestatic

Definition at line 165 of file dirCount.cpp.

165  {
166  std::unique_lock<decltype(listMutex)> lock(listMutex);
167  if (nWorkers < nThreads) {
168  nWorkers++;
169  nActiveWorkers++;
170  runners().emplace_front(dirQueue);
171  }
172  }

References listMutex, nActiveWorkers, nThreads, nWorkers, and runners().

Referenced by main(), and process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ process()

void runnerType::process ( dirQueueType dirQueue)
inline

Definition at line 201 of file dirCount.cpp.

201  {
202  while (auto path = dirQueue.dequeue()) {
203  dirsDone++;
204  static timer::anchor a("opendir");
206  auto result = opendir(path->c_str());
207  i.stop();
208  if (result == nullptr) {
209  if (errno == EACCES && ignoreAccess) {
210  counter.count(counterType::specials::denied);
211  continue;
212  } else if (errno == ENOENT) {
213  counter.count(counterType::specials::noent);
214  continue;
215  } else if (errno == ENOTDIR) {
216  counter.count(counterType::specials::notdir);
217  continue;
218  }
219  throwcall::badval(result, nullptr, "can't open directory ", *path);
220  }
221  scoped::Dir dir(*path, result);
222  static timer::anchor b("readdir");
224  while (auto entry = readdir(dir)) {
225  I.stop();
226  if (entry->d_name[entry->d_name[0] != '.' ? 0 : entry->d_name[1] != '.' ? 1 : 2] == '\0') {
227  I.restart();
228  continue; // skip . .. and empty strings
229  }
230  counter.count(entry->d_type);
231  if (entry->d_type == DT_DIR) {
232  std::string subdir(*path);
233  subdir += "/";
234  subdir += entry->d_name;
235  dirQueue.emplace(subdir);
236  newWorker(dirQueue);
237  } else if (entry->d_type == DT_UNKNOWN && reportUnknowns) {
238  std::string item(*path);
239  item += "/";
240  item += entry->d_name;
241  std::unique_lock<decltype(unknownListMutex)> lock(unknownListMutex); //(NOLINT clang-analyzer-alpha.core.CastToStruct)
242  unknownList.emplace_front(item);
243  }
244  I.restart();
245  }
246  }
247  std::unique_lock<decltype(listMutex)> lock;
248  --nActiveWorkers;
249  cv.notify_one();
250  }

References throwcall::badval(), counterType::count(), counter, cv, MyWaitQueues::simple< T >::dequeue(), dirsDone, MyWaitQueues::simple< T >::emplace(), ignoreAccess, listMutex, nActiveWorkers, newWorker(), reportUnknowns, timer::instanceUnscoped::restart(), timer::instanceUnscoped::stop(), unknownList, and unknownListMutex.

Referenced by runnerType().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ runners()

static std::forward_list<runnerType>& runnerType::runners ( )
inlinestatic

Definition at line 155 of file dirCount.cpp.

155  {
156  static std::forward_list<runnerType> list;
157  return list;
158  }

Referenced by finish(), and newWorker().

Here is the caller graph for this function:

◆ sum()

void runnerType::sum ( counterType other)
inline

Definition at line 195 of file dirCount.cpp.

195  {
196  counter.sum(other);
197  }

References counter, and counterType::sum().

Here is the call graph for this function:

Member Data Documentation

◆ counter

counterType runnerType::counter
private

Definition at line 149 of file dirCount.cpp.

Referenced by process(), and sum().

◆ dirsDone

unsigned int runnerType::dirsDone
private

Definition at line 150 of file dirCount.cpp.

Referenced by getDirsDone(), and process().

◆ worker

std::thread runnerType::worker

Definition at line 160 of file dirCount.cpp.

Referenced by runnerType().


The documentation for this class was generated from the following file:
verbose
options::single< bool > verbose
runnerType::cv
static std::condition_variable cv
Definition: dirCount.cpp:152
unknownList
static std::forward_list< std::string > unknownList
Definition: dirCount.cpp:145
throwcall::badval
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
Definition: throwcall.h:54
counterType::count
void count(unsigned char what)
Definition: dirCount.cpp:116
runnerType::process
void process(dirQueueType &dirQueue)
Definition: dirCount.cpp:201
runnerType::newWorker
static void newWorker(dirQueueType &dirQueue)
Definition: dirCount.cpp:165
runnerType::worker
std::thread worker
Definition: dirCount.cpp:160
runnerType::runners
static std::forward_list< runnerType > & runners()
Definition: dirCount.cpp:155
nThreads
static options::single< unsigned > nThreads('n', "nThreads", "number of threads", 0)
runnerType::nWorkers
static unsigned int nWorkers
Definition: dirCount.cpp:159
timer::instanceUnscoped
Definition: timer.h:95
runnerType::dirsDone
unsigned int dirsDone
Definition: dirCount.cpp:150
timer::anchor
Definition: timer.h:22
MyWaitQueues::simple::emplace
void emplace(Types ... args)
Definition: dirCount.cpp:37
unknownListMutex
static std::mutex unknownListMutex
Definition: dirCount.cpp:146
runnerType::counter
counterType counter
Definition: dirCount.cpp:149
ignoreAccess
static options::single< bool > ignoreAccess('i', "ignoreAccess", "ignore subdirs we may not access")
scoped::Dir
Definition: scoped.h:71
counterType::sum
void sum(counterType &other)
Definition: dirCount.cpp:119
MyWaitQueues::simple::dequeue
std::unique_ptr< T > dequeue()
Definition: dirCount.cpp:41
reportUnknowns
static options::single< bool > reportUnknowns('U',"reportUnknowns", "print a list of items with type DT_UNKNOWN")
runnerType::nActiveWorkers
static std::atomic< unsigned int > nActiveWorkers
Definition: dirCount.cpp:153
runnerType::listMutex
static std::mutex listMutex
Definition: dirCount.cpp:151