Line data Source code
1 : // Copyright (c) 2013-2021 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/cppthread
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : /** \file
21 : * \brief Implementation of the Thread Runner and Managers.
22 : *
23 : * This file includes the implementation used by the cppthread environment.
24 : */
25 :
26 :
27 : // self
28 : //
29 : #include "cppthread/thread.h"
30 :
31 : #include "cppthread/exception.h"
32 : #include "cppthread/guard.h"
33 : #include "cppthread/log.h"
34 : #include "cppthread/runner.h"
35 :
36 :
37 : // snapdev lib
38 : //
39 : #include <snapdev/glob_to_list.h>
40 :
41 :
42 : // C++ lib
43 : //
44 : #include <fstream>
45 :
46 :
47 : // C lib
48 : //
49 : #include <signal.h>
50 : #include <sys/stat.h>
51 : #include <sys/syscall.h>
52 : #include <sys/sysinfo.h>
53 : #include <unistd.h>
54 :
55 :
56 : // last include
57 : //
58 : #include <snapdev/poison.h>
59 :
60 :
61 :
62 :
63 : namespace cppthread
64 : {
65 :
66 :
67 :
68 :
69 :
70 : /** \brief Initialize the thread object.
71 : *
72 : * This function saves the name of the thread. The name is generally a
73 : * static string and it is used to distinguish between threads when
74 : * managing several at once. The function makes a copy of the name.
75 : *
76 : * The runner pointer is an object which has a run() function that will
77 : * be called from another thread. That object becomes the "child" of
78 : * this thread \em controller. However, if it is already assigned a
79 : * thread controller, then the initialization of the thread fails.
80 : * You may test whether a runner is already assigned a thread controller
81 : * by calling its get_thread() function and see that it is not nullptr.
82 : *
83 : * The pointer to the runner object cannot be nullptr.
84 : *
85 : * \param[in] name The name of the process.
86 : * \param[in] runner The runner (the actual thread) to handle.
87 : */
88 0 : thread::thread(std::string const & name, runner * runner)
89 : : f_name(name)
90 0 : , f_runner(runner)
91 : {
92 0 : if(f_runner == nullptr)
93 : {
94 0 : throw cppthread_invalid_error("runner missing in thread() constructor");
95 : }
96 0 : if(f_runner->f_thread != nullptr)
97 : {
98 0 : throw cppthread_in_use_error("this runner (" + name + ") is already in use");
99 : }
100 :
101 0 : int err(pthread_attr_init(&f_thread_attr));
102 0 : if(err != 0)
103 : {
104 0 : log << log_level_t::fatal
105 0 : << "the thread attributes could not be initialized, error #"
106 0 : << err
107 0 : << end;
108 0 : throw cppthread_invalid_error("pthread_attr_init() failed");
109 : }
110 0 : err = pthread_attr_setdetachstate(&f_thread_attr, PTHREAD_CREATE_JOINABLE);
111 0 : if(err != 0)
112 : {
113 0 : log << log_level_t::fatal
114 0 : << "the thread detach state could not be initialized, error #"
115 0 : << err
116 0 : << end;
117 0 : pthread_attr_destroy(&f_thread_attr);
118 0 : throw cppthread_invalid_error("pthread_attr_setdetachstate() failed");
119 : }
120 :
121 0 : f_runner->f_thread = this;
122 0 : }
123 :
124 :
125 : /** \brief Delete a thread object.
126 : *
127 : * The destructor of a Snap! C++ thread object ensures that the thread stops
128 : * running before actually deleting the runner object.
129 : *
130 : * Then it destroys the thread attributes and returns.
131 : *
132 : * The destructor also removes the thread from the runner so the runner
133 : * can create another thread controller and run again.
134 : */
135 0 : thread::~thread()
136 : {
137 : try
138 : {
139 0 : stop();
140 : }
141 0 : catch(...)
142 : {
143 : // stop() may rethrow any user exception which we have to ignore in
144 : // a destructor...
145 : }
146 0 : f_runner->f_thread = nullptr;
147 :
148 0 : int const err(pthread_attr_destroy(&f_thread_attr));
149 0 : if(err != 0)
150 : {
151 0 : log << log_level_t::error
152 0 : << "the thread attributes could not be destroyed, error #"
153 0 : << err
154 0 : << end;
155 : }
156 0 : }
157 :
158 :
159 : /** \brief Retrieve the name of this process object.
160 : *
161 : * This process object is given a name on creation. In most cases this is
162 : * a static name that is used to determine which process is which.
163 : *
164 : * \return The name of the process.
165 : */
166 0 : std::string const & thread::get_name() const
167 : {
168 0 : return f_name;
169 : }
170 :
171 :
172 : /** \brief Get a pointer to this thread runner.
173 : *
174 : * This function returns the pointer to the thread runner. There are cases
175 : * where it is quite handy to be able to use this function rather than
176 : * having to hold on the information in your own way.
177 : *
178 : * You will probably have to dynamic_cast<>() the result to your own
179 : * object type.
180 : *
181 : * \note
182 : * The thread constructor ensures that this pointer is never nullptr.
183 : * Therefore this function never returns a null pointer. However, the
184 : * dynamic_cast<>() function may return a nullptr.
185 : *
186 : * \return The runner object attached to this thread.
187 : */
188 0 : runner * thread::get_runner() const
189 : {
190 0 : return f_runner;
191 : }
192 :
193 :
194 : /** \brief Check whether the thread is considered to be running.
195 : *
196 : * This flag is used to know whether the thread is running.
197 : *
198 : * \todo
199 : * We need to save the pid of the process that creates threads.
200 : * This tells us whether the thread is running in this process.
201 : * i.e. if a fork() happens, then the child process does not
202 : * have any threads so is_running() has to return false. Also,
203 : * any other function that checks whether a thread is running
204 : * needs to also check the pid. We have to save the pid at
205 : * the time we start the thread and then when we check whether
206 : * the thread is running.
207 : *
208 : * \return true if the thread is still considered to be running.
209 : */
210 0 : bool thread::is_running() const
211 : {
212 0 : guard lock(f_mutex);
213 0 : return f_running;
214 : }
215 :
216 :
217 : /** \brief Check whether the thread was asked to stop.
218 : *
219 : * The thread is using three status flags. One of them is f_stopping which
220 : * is set to false (which is also the default status) when start() is called
221 : * and to true when stop() is called. This function is used to read that
222 : * flag status from the continue_running() function.
223 : *
224 : * \return true if the stop() function was called, false otherwise.
225 : */
226 0 : bool thread::is_stopping() const
227 : {
228 0 : guard lock(f_mutex);
229 0 : return f_stopping;
230 : }
231 :
232 :
233 : /** \brief Start the actual thread.
234 : *
235 : * This function is called when starting the thread. This is a static
236 : * function since pthread can only accept such a function pointer.
237 : *
238 : * The function then calls the internal_thread().
239 : *
240 : * \note
241 : * The function parameter is a void * instead of thread because that
242 : * way the function signature matches the signature the pthread_create()
243 : * function expects.
244 : *
245 : * \param[in] system_thread The thread pointer.
246 : *
247 : * \return We return a null pointer, which we do not use because we expect
248 : * uses to pass results in a different way (i.e. using the fifo).
249 : */
250 0 : void * func_internal_start(void * system_thread)
251 : {
252 0 : thread * t(reinterpret_cast<thread *>(system_thread));
253 0 : t->internal_thread();
254 0 : return nullptr; // == pthread_exit(nullptr);
255 : }
256 :
257 :
258 : /** \brief Run the thread process.
259 : *
260 : * This function is called by the func_internal_start() so we run from
261 : * within the thread class. (i.e. the func_internal_start() function
262 : * itself is static.)
263 : *
264 : * The function marks the thread as started which allows the parent start()
265 : * function to return.
266 : *
267 : * \note
268 : * The function catches standard exceptions thrown by any of the functions
269 : * called by the thread. When that happens, the thread returns early after
270 : * making a copy of the exception. The stop() function will then rethrow
271 : * that exception and it can be managed as if it had happened in the main
272 : * process (if a thread creates another thread, then it can be propagated
273 : * multiple times between all the threads up to the main process.)
274 : */
275 0 : void thread::internal_thread()
276 : {
277 : try
278 : {
279 : {
280 0 : guard lock(f_mutex);
281 0 : f_tid = gettid();
282 0 : f_started = true;
283 0 : f_mutex.signal();
284 : }
285 :
286 : // if the enter failed, do not continue
287 : //
288 0 : if(internal_enter())
289 : {
290 0 : if(internal_run())
291 : {
292 0 : internal_leave(leave_status_t::LEAVE_STATUS_NORMAL);
293 : }
294 : else
295 : {
296 0 : internal_leave(leave_status_t::LEAVE_STATUS_THREAD_FAILED);
297 : }
298 : }
299 : else
300 : {
301 0 : internal_leave(leave_status_t::LEAVE_STATUS_INITIALIZATION_FAILED);
302 : }
303 :
304 : // if useful (necessary) it would probably be better to call this
305 : // function from here; see function and read the "note" section
306 : // for additional info
307 : //
308 : //tcp_client_server::cleanup_on_thread_exit();
309 : }
310 0 : catch(std::exception const & e)
311 : {
312 : // keep a copy of the exception
313 : //
314 0 : f_exception = std::current_exception();
315 :
316 0 : if(f_log_all_exceptions)
317 : {
318 0 : log << log_level_t::fatal
319 0 : << "thread internal_thread() got exception: \""
320 0 : << e.what()
321 0 : << "\", exiting thread now."
322 0 : << end;
323 : }
324 :
325 0 : internal_leave(leave_status_t::LEAVE_STATUS_INSTRUMENTATION);
326 : }
327 0 : catch(...)
328 : {
329 : // ... any other exception terminates the whole process ...
330 : //
331 0 : log << log_level_t::fatal
332 0 : << "thread internal_thread() got an unknown exception (a.k.a. non-std::exception), exiting process."
333 0 : << end;
334 :
335 : // rethrow, our goal is not to ignore the exception, only to
336 : // have a log about it
337 : //
338 0 : throw;
339 : }
340 :
341 : // marked we are done (outside of the try/catch because if this one
342 : // fails, we have a big problem... (i.e. invalid mutex or more unlock
343 : // than locks)
344 : {
345 0 : guard lock(f_mutex);
346 0 : f_running = false;
347 0 : f_tid = PID_UNDEFINED;
348 0 : f_mutex.signal();
349 : }
350 0 : }
351 :
352 :
353 : /** \brief Enter the thread runner.
354 : *
355 : * This function signals that the thread runner is about to be entered.
356 : * This is often used as an initialization function.
357 : *
358 : * If the runner::enter() function raises an std::exception, then the
359 : * function saves that exception for the thread owner, emits a log,
360 : * and returns false.
361 : *
362 : * \note
363 : * The log is not emitted if set_log_all_exceptions() was called with false.
364 : *
365 : * \return true if the runner::enter() function returned as expected.
366 : */
367 0 : bool thread::internal_enter()
368 : {
369 : try
370 : {
371 0 : f_runner->enter();
372 0 : return true;
373 : }
374 0 : catch(std::exception const & e)
375 : {
376 : // keep a copy of the exception
377 : //
378 0 : f_exception = std::current_exception();
379 :
380 0 : if(f_log_all_exceptions)
381 : {
382 0 : log << log_level_t::fatal
383 0 : << "thread internal_enter() got exception: \""
384 0 : << e.what()
385 0 : << "\", exiting thread now."
386 0 : << end;
387 : }
388 : }
389 :
390 0 : return false;
391 : }
392 :
393 :
394 : /** \brief Execute the run() function.
395 : *
396 : * This function specifically calls the run() function in an exception
397 : * safe manner.
398 : *
399 : * If no exception occurs, the function returns true meaning that everything
400 : * worked as expected.
401 : *
402 : * When an std::exception occurs, the function returns false after saving
403 : * the exception so it can be reported to this thread owner. (i.e. it gets
404 : * re-thrown whenever the thread owner joins with the thread).
405 : *
406 : * The std::exception can be logged by calling the set_log_all_exceptions()
407 : * function with true, which is the default (i.e. don't call it with false
408 : * if you want to get the logs).
409 : *
410 : * Other exceptions are ignored (they will be caught by the internal_thread()
411 : * function).
412 : *
413 : * \return true if the run worked as expected; false if an exception was
414 : * caught.
415 : */
416 0 : bool thread::internal_run()
417 : {
418 : try
419 : {
420 0 : f_runner->run();
421 0 : return true;
422 : }
423 0 : catch(std::exception const & e)
424 : {
425 : // keep a copy of the exception
426 : //
427 0 : f_exception = std::current_exception();
428 :
429 0 : if(f_log_all_exceptions)
430 : {
431 0 : log << log_level_t::fatal
432 0 : << "thread internal_run() got exception: \""
433 0 : << e.what()
434 0 : << "\", exiting thread now."
435 0 : << end;
436 : }
437 : }
438 :
439 0 : return false;
440 : }
441 :
442 :
443 : /** \brief Function called when leaving the thread runner.
444 : *
445 : * Whenever the thread runner leaves, we want to send a signal to the
446 : * runner owner through the runner::leave() function. This is the thread
447 : * function which makes sure that the runner::leave() function get called.
448 : *
449 : * The function is called with a status which tells us what failed (i.e.
450 : * the reason for the call).
451 : *
452 : * The function is std::exception safe. Unknown exceptions are ignored here
453 : * since they will be caught by the internal_thread() function.
454 : *
455 : * std::exceptions are reported and either ignored (another exception occurred
456 : * earlier) or reported back to the thread owner after the owner joins with
457 : * the thread.
458 : *
459 : * \param[in] status The status when the internal_leave() function gets called.
460 : */
461 0 : void thread::internal_leave(leave_status_t status)
462 : {
463 : try
464 : {
465 0 : f_runner->leave(status);
466 : }
467 0 : catch(std::exception const & e)
468 : {
469 : // keep the first exception (i.e. internal_enter() or internal_run()
470 : // have priority on this one)
471 : //
472 0 : if(f_exception == std::exception_ptr())
473 : {
474 0 : f_exception = std::current_exception();
475 : }
476 :
477 0 : log << log_level_t::fatal
478 0 : << "thread internal_leave() got exception: \""
479 0 : << e.what()
480 0 : << "\", exiting thread now."
481 0 : << end;
482 : }
483 0 : }
484 :
485 :
486 : /** \brief Attempt to start the thread.
487 : *
488 : * This function is used to start running the thread code. If the
489 : * thread is already running, then the function returns false.
490 : *
491 : * The function makes use of a condition to wait until the thread
492 : * is indeed started. The function will not return until the thread
493 : * is started or something failed.
494 : *
495 : * \return true if the thread successfully started, false otherwise.
496 : */
497 0 : bool thread::start()
498 : {
499 0 : guard lock(f_mutex);
500 :
501 0 : if(f_running || f_started)
502 : {
503 0 : log << log_level_t::warning
504 0 : << "the thread is already running"
505 0 : << end;
506 0 : return false;
507 : }
508 :
509 0 : if(!f_runner->is_ready())
510 : {
511 0 : log << log_level_t::warning
512 0 : << "the thread runner is not ready"
513 0 : << end;
514 0 : return false;
515 : }
516 :
517 0 : f_running = true;
518 0 : f_started = false;
519 0 : f_stopping = false; // make sure it is reset
520 0 : f_exception = std::exception_ptr();
521 :
522 0 : int const err(pthread_create(&f_thread_id, &f_thread_attr, &func_internal_start, this));
523 0 : if(err != 0)
524 : {
525 0 : f_running = false;
526 :
527 0 : log << log_level_t::error
528 0 : << "the thread could not be created, error #"
529 0 : << err
530 0 : << end;
531 0 : return false;
532 : }
533 :
534 0 : while(!f_started)
535 : {
536 0 : f_mutex.wait();
537 : }
538 :
539 0 : return true;
540 : }
541 :
542 :
543 : /** \brief Stop the thread.
544 : *
545 : * This function requests the thread to stop. Note that the function does
546 : * not actually forcibly stop the thread. It only turns on a flag (namely
547 : * it makes the is_stopping() function return true) meaning that the
548 : * thread should stop as soon as possible. This gives the thread the
549 : * time necessary to do all necessary cleanup before quitting.
550 : *
551 : * The stop function blocks until the thread is done.
552 : *
553 : * \warning
554 : * This function throws the thread exceptions that weren't caught in your
555 : * run() function. This happens after the thread has completed. The exception
556 : * is then removed from the thread (i.e. it won't re-throw a second time
557 : * and a call to get_exception() returns a null pointer).
558 : */
559 0 : void thread::stop()
560 : {
561 : {
562 0 : guard lock(f_mutex);
563 :
564 0 : if(!f_running && !f_started)
565 : {
566 : // we return immediately in this case because
567 : // there is nothing to join when the thread never
568 : // started...
569 : //
570 0 : return;
571 : }
572 :
573 : // request the child to stop
574 : //
575 0 : f_stopping = true;
576 : }
577 :
578 : // wait for the child to be stopped
579 : //
580 : // we cannot pass any results through the pthread interface so we
581 : // pass a nullptr for the result; instead, the user is expected to
582 : // add fields to his class and fill in whatever results he wants
583 : // there; it is going to work much better that way
584 : //
585 0 : pthread_join(f_thread_id, nullptr);
586 :
587 : // at this point the thread has fully exited
588 :
589 : // we are done now
590 : //
591 : // these flags are likely already the correct value except for
592 : // f_stopping which the stop() function manages here
593 : //
594 0 : f_running = false;
595 0 : f_started = false;
596 0 : f_stopping = false;
597 :
598 : // if the child died because of a standard exception, rethrow it now
599 : // and "lose it" at the same time
600 : //
601 0 : if(f_exception != std::exception_ptr())
602 : {
603 0 : std::exception_ptr e;
604 0 : e.swap(f_exception);
605 0 : std::rethrow_exception(e);
606 : }
607 : }
608 :
609 :
610 : /** \brief Retrieve the thread identifier of this thread.
611 : *
612 : * Under Linux, threads are tasks like any others. Each task is given a
613 : * `pid_t` value. This function returns that `pid_t` for this thread.
614 : *
615 : * When the thread is not running this function returns PID_UNDEFINED.
616 : * Note, however, that the value is set a little after the thread started
617 : * and cleared a little before the thread exits. This is **not** a good
618 : * way to know whether the thread is running. Use the is_running() function
619 : * instead.
620 : *
621 : * \return The thread identifier (tid) or PID_UNDEFINED if the thread is
622 : * not running.
623 : */
624 0 : pid_t thread::get_thread_tid() const
625 : {
626 0 : guard lock(f_mutex);
627 0 : return f_tid;
628 : }
629 :
630 :
631 : /** \brief Retrieve a reference to the thread mutex.
632 : *
633 : * This function returns a reference to this thread mutex. Note that
634 : * the `runner` has its own mutex as well.
635 : *
636 : * \return This thread's mutex.
637 : */
638 0 : mutex & thread::get_thread_mutex() const
639 : {
640 0 : return f_mutex;
641 : }
642 :
643 :
644 : /** \brief Whether to log exceptions caught in the thread.
645 : *
646 : * We catch exceptions that happen in your threads. By default, we log them
647 : * with the basic cppthread log mechanism. If you do not want to have this
648 : * intermediate logging kick in, you can set this flag to false.
649 : *
650 : * This flag is defaulted to true because in many cases you are not joining
651 : * a thread when the exception occurs. That means your code would never
652 : * see the exception. Instead, you'd have a dangling process as it is
653 : * likely to expect things are happening in the thread and if not, it
654 : * gets stuck. At least, in this way, by default you get a message in your
655 : * logs.
656 : *
657 : * \note
658 : * Unknown exceptions (i.e. those not derived from std::exception), are
659 : * always logged and re-thrown (which has the effect of terminating your
660 : * process). Those exceptions are always logged, whatever the state of
661 : * this "log all exceptions" flag.
662 : *
663 : * \param[in] log_all_exceptions Whether to log (true) all exceptions or
664 : * not (false).
665 : *
666 : * \sa get_log_all_exceptions()
667 : */
668 0 : void thread::set_log_all_exceptions(bool log_all_exceptions)
669 : {
670 0 : f_log_all_exceptions = log_all_exceptions;
671 0 : }
672 :
673 :
674 : /** \brief Retrieve whether all exceptions get logged or not.
675 : *
676 : * This function returns true if all exceptions are to be logged. By default
677 : * this flag is set to true. You can change it with the
678 : * set_log_all_exceptions() function.
679 : *
680 : * Internally, the flag is used to know whether we should log exceptions.
681 : * It is very useful to do so if you do not join your thread on a constant
682 : * basis (i.e. in a service where a thread runs as long as the service
683 : * itself--you probably will want to know when the thread runs in a problem).
684 : *
685 : * This also means you do not have to log the exception yourself unless you
686 : * need some special handling to indicate all the possible messages and
687 : * parameters found in the exception object. However, the logging doesn't
688 : * prevent the system from re-throwing the exception once the thread was
689 : * joined. In other words, whether you log the exception or not, you most
690 : * certainly want to catch it or your process will be terminated.
691 : *
692 : * \return true if the thread object is to log all exceptions.
693 : *
694 : * \sa set_log_all_exceptions()
695 : */
696 0 : bool thread::get_log_all_exceptions() const
697 : {
698 0 : return f_log_all_exceptions;
699 : }
700 :
701 :
702 : /** \brief Get the exception pointer.
703 : *
704 : * When the thread runner raises an exception, it gets saved in the
705 : * thread object. That exception can be retrieved using this get_exception()
706 : * function.
707 : *
708 : * If no exception occurred, then this pointer will be the nullptr. If
709 : * an exception did occur, then it will be a pointer to that exception.
710 : * It can be rethrown inside a try/catch in order to handle it.
711 : *
712 : * \code
713 : * std::exception_ptr e(my_thread->get_exception());
714 : * if(e != std::exception_ptr())
715 : * {
716 : * try
717 : * {
718 : * e->rethrow_exception();
719 : * }
720 : * catch(std::exception const & e)
721 : * {
722 : * std::cerr << "exception occurred: " << e.what() << std::endl;
723 : * }
724 : * }
725 : * \endcode
726 : *
727 : * \return A pointer to a standard exception (std::exception).
728 : */
729 0 : std::exception_ptr thread::get_exception() const
730 : {
731 0 : guard lock(f_mutex);
732 0 : return f_exception;
733 : }
734 :
735 :
736 : /** \brief Send a signal to this thread.
737 : *
738 : * This function sends a signal to a specific thread.
739 : *
740 : * You have to be particularly careful with Unix signal and threads as they
741 : * do not always work as expected. This is yet particularly useful if you
742 : * want to send a signal such as SIGUSR1 and SIGUSR2 to a thread so it
743 : * reacts one way or another (i.e. you are using poll() over a socket and
744 : * need to be stopped without using a possibly long time out, you can use
745 : * the signalfd() function to transform SIGUSR1 into a poll-able signal.)
746 : *
747 : * \note
748 : * Obviously, if the thread is not running, nothing happens.
749 : *
750 : * \param[in] sig The signal to send to this thread.
751 : *
752 : * \return true if the signal was sent, false if the signal could not
753 : * be sent (i.e. the thread was already terminated...)
754 : */
755 0 : bool thread::kill(int sig)
756 : {
757 0 : guard lock(f_mutex);
758 0 : if(f_running)
759 : {
760 : // pthread_kill() returns zero on success, otherwise it returns
761 : // an error code which at this point we lose
762 : //
763 0 : return pthread_kill(f_thread_id, sig) == 0;
764 : }
765 :
766 0 : return false;
767 : }
768 :
769 :
770 :
771 :
772 :
773 :
774 :
775 :
776 : /** \brief Retrieve the number of processors available on this system.
777 : *
778 : * This function returns the number of processors available on this system.
779 : *
780 : * \attention
781 : * Note that the OS may not be using all of the available processors. This
782 : * function returns the total number, including processors that are not
783 : * currently usable by your application. Most often, you probably want to
784 : * call get_number_of_available_processors() instead.
785 : *
786 : * \return The total number of processors on this system.
787 : *
788 : * \sa get_number_of_available_processors()
789 : */
790 0 : int get_total_number_of_processors()
791 : {
792 0 : return get_nprocs_conf();
793 : }
794 :
795 :
796 : /** \brief Retrieve the number of processors currently usable.
797 : *
798 : * This function returns the number of processors that are currently
799 : * running on this system. This is usually what you want to know about
800 : * to determine how many threads to run in parallel.
801 : *
802 : * This function is going to be equal or less than what the
803 : * get_total_number_of_processors() returns. For example, on some systems
804 : * a processors can be made offline. This is useful to save energy when
805 : * the total load decreases under a given threshold.
806 : *
807 : * \note
808 : * What is the right number of threads needed in a thread pool? If you
809 : * have worker threads that do a fairly small amount of work, then
810 : * having a number of threads equal to two times the number of
811 : * available thread is still sensible:
812 : *
813 : * \code
814 : * pool_size = get_number_of_available_processors() * 2;
815 : * \endcode
816 : *
817 : * \par
818 : * This is particularly true when threads perform I/O with high latency
819 : * (i.e. read/write from a hard drive or a socket.)
820 : *
821 : * \par
822 : * If your thread does really intensive work for a while (i.e. one thread
823 : * working on one 4Mb image,) then the pool size should be limited to
824 : * one worker per CPU:
825 : *
826 : * \code
827 : * pool_size = get_number_of_available_processors();
828 : * \endcode
829 : *
830 : * \par
831 : * Also, if you know that you will never get more than `n` objects at
832 : * a time in your input, then the maximum number of threads needed is
833 : * going to be `n`. In most cases `n` is going to be larger than the
834 : * number of processors although now that we can have machines with
835 : * over 100 CPUs, make sure to clamp your `pool_size` parameter to
836 : * `n` if known ahead of time.
837 : *
838 : * \return The number of processors currently available for your threads.
839 : *
840 : * \sa get_total_number_of_processors()
841 : */
842 0 : int get_number_of_available_processors()
843 : {
844 0 : return get_nprocs();
845 : }
846 :
847 :
848 : /** \brief Get the thread identifier of the current thread.
849 : *
850 : * This function retrieves the thread identifier of the current thread.
851 : * In most cases, this is only useful to print out messages to a log
852 : * including the thread identifier. This identifier is equivalent
853 : * to the `pid_t` returned by `getpid()` but specific to the running
854 : * thread.
855 : *
856 : * \return The thread identifier.
857 : */
858 0 : pid_t gettid()
859 : {
860 0 : return static_cast<pid_t>(syscall(SYS_gettid));
861 : }
862 :
863 :
864 : /** \brief Set the name of the currently running thread.
865 : *
866 : * This function is used to set the name of the currently running thread.
867 : *
868 : * \param[in] name The name of the thread.
869 : *
870 : * \return 0 if the function worked, -1 on error.
871 : */
872 0 : int set_current_thread_name(std::string const & name)
873 : {
874 0 : return set_thread_name(gettid(), name);
875 : }
876 :
877 :
878 : /** \brief Set the name of the specified thread.
879 : *
880 : * This function changes the name of one of your threads. In
881 : * most cases, you should let the runner set the name of the thread
882 : * on construction.
883 : *
884 : * This function should be used only if the name somehow changes over
885 : * time, for example:
886 : *
887 : * The thread is a worker thread and you want the name to reflect what
888 : * the worker is currently doing. However, do that only if the worker
889 : * is going to do work for a while, otherwise it's likely going to be
890 : * rather useless (i.e. htop refresh rate is 1 to 2 seconds).
891 : *
892 : * \exception cppthread_invalid_error
893 : * This exception is raised if the name is empty.
894 : *
895 : * \exception cppthread_out_of_range
896 : * This exception is raised if the name is too long. Linux limits the
897 : * name of a thread to 15 characters (the buffer has a limit of
898 : * 16 characters).
899 : *
900 : * \param[in] tid The thread identifier (its number, not pthread_t).
901 : * \param[in] name The name of the thread.
902 : *
903 : * \return 0 if the function worked, -1 on error.
904 : */
905 0 : int set_thread_name(pid_t tid, std::string const & name)
906 : {
907 0 : if(name.empty())
908 : {
909 0 : throw cppthread_invalid_error("thread name cannot be empty.");
910 : }
911 0 : if(name.length() > 15)
912 : {
913 : throw cppthread_out_of_range(
914 : "thread name is limited to 15 characters, \""
915 0 : + name
916 0 : + "\" is too long.");
917 : }
918 :
919 0 : std::ofstream comm("/proc/" + std::to_string(tid) + "/comm");
920 0 : comm << name;
921 :
922 0 : return comm ? 0 : -1;
923 : }
924 :
925 :
926 : /** \brief Retrieve the name of the current thread.
927 : *
928 : * This function reads the name of the currently running thread by reading
929 : * its `/proc/\<tid>/comm` file. See the get_thread_name() for more details.
930 : *
931 : * \return The name of the current thread.
932 : *
933 : * \sa get_thread_name()
934 : * \sa gettid()
935 : */
936 0 : std::string get_current_thread_name()
937 : {
938 0 : return get_thread_name(gettid());
939 : }
940 :
941 :
942 : /** \brief Retrieve the name of a thread.
943 : *
944 : * This function reads the name of the \p tid thread by reading its
945 : * `/proc/\<tid>/comm` file.
946 : *
947 : * This function is different from the pthread_getname_np() which will
948 : * return the in memory name. If you have access to your runner, you
949 : * may instead want to use its get_name() function. Note that the name
950 : * of a runner cannot be changed so it may be considered more authoritative.
951 : *
952 : * \param[in] tid The thread identifier (its number, not pthread_t).
953 : *
954 : * \return The name of the specified thread.
955 : *
956 : * \sa get_current_thread_name()
957 : * \sa gettid()
958 : */
959 0 : std::string get_thread_name(pid_t tid)
960 : {
961 0 : std::ifstream comm("/proc/" + std::to_string(tid) + "/comm");
962 0 : std::string name;
963 0 : comm >> name;
964 0 : return name;
965 : }
966 :
967 :
968 : /** \brief Retrieve the list of threads for a given process.
969 : *
970 : * This function reads the list of PID from `/proc/<pid>/task/\*` which is
971 : * the list of threads of a process has. If only one PID, then this is the
972 : * main process PID and the process has no threads currently running.
973 : *
974 : * \param[in] pid The parent process to be searched for threads.
975 : *
976 : * \return A vector of PIDs.
977 : */
978 0 : process_ids_t get_thread_ids(pid_t pid)
979 : {
980 0 : process_ids_t results;
981 :
982 0 : if(pid == -1)
983 : {
984 0 : pid = getpid();
985 : }
986 :
987 0 : std::string pattern("/proc/");
988 0 : pattern += std::to_string(pid);
989 0 : pattern += "/task/*";
990 :
991 0 : snap::glob_to_list<std::vector<std::string>> glob;
992 0 : if(glob.read_path<
993 : snap::glob_to_list_flag_t::GLOB_FLAG_IGNORE_ERRORS
994 0 : , snap::glob_to_list_flag_t::GLOB_FLAG_ONLY_DIRECTORIES>(pattern))
995 : {
996 0 : for(auto s : glob)
997 : {
998 0 : pid_t id(0);
999 0 : std::string::size_type pos(s.rfind('/') + 1);
1000 :
1001 0 : bool valid(pos < s.length());
1002 0 : for(; pos < s.length(); ++pos)
1003 : {
1004 0 : char const c(s[pos]);
1005 0 : if(c >= '0' && c <= '9')
1006 : {
1007 0 : id = id * 10 + c - '0';
1008 : }
1009 : else
1010 : {
1011 0 : valid = false;
1012 0 : break;
1013 : }
1014 : }
1015 0 : if(valid)
1016 : {
1017 0 : results.push_back(id);
1018 : }
1019 : }
1020 : }
1021 :
1022 0 : return results;
1023 : }
1024 :
1025 :
1026 : /** \brief Check whether a process is running or not.
1027 : *
1028 : * This function checks whether the `/proc/<pid>` directory exists. If so,
1029 : * that means that the process with \p pid is current running.
1030 : *
1031 : * \note
1032 : * Keep in mind that between the time this function checks whether a process
1033 : * is running or not and the time it returns, the given process may have
1034 : * stopped or a new process may have been started.
1035 : * \note
1036 : * Also, security wise, this is not safe except around the time a process
1037 : * quits and even though, on a very heavy system starting new processes all
1038 : * the time, it may re-use the same \p pid very quickly.
1039 : *
1040 : * \param[in] pid The process identifier to check.
1041 : *
1042 : * \return true if the process is currently running.
1043 : */
1044 0 : bool is_process_running(pid_t pid)
1045 : {
1046 0 : if(pid == getpid())
1047 : {
1048 : // funny guy testing whether he himself is running!?
1049 : //
1050 0 : return true;
1051 : }
1052 :
1053 0 : std::string proc_path("/proc/");
1054 0 : proc_path += std::to_string(pid);
1055 :
1056 0 : struct stat st;
1057 0 : return stat(proc_path.c_str(), &st) == 0;
1058 : }
1059 :
1060 :
1061 : /** \brief Retrieve the boot UUID.
1062 : *
1063 : * The Linux kernel generates a UUID on a reboot. This allows software to
1064 : * determine whether the computer was rebooted since the last time it was
1065 : * used.
1066 : *
1067 : * On computers where there is no boot identifier, this function returns
1068 : * an empty string.
1069 : *
1070 : * \return The boot UUID as a string or an empty string if not available.
1071 : */
1072 0 : std::string get_boot_id()
1073 : {
1074 0 : std::ifstream in("/proc/sys/kernel/random/boot_id");
1075 0 : std::string uuid;
1076 0 : if(in)
1077 : {
1078 0 : std::getline(in, uuid);
1079 : }
1080 0 : return uuid;
1081 : }
1082 :
1083 :
1084 :
1085 :
1086 :
1087 :
1088 :
1089 :
1090 :
1091 :
1092 :
1093 :
1094 :
1095 :
1096 :
1097 :
1098 :
1099 :
1100 :
1101 :
1102 :
1103 :
1104 :
1105 :
1106 :
1107 :
1108 :
1109 :
1110 :
1111 :
1112 :
1113 : /** \class thread
1114 : * \brief A thread object that ensures proper usage of system threads.
1115 : *
1116 : * This class is used to handle threads. It should NEVER be used, however,
1117 : * there are some very specific cases where a thread is necessary to make
1118 : * sure that main process doesn't get stuck. For example, the process
1119 : * environment using pipes requires threads to read and write pipes
1120 : * because otherwise the processes could lock up.
1121 : */
1122 :
1123 :
1124 : /** \fn thread::thread(thread const & rhs)
1125 : * \brief The copy operator is deleted.
1126 : *
1127 : * The thread object holds a pointer to a runner which is an OS thread.
1128 : * These would be really difficult to _copy_. Instead we prevent the
1129 : * operation altogether.
1130 : *
1131 : * \param[in] rhs The right hand side.
1132 : */
1133 :
1134 :
1135 : /** \fn thread::operator = (thread const & rhs)
1136 : * \brief The assignment operator is deleted.
1137 : *
1138 : * The thread object holds a pointer to a runner which is an OS thread.
1139 : * These would be really difficult to _assign_. Instead we prevent
1140 : * the operation altogether.
1141 : *
1142 : * \param[in] rhs The right hand side.
1143 : *
1144 : * \return A reference to this object.
1145 : */
1146 :
1147 :
1148 : /** \typedef thread::pointer_t
1149 : * \brief The shared pointer for a thread object.
1150 : *
1151 : * This type is used to hold a smart pointer to a thread.
1152 : *
1153 : * This smart pointer is safe. It can be used to hold a thread object and
1154 : * when it goes out of scope, it properly ends the corresponding thread
1155 : * runner (the runner) and returns.
1156 : *
1157 : * Be cautious because the smart pointer of a runner is not actually
1158 : * safe to delete without first stopping the thread. Make sure to manage
1159 : * all your threads in with two objects, making sure that the thread goes
1160 : * out of scope first so it can stop your thread before your thread object
1161 : * gets destroyed.
1162 : */
1163 :
1164 :
1165 : /** \typedef thread::vector_t
1166 : * \brief A vector of threads.
1167 : *
1168 : * This type defines a vector of threads. Since each entry in the vector
1169 : * is a smart pointer, it is safe to use this type.
1170 : */
1171 :
1172 :
1173 : /** \var thread::f_exception
1174 : * \brief An exception pointer.
1175 : *
1176 : * The exception pointer to the exception that was raised in the runner.
1177 : * By default this pointer is null.
1178 : *
1179 : * This pointer is reset back to a null pointer each time the start()
1180 : * is called.
1181 : *
1182 : * This exception must be caught by your function when calling the
1183 : * stop() function. If you don't catch these, then it will stop your
1184 : * process.
1185 : *
1186 : * \note
1187 : * Only standard exceptions can be caught in this way. You should
1188 : * derive all your exception from std::exception (or use the libexcept).
1189 : */
1190 :
1191 :
1192 : /** \var thread::f_log_all_exceptions
1193 : * \brief Whether the runner exceptions should be logged or not.
1194 : *
1195 : * Whenever an exception occurs in a runner, the exception pointer is
1196 : * saved in the runner so it can be re-thrown after we join with that
1197 : * thread.
1198 : *
1199 : * The main problem here is that certain threads are not joined until
1200 : * we are done with an application. So the exception lingers and there
1201 : * is absolutely no trace of it, especially if you hit Ctlr-C to exit
1202 : * your software, the exception will 100% be lost.
1203 : *
1204 : * Instead, we have this flag to determine whether the exception should
1205 : * be logged at the time it gets caught instead of just saving it in
1206 : * the pointer. By default the flag is set to true which means we will
1207 : * log the exception immediately. This makes it easy to not forget.
1208 : *
1209 : * If you use threads to run a quick process and then return/join
1210 : * (i.e. stop()), then setting this flag to false is okay.
1211 : *
1212 : * \sa get_log_all_exceptions()
1213 : * \sa set_log_all_exceptions()
1214 : */
1215 :
1216 :
1217 : /** \var thread::f_mutex
1218 : * \brief The thread mutex to guard various functions.
1219 : *
1220 : * The mutex is used whenever a variable that may be accessed by different
1221 : * threads is used. Especially, it makes sure that the variables do not
1222 : * get changed too early or too late (i.e. avoid race conditions).
1223 : *
1224 : * Also the mutex is used to send signals. For example, the thread waits
1225 : * on the runner to start. Once the runner is started, it signals the
1226 : * main thread which can then wake up and return as everything is now
1227 : * well defined.
1228 : */
1229 :
1230 :
1231 : /** \var thread::f_name
1232 : * \brief The name of this thread.
1233 : *
1234 : * For debug purposes, you can give each one of your threads a different
1235 : * name. It gets saved in this string.
1236 : */
1237 :
1238 :
1239 : /** \var thread::f_runner
1240 : * \brief The actual thread object.
1241 : *
1242 : * The runner is the object which holds the system thread and runs the
1243 : * commands. We have a separate object because that way we can make sure
1244 : * the runner destructor isn't called while the thread is still running.
1245 : * If that were to happen, then all the virtual functions would be
1246 : * invalid at that point and the system could crash.
1247 : *
1248 : * So the thread object holds a runner allowing the thread to be destroyed
1249 : * first, which calls the stop() function before the runner gets destroyed.
1250 : */
1251 :
1252 :
1253 : /** \var thread::f_running
1254 : * \brief The thread is running.
1255 : *
1256 : * When the thread is running, this flag is set to true. The start()
1257 : * function sets this flag to true before starting the thread and the
1258 : * internal_run() function sets the flag back to false right before
1259 : * the thread exits.
1260 : *
1261 : * In other words, the flag is true early and false early. It's not
1262 : * a way to know whether the actual system thread is running or not.
1263 : */
1264 :
1265 :
1266 : /** \var thread::f_started
1267 : * \brief The thread is started.
1268 : *
1269 : * The start() function returns only after the thread is started. To control
1270 : * that state, we use this flag. The caller will wait until the child
1271 : * thread is started (i.e. f_started is true).
1272 : */
1273 :
1274 :
1275 : /** \var thread::f_stopping
1276 : * \brief The thread is currently in the stopping process.
1277 : *
1278 : * When the stop() function is called, the flag is set to true until after
1279 : * the caller joined with the thread.
1280 : *
1281 : * The is_stopping() function returns the current value of that field.
1282 : */
1283 :
1284 :
1285 : /** \var thread::f_thread_attr
1286 : * \brief This thread attributes.
1287 : *
1288 : * When we create a thread we create attributes to assign to the thread
1289 : * on creation. These are the attributes.
1290 : *
1291 : * These are created once at the time the thread object is created and
1292 : * released when the object is destroyed. The same attributes are reused
1293 : * to re-start the thread over and over again (i.e. start() / stop()
1294 : * sequences).
1295 : */
1296 :
1297 :
1298 : /** \var thread::f_thread_id
1299 : * \brief This thread identifier.
1300 : *
1301 : * Each thread is assigned a unique identifier by the C-library. This is
1302 : * that identifier. Under Linux, it is an IP address.
1303 : */
1304 :
1305 :
1306 : /** \var thread::f_tid
1307 : * \brief This thread identifier.
1308 : *
1309 : * Each thread is assigned a unique identifier by the OS.
1310 : */
1311 :
1312 :
1313 :
1314 : /** \var PID_UNDEFINED
1315 : * \brief The value a PID variable is set to when not representing a process.
1316 : *
1317 : * In many cases we want to be able to initialize a pid_t variable with some
1318 : * default value. This variable is generally the best choice.
1319 : *
1320 : * \code
1321 : * pid_t f_my_process = PID_UNDEFINED;
1322 : * \endcode
1323 : */
1324 :
1325 :
1326 : /** \var THREAD_UNDEFINED
1327 : * \brief An invalid thread identifier for initialization.
1328 : *
1329 : * In many cases we want to be able to initialize a pthread_t variable
1330 : * with some default value. This variable is generally the best choice.
1331 : *
1332 : * \code
1333 : * pthread_t f_my_thread = THREAD_UNDEFINED;
1334 : * \endcode
1335 : */
1336 :
1337 :
1338 : /** \typedef process_ids_t
1339 : * \brief A list of identifiers representing various processes.
1340 : *
1341 : * This type defines a vector that can hold identifiers to various
1342 : * processes.
1343 : */
1344 :
1345 :
1346 :
1347 6 : } // namespace cppthread
1348 : // vim: ts=4 sw=4 et
|