Flutter Engine
message_loop_darwin.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/fml/platform/darwin/message_loop_darwin.h"
6 
7 #include <CoreFoundation/CFRunLoop.h>
8 #include <Foundation/Foundation.h>
9 
10 #include "flutter/fml/logging.h"
11 
12 namespace fml {
13 
14 static constexpr CFTimeInterval kDistantFuture = 1.0e10;
15 
16 MessageLoopDarwin::MessageLoopDarwin()
17  : running_(false), loop_((CFRunLoopRef)CFRetain(CFRunLoopGetCurrent())) {
18  FML_DCHECK(loop_ != nullptr);
19 
20  // Setup the delayed wake source.
21  CFRunLoopTimerContext timer_context = {
22  .info = this,
23  };
24  delayed_wake_timer_.Reset(
25  CFRunLoopTimerCreate(kCFAllocatorDefault, kDistantFuture /* fire date */,
26  HUGE_VAL /* interval */, 0 /* flags */, 0 /* order */,
27  reinterpret_cast<CFRunLoopTimerCallBack>(&MessageLoopDarwin::OnTimerFire)
28  /* callout */,
29  &timer_context /* context */));
30  FML_DCHECK(delayed_wake_timer_ != nullptr);
31  CFRunLoopAddTimer(loop_, delayed_wake_timer_, kCFRunLoopCommonModes);
32 }
33 
34 MessageLoopDarwin::~MessageLoopDarwin() {
35  CFRunLoopTimerInvalidate(delayed_wake_timer_);
36  CFRunLoopRemoveTimer(loop_, delayed_wake_timer_, kCFRunLoopCommonModes);
37 }
38 
39 void MessageLoopDarwin::Run() {
40  FML_DCHECK(loop_ == CFRunLoopGetCurrent());
41 
42  running_ = true;
43 
44  while (running_) {
45  @autoreleasepool {
46  int result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, kDistantFuture, YES);
47  if (result == kCFRunLoopRunStopped || result == kCFRunLoopRunFinished) {
48  // This handles the case where the loop is terminated using
49  // CoreFoundation APIs.
50  @autoreleasepool {
52  }
53  running_ = false;
54  }
55  }
56  }
57 }
58 
59 void MessageLoopDarwin::Terminate() {
60  running_ = false;
61  CFRunLoopStop(loop_);
62 }
63 
64 void MessageLoopDarwin::WakeUp(fml::TimePoint time_point) {
65  // Rearm the timer. The time bases used by CoreFoundation and FXL are
66  // different and must be accounted for.
67  CFRunLoopTimerSetNextFireDate(
68  delayed_wake_timer_,
69  CFAbsoluteTimeGetCurrent() + (time_point - fml::TimePoint::Now()).ToSecondsF());
70 }
71 
72 void MessageLoopDarwin::OnTimerFire(CFRunLoopTimerRef timer, MessageLoopDarwin* loop) {
73  @autoreleasepool {
74  // RunExpiredTasksNow rearms the timer as appropriate via a call to WakeUp.
75  loop->RunExpiredTasksNow();
76  }
77 }
78 
79 } // namespace fml
#define FML_DCHECK(condition)
Definition: logging.h:86
Definition: ascii_trie.cc:9
static constexpr CFTimeInterval kDistantFuture
static TimePoint Now()
Definition: time_point.cc:26