69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| // Copyright 2021 The Pigweed Authors
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not
 | |
| // use this file except in compliance with the License. You may obtain a copy of
 | |
| // the License at
 | |
| //
 | |
| //     https://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | |
| // License for the specific language governing permissions and limitations under
 | |
| // the License.
 | |
| 
 | |
| #include "pw_chrono/system_timer.h"
 | |
| 
 | |
| #include <thread>
 | |
| 
 | |
| namespace pw::chrono {
 | |
| namespace {
 | |
| 
 | |
| using CallbackContext = backend::NativeSystemTimer::CallbackContext;
 | |
| 
 | |
| void SystemTimerThreadFunction(
 | |
|     std::shared_ptr<bool> timer_enabled,
 | |
|     std::shared_ptr<CallbackContext> callback_context,
 | |
|     SystemClock::time_point expiry_deadline) {
 | |
|   // Sleep until the requested deadline.
 | |
|   std::this_thread::sleep_until(expiry_deadline);
 | |
| 
 | |
|   {
 | |
|     std::lock_guard lock(callback_context->mutex);
 | |
|     // Only invoke the user's callback if this invocation has not been
 | |
|     // cancelled.
 | |
|     if (*timer_enabled) {
 | |
|       (callback_context->callback)(expiry_deadline);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| void SystemTimer::InvokeAt(SystemClock::time_point timestamp) {
 | |
|   std::lock_guard lock(native_type_.callback_context->mutex);
 | |
| 
 | |
|   // First, cancel any outstanding requests.
 | |
|   if (native_type_.active_timer_enabled) {
 | |
|     *native_type_.active_timer_enabled = false;
 | |
|   }
 | |
| 
 | |
|   // Second, active another detached timer thread with a new shared atomic bool.
 | |
|   native_type_.active_timer_enabled = std::make_shared<bool>(true);
 | |
|   std::thread(SystemTimerThreadFunction,
 | |
|               native_type_.active_timer_enabled,
 | |
|               native_type_.callback_context,
 | |
|               timestamp)
 | |
|       .detach();
 | |
| }
 | |
| 
 | |
| void SystemTimer::Cancel() {
 | |
|   std::lock_guard lock(native_type_.callback_context->mutex);
 | |
| 
 | |
|   if (native_type_.active_timer_enabled) {
 | |
|     *native_type_.active_timer_enabled = false;
 | |
|   }
 | |
| }
 | |
| 
 | |
| }  // namespace pw::chrono
 |