From d9de4c03043298138503617967e0881cba9a306f Mon Sep 17 00:00:00 2001 From: "John W. Bruce" Date: Tue, 19 Feb 2019 14:05:40 -0800 Subject: [PATCH] Add Lock to ValueMetric (This is a merge of http://go/wvgerrit/72723) ValueMetric, unlike the other metrics, was not safe to call from multiple threads. This patch adds internal locking to ValueMetric to ensure its safety. Bug: 124459322 Bug: 70889998 Bug: 118584039 Test: CE CDM Unit Tests Test: Android Unit Tests Change-Id: I55855ba8a5cdb2bbe1e15be7742304293245b5aa --- .../cdm/metrics/include/value_metric.h | 35 ++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/libwvdrmengine/cdm/metrics/include/value_metric.h b/libwvdrmengine/cdm/metrics/include/value_metric.h index 360e1dbc..19bf6924 100644 --- a/libwvdrmengine/cdm/metrics/include/value_metric.h +++ b/libwvdrmengine/cdm/metrics/include/value_metric.h @@ -6,6 +6,7 @@ #define WVCDM_METRICS_VALUE_METRIC_H_ #include +#include #include #include "metrics.pb.h" @@ -46,6 +47,7 @@ class ValueMetric { // Record the value of the metric. void Record(const T &value) { + std::unique_lock lock(internal_lock_); value_ = value; has_value_ = true; has_error_ = false; @@ -53,19 +55,33 @@ class ValueMetric { // Set the error code if an error was encountered. void SetError(int error_code) { + std::unique_lock lock(internal_lock_); error_code_ = error_code; has_value_ = false; has_error_ = true; } - bool HasValue() const { return has_value_; } - const T &GetValue() const { return value_; } + bool HasValue() const { + std::unique_lock lock(internal_lock_); + return has_value_; + } + const T &GetValue() const { + std::unique_lock lock(internal_lock_); + return value_; + } - bool HasError() const { return has_error_; } - int GetError() const { return error_code_; } + bool HasError() const { + std::unique_lock lock(internal_lock_); + return has_error_; + } + int GetError() const { + std::unique_lock lock(internal_lock_); + return error_code_; + } // Clears the indicators that the metric or error was set. void Clear() { + std::unique_lock lock(internal_lock_); has_value_ = false; has_error_ = false; } @@ -73,6 +89,7 @@ class ValueMetric { // Returns a new ValueMetric proto containing the metric value or the // error code. If neither the error or value are set, it returns nullptr. drm_metrics::ValueMetric *ToProto() const { + std::unique_lock lock(internal_lock_); if (has_error_) { drm_metrics::ValueMetric *value_proto = new drm_metrics::ValueMetric; value_proto->set_error_code(error_code_); @@ -91,6 +108,16 @@ class ValueMetric { int error_code_; bool has_error_; bool has_value_; + + /* + * This locks the internal state of the value metric to ensure safety + * across multiple threads preventing the caller from worrying about + * locking. + * + * This field must be declared mutable because the lock must be takeable even + * in const methods. + */ + mutable std::mutex internal_lock_; }; } // namespace metrics