| 487 | // ---------------------------------------------------------------------------------------- |
| 488 | |
| 489 | class thread_pool |
| 490 | { |
| 491 | /*! |
| 492 | This object is just a shell that holds a std::shared_ptr |
| 493 | to the real thread_pool_implementation object. The reason for doing |
| 494 | it this way is so that we can allow any mixture of destruction orders |
| 495 | between thread_pool objects and futures. Whoever gets destroyed |
| 496 | last cleans up the thread_pool_implementation resources. |
| 497 | !*/ |
| 498 | typedef bound_function_pointer::kernel_1a_c bfp_type; |
| 499 | |
| 500 | public: |
| 501 | explicit thread_pool ( |
| 502 | unsigned long num_threads |
| 503 | ) |
| 504 | { |
| 505 | impl.reset(new thread_pool_implementation(num_threads)); |
| 506 | } |
| 507 | |
| 508 | ~thread_pool ( |
| 509 | ) |
| 510 | { |
| 511 | try |
| 512 | { |
| 513 | impl->shutdown_pool(); |
| 514 | } |
| 515 | catch (std::exception& e) |
| 516 | { |
| 517 | std::cerr << "An unhandled exception was inside a dlib::thread_pool when it was destructed." << std::endl; |
| 518 | std::cerr << "It's what string is: \n" << e.what() << std::endl; |
| 519 | assert(false); |
| 520 | abort(); |
| 521 | } |
| 522 | catch (...) |
| 523 | { |
| 524 | std::cerr << "An unhandled exception was inside a dlib::thread_pool when it was destructed." << std::endl; |
| 525 | assert(false); |
| 526 | abort(); |
| 527 | } |
| 528 | } |
| 529 | |
| 530 | void wait_for_task ( |
| 531 | uint64 task_id |
| 532 | ) const { impl->wait_for_task(task_id); } |
| 533 | |
| 534 | unsigned long num_threads_in_pool ( |
| 535 | ) const { return impl->num_threads_in_pool(); } |
| 536 | |
| 537 | void wait_for_all_tasks ( |
| 538 | ) const { impl->wait_for_all_tasks(); } |
| 539 | |
| 540 | bool is_task_thread ( |
| 541 | ) const { return impl->is_task_thread(); } |
| 542 | |
| 543 | template <typename T> |
| 544 | uint64 add_task ( |
| 545 | T& obj, |
| 546 | void (T::*funct)() |
no outgoing calls
no test coverage detected