mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
 | |
| // reserved. Use of this source code is governed by a BSD-style license that
 | |
| // can be found in the LICENSE file.
 | |
| 
 | |
| #include "tests/shared/browser/main_message_loop_external_pump.h"
 | |
| 
 | |
| #include <climits>
 | |
| 
 | |
| #include "include/cef_app.h"
 | |
| #include "include/wrapper/cef_helpers.h"
 | |
| #include "tests/shared/browser/main_message_loop.h"
 | |
| 
 | |
| namespace client {
 | |
| 
 | |
| namespace {
 | |
| 
 | |
| // Special timer delay placeholder value. Intentionally 32-bit for Windows and
 | |
| // OS X platform API compatibility.
 | |
| const int32 kTimerDelayPlaceholder = INT_MAX;
 | |
| 
 | |
| // The maximum number of milliseconds we're willing to wait between calls to
 | |
| // DoWork().
 | |
| const int64 kMaxTimerDelay = 1000 / 30;  // 30fps
 | |
| 
 | |
| client::MainMessageLoopExternalPump* g_external_message_pump = nullptr;
 | |
| 
 | |
| }  // namespace
 | |
| 
 | |
| MainMessageLoopExternalPump::MainMessageLoopExternalPump()
 | |
|     : is_active_(false), reentrancy_detected_(false) {
 | |
|   DCHECK(!g_external_message_pump);
 | |
|   g_external_message_pump = this;
 | |
| }
 | |
| 
 | |
| MainMessageLoopExternalPump::~MainMessageLoopExternalPump() {
 | |
|   g_external_message_pump = nullptr;
 | |
| }
 | |
| 
 | |
| MainMessageLoopExternalPump* MainMessageLoopExternalPump::Get() {
 | |
|   return g_external_message_pump;
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPump::OnScheduleWork(int64 delay_ms) {
 | |
|   REQUIRE_MAIN_THREAD();
 | |
| 
 | |
|   if (delay_ms == kTimerDelayPlaceholder && IsTimerPending()) {
 | |
|     // Don't set the maximum timer requested from DoWork() if a timer event is
 | |
|     // currently pending.
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   KillTimer();
 | |
| 
 | |
|   if (delay_ms <= 0) {
 | |
|     // Execute the work immediately.
 | |
|     DoWork();
 | |
|   } else {
 | |
|     // Never wait longer than the maximum allowed time.
 | |
|     if (delay_ms > kMaxTimerDelay) {
 | |
|       delay_ms = kMaxTimerDelay;
 | |
|     }
 | |
| 
 | |
|     // Results in call to OnTimerTimeout() after the specified delay.
 | |
|     SetTimer(delay_ms);
 | |
|   }
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPump::OnTimerTimeout() {
 | |
|   REQUIRE_MAIN_THREAD();
 | |
| 
 | |
|   KillTimer();
 | |
|   DoWork();
 | |
| }
 | |
| 
 | |
| void MainMessageLoopExternalPump::DoWork() {
 | |
|   const bool was_reentrant = PerformMessageLoopWork();
 | |
|   if (was_reentrant) {
 | |
|     // Execute the remaining work as soon as possible.
 | |
|     OnScheduleMessagePumpWork(0);
 | |
|   } else if (!IsTimerPending()) {
 | |
|     // Schedule a timer event at the maximum allowed time. This may be dropped
 | |
|     // in OnScheduleWork() if another timer event is already in-flight.
 | |
|     OnScheduleMessagePumpWork(kTimerDelayPlaceholder);
 | |
|   }
 | |
| }
 | |
| 
 | |
| bool MainMessageLoopExternalPump::PerformMessageLoopWork() {
 | |
|   if (is_active_) {
 | |
|     // When CefDoMessageLoopWork() is called there may be various callbacks
 | |
|     // (such as paint and IPC messages) that result in additional calls to this
 | |
|     // method. If re-entrancy is detected we must repost a request again to the
 | |
|     // owner thread to ensure that the discarded call is executed in the future.
 | |
|     reentrancy_detected_ = true;
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   reentrancy_detected_ = false;
 | |
| 
 | |
|   is_active_ = true;
 | |
|   CefDoMessageLoopWork();
 | |
|   is_active_ = false;
 | |
| 
 | |
|   // |reentrancy_detected_| may have changed due to re-entrant calls to this
 | |
|   // method.
 | |
|   return reentrancy_detected_;
 | |
| }
 | |
| 
 | |
| }  // namespace client
 |