diff --git opencensus/stats/internal/stats_exporter.cc b/opencensus/stats/internal/stats_exporter.cc --- opencensus/stats/internal/stats_exporter.cc +++ opencensus/stats/internal/stats_exporter.cc @@ -95,25 +95,51 @@ void StatsExporterImpl::ClearHandlersForTesting() { } void StatsExporterImpl::StartExportThread() EXCLUSIVE_LOCKS_REQUIRED(mu_) { - t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this); thread_started_ = true; + t_ = std::thread(&StatsExporterImpl::RunWorkerLoop, this); +} + +void StatsExporterImpl::Shutdown() { + absl::MutexLock l(&mu_); + if (!thread_started_) { + return; + } + thread_started_ = false; + // Join loop thread when shutdown. + if (t_.joinable()) { + t_.join(); + } } void StatsExporterImpl::RunWorkerLoop() { absl::Time next_export_time = GetNextExportTime(); - while (true) { + bool thread_started = false; + { + absl::MutexLock l(&mu_); + bool thread_started = thread_started_; + } + while (thread_started) { // SleepFor() returns immediately when given a negative duration. absl::SleepFor(next_export_time - absl::Now()); // In case the last export took longer than the export interval, we // calculate the next time from now. next_export_time = GetNextExportTime(); Export(); + { + absl::MutexLock l(&mu_); + thread_started = thread_started_; + } } } // StatsExporter // ------------- +void StatsExporter::Shutdown() { + StatsExporterImpl::Get()->Shutdown(); + StatsExporterImpl::Get()->ClearHandlersForTesting(); +} + // static void StatsExporter::SetInterval(absl::Duration interval) { StatsExporterImpl::Get()->SetInterval(interval); diff --git opencensus/stats/internal/stats_exporter_impl.h b/opencensus/stats/internal/stats_exporter_impl.h --- opencensus/stats/internal/stats_exporter_impl.h +++ opencensus/stats/internal/stats_exporter_impl.h @@ -35,6 +35,7 @@ class StatsExporterImpl { static StatsExporterImpl* Get(); void SetInterval(absl::Duration interval); absl::Time GetNextExportTime() const; + void Shutdown(); void AddView(const ViewDescriptor& view); void RemoveView(absl::string_view name); diff --git opencensus/stats/stats_exporter.h b/opencensus/stats/stats_exporter.h --- opencensus/stats/stats_exporter.h +++ opencensus/stats/stats_exporter.h @@ -45,6 +45,8 @@ class StatsExporter final { // Removes the view with 'name' from the registry, if one is registered. static void RemoveView(absl::string_view name); + static void Shutdown(); + // StatsExporter::Handler is the interface for push exporters that export // recorded data for registered views. The exporter should provide a static // Register() method that takes any arguments needed by the exporter (e.g. a