worker_thread.cc 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2015 The Crashpad Authors. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "util/thread/worker_thread.h"
  15. #include "base/logging.h"
  16. #include "util/thread/thread.h"
  17. namespace crashpad {
  18. namespace internal {
  19. class WorkerThreadImpl final : public Thread {
  20. public:
  21. WorkerThreadImpl(WorkerThread* self, double initial_work_delay)
  22. : semaphore_(0),
  23. initial_work_delay_(initial_work_delay),
  24. self_(self) {}
  25. ~WorkerThreadImpl() {}
  26. void ThreadMain() override {
  27. if (initial_work_delay_ > 0)
  28. semaphore_.TimedWait(initial_work_delay_);
  29. while (self_->running_) {
  30. self_->delegate_->DoWork(self_);
  31. semaphore_.TimedWait(self_->work_interval_);
  32. }
  33. }
  34. void SignalSemaphore() {
  35. semaphore_.Signal();
  36. }
  37. private:
  38. // TODO(mark): Use a condition variable instead?
  39. Semaphore semaphore_;
  40. double initial_work_delay_;
  41. WorkerThread* self_; // Weak, owns this.
  42. };
  43. } // namespace internal
  44. WorkerThread::WorkerThread(double work_interval,
  45. WorkerThread::Delegate* delegate)
  46. : work_interval_(work_interval),
  47. delegate_(delegate),
  48. impl_(),
  49. running_(false) {}
  50. WorkerThread::~WorkerThread() {
  51. DCHECK(!running_);
  52. }
  53. void WorkerThread::Start(double initial_work_delay) {
  54. DCHECK(!impl_);
  55. DCHECK(!running_);
  56. running_ = true;
  57. impl_.reset(new internal::WorkerThreadImpl(this, initial_work_delay));
  58. impl_->Start();
  59. }
  60. void WorkerThread::Stop() {
  61. DCHECK(running_);
  62. DCHECK(impl_);
  63. if (!running_)
  64. return;
  65. running_ = false;
  66. impl_->SignalSemaphore();
  67. impl_->Join();
  68. impl_.reset();
  69. }
  70. void WorkerThread::DoWorkNow() {
  71. DCHECK(running_);
  72. impl_->SignalSemaphore();
  73. }
  74. } // namespace crashpad