blob: 991a921d2a06139e7a41aac64d81b8cff150f8c1 [file] [log] [blame]
Eric Laurent3528c932018-02-23 17:17:22 -08001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080017#pragma once
Eric Laurent3528c932018-02-23 17:17:22 -080018
Eric Laurent42896a02019-09-27 15:40:33 -070019#include <vector>
Eric Laurent3528c932018-02-23 17:17:22 -080020
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080021#include <mediautils/TimerThread.h>
22
Andy Hung5c6d68a2022-03-09 21:54:59 -080023namespace android::mediautils {
Eric Laurent3528c932018-02-23 17:17:22 -080024
25// A class monitoring execution time for a code block (scoped variable) and causing an assert
26// if it exceeds a certain time
27
28class TimeCheck {
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080029 public:
Andy Hung5c6d68a2022-03-09 21:54:59 -080030 using OnTimerFunc = std::function<void(bool /* timeout */, float /* elapsedMs */ )>;
31
Eric Laurent3528c932018-02-23 17:17:22 -080032 // The default timeout is chosen to be less than system server watchdog timeout
33 static constexpr uint32_t kDefaultTimeOutMs = 5000;
34
Andy Hung5c6d68a2022-03-09 21:54:59 -080035 /**
36 * TimeCheck is a RAII object which will notify a callback
37 * on timer expiration or when the object is deallocated.
38 *
39 * TimeCheck is used as a watchdog and aborts by default on timer expiration.
40 * When it aborts, it will also send a debugger signal to pids passed in through
41 * setAudioHalPids().
42 *
43 * If the callback function returns for timeout it will not be called again for
44 * the deallocation.
45 *
46 * \param tag string associated with the TimeCheck object.
47 * \param onTimer callback function with 2 parameters
48 * bool timeout (which is true when the TimeCheck object
49 * times out, false when the TimeCheck object is
50 * destroyed or leaves scope before the timer expires.)
51 * float elapsedMs (the elapsed time to this event).
52 * The callback when timeout is true will be called on a different thread.
53 * Currently this is guaranteed to block the destructor
54 * (potential lock inversion warning here) nevertheless
55 * it would be safer not to depend on stack contents.
56 * \param timeoutMs timeout in milliseconds.
57 * \param crashOnTimeout true if the object issues an abort on timeout.
58 */
59 explicit TimeCheck(std::string tag, OnTimerFunc&& onTimer = {},
60 uint32_t timeoutMs = kDefaultTimeOutMs, bool crashOnTimeout = true);
61 // Remove copy constructors as there should only be one call to the destructor.
62 // Move is kept implicitly disabled, but would be logically consistent if enabled.
63 TimeCheck(const TimeCheck& other) = delete;
64 TimeCheck& operator=(const TimeCheck&) = delete;
65
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080066 ~TimeCheck();
67 static void setAudioHalPids(const std::vector<pid_t>& pids);
68 static std::vector<pid_t> getAudioHalPids();
Eric Laurent3528c932018-02-23 17:17:22 -080069
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080070 private:
Andy Hung5c6d68a2022-03-09 21:54:59 -080071 static TimerThread& getTimeCheckThread();
Eric Laurent42896a02019-09-27 15:40:33 -070072 static void accessAudioHalPids(std::vector<pid_t>* pids, bool update);
Eric Laurent3528c932018-02-23 17:17:22 -080073
Andy Hung5c6d68a2022-03-09 21:54:59 -080074 // Helper class for handling events.
75 // The usage here is const safe.
76 class TimeCheckHandler {
77 public:
78 const std::string tag;
79 const OnTimerFunc onTimer;
80 const bool crashOnTimeout;
81 const std::chrono::system_clock::time_point startTime;
82 const pid_t tid;
83
84 void onCancel(TimerThread::Handle handle) const;
85 void onTimeout() const;
86 };
87
88 // mTimeCheckHandler is immutable, prefer to be first initialized, last destroyed.
89 // Technically speaking, we do not need a shared_ptr here because TimerThread::cancelTask()
90 // is mutually exclusive of the callback, but the price paid for lifetime safety is minimal.
91 const std::shared_ptr<const TimeCheckHandler> mTimeCheckHandler;
Ytai Ben-Tsvi1ea62c92021-11-10 14:38:27 -080092 const TimerThread::Handle mTimerHandle;
Eric Laurent3528c932018-02-23 17:17:22 -080093};
94
Andy Hung5c6d68a2022-03-09 21:54:59 -080095} // namespace android::mediautils