Flutter macOS Embedder
FlutterThreadSynchronizer Class Reference

#import <FlutterThreadSynchronizer.h>

Inheritance diagram for FlutterThreadSynchronizer:

Instance Methods

(nullable instancetype) - init
 
(void) - beginResizeForView:size:notify:
 
(void) - performCommitForView:size:notify:
 
(void) - performOnPlatformThread:
 
(void) - registerView:
 
(void) - deregisterView:
 
(void) - shutdown
 
(nullable instancetype) - initWithMainQueue:
 
(BOOL) - isWaitingWhenMutexIsAvailable
 
(void) - blockUntilFrameAvailable
 

Detailed Description

Takes care of synchronization between raster and platform thread.

All methods of this class must be called from the platform thread, except for performCommitForView:size:notify:.

Definition at line 18 of file FlutterThreadSynchronizer.h.

Method Documentation

◆ beginResizeForView:size:notify:

- (void) beginResizeForView: (FlutterViewIdentifier viewIdentifier
size: (CGSize)  size
notify: (nonnull dispatch_block_t)  notify 

Blocks until all views have a commit with their given sizes (or empty) is requested.

Definition at line 102 of file FlutterThreadSynchronizer.mm.

102  :(FlutterViewIdentifier)viewIdentifier
103  size:(CGSize)size
104  notify:(nonnull dispatch_block_t)notify {
105  dispatch_assert_queue(_mainQueue);
106  std::unique_lock<std::mutex> lock(_mutex);
107 
108  if (![self allViewsHaveFrame] || _shuttingDown) {
109  // No blocking until framework produces at least one frame
110  notify();
111  return;
112  }
113 
114  [self drain];
115 
116  notify();
117 
118  _contentSizes[viewIdentifier] = CGSizeMake(-1, -1);
119 
120  _beginResizeWaiting = YES;
121 
122  while (true) {
123  if (_shuttingDown) {
124  break;
125  }
126  const CGSize& contentSize = _contentSizes[viewIdentifier];
127  if (CGSizeEqualToSize(contentSize, size) || CGSizeEqualToSize(contentSize, CGSizeZero)) {
128  break;
129  }
130  _condBlockBeginResize.wait(lock);
131  [self drain];
132  }
133 
134  _beginResizeWaiting = NO;
135 }

Referenced by TEST().

◆ blockUntilFrameAvailable

- (void) blockUntilFrameAvailable

Blocks current thread until there is frame available. Used in FlutterEngineTest.

Provided by category FlutterThreadSynchronizer(TestUtils).

◆ deregisterView:

- (void) deregisterView: (FlutterViewIdentifier viewIdentifier

Requests the synchronizer to no longer track a view.

It is typically done when the view controller is destroyed.

Definition at line 186 of file FlutterThreadSynchronizer.mm.

186  :(FlutterViewIdentifier)viewIdentifier {
187  dispatch_assert_queue(_mainQueue);
188  std::unique_lock<std::mutex> lock(_mutex);
189  _contentSizes.erase(viewIdentifier);
190 }

◆ init

- (instancetype) init

Creates a FlutterThreadSynchronizer that uses the OS main thread as the platform thread.

Definition at line 47 of file FlutterThreadSynchronizer.mm.

47  {
48  return [self initWithMainQueue:dispatch_get_main_queue()];
49 }

References initWithMainQueue:.

◆ initWithMainQueue:

- (nullable instancetype) initWithMainQueue: (nonnull dispatch_queue_t)  queue

Creates a FlutterThreadSynchronizer that uses the specified queue as the platform thread.

Provided by category FlutterThreadSynchronizer(TestUtils).

Referenced by init.

◆ isWaitingWhenMutexIsAvailable

- (BOOL) isWaitingWhenMutexIsAvailable

Blocks current thread until the mutex is available, then return whether the synchronizer is waiting for a correct commit during resizing.

After calling an operation of the thread synchronizer, call this method, and when it returns, the thread synchronizer can be at one of the following 3 states:

  1. The operation has not started at all (with a return value FALSE.)
  2. The operation has ended (with a return value FALSE.)
  3. beginResizeForView: is in progress, waiting (with a return value TRUE.)

By eliminating the 1st case (such as using the notify callback), we can use this return value to decide whether the synchronizer is in case 2 or case 3, that is whether the resizing is blocked by a mismatching commit.

Provided by category FlutterThreadSynchronizer(TestUtils).

◆ performCommitForView:size:notify:

- (void) performCommitForView: (FlutterViewIdentifier viewIdentifier
size: (CGSize)  size
notify: (nonnull dispatch_block_t)  notify 

Called from raster thread. Schedules the given block on platform thread and blocks until it is performed.

If platform thread is blocked in beginResize: for given size (or size is empty), unblocks platform thread.

The notify block is guaranteed to be called within a core animation transaction.

Definition at line 137 of file FlutterThreadSynchronizer.mm.

137  :(FlutterViewIdentifier)viewIdentifier
138  size:(CGSize)size
139  notify:(nonnull dispatch_block_t)notify {
140  dispatch_assert_queue_not(_mainQueue);
141  fml::AutoResetWaitableEvent event;
142  {
143  std::unique_lock<std::mutex> lock(_mutex);
144  if (_shuttingDown) {
145  // Engine is shutting down, main thread may be blocked by the engine
146  // waiting for raster thread to finish.
147  return;
148  }
149  fml::AutoResetWaitableEvent& e = event;
150  _scheduledBlocks.push_back(^{
151  notify();
152  _contentSizes[viewIdentifier] = size;
153  e.Signal();
154  });
155  if (_beginResizeWaiting) {
156  _condBlockBeginResize.notify_all();
157  } else {
158  dispatch_async(_mainQueue, ^{
159  std::unique_lock<std::mutex> lock(_mutex);
160  [self drain];
161  });
162  }
163  }
164  event.Wait();
165 }

Referenced by TEST(), and flutter::testing::TEST_F().

◆ performOnPlatformThread:

- (void) performOnPlatformThread: (nonnull dispatch_block_t)  block

Schedules the given block to be performed on the platform thread. The block will be performed even if the platform thread is blocked waiting for a commit.

Definition at line 167 of file FlutterThreadSynchronizer.mm.

167  :(nonnull dispatch_block_t)block {
168  std::unique_lock<std::mutex> lock(_mutex);
169  _scheduledBlocks.push_back(block);
170  if (_beginResizeWaiting) {
171  _condBlockBeginResize.notify_all();
172  } else {
173  dispatch_async(_mainQueue, ^{
174  std::unique_lock<std::mutex> lock(_mutex);
175  [self drain];
176  });
177  }
178 }

◆ registerView:

- (void) registerView: (FlutterViewIdentifier viewIdentifier

Requests the synchronizer to track another view.

A view must be registered before calling begineResizeForView: or performCommitForView:. It is typically done when the view controller is created.

Definition at line 180 of file FlutterThreadSynchronizer.mm.

180  :(FlutterViewIdentifier)viewIdentifier {
181  dispatch_assert_queue(_mainQueue);
182  std::unique_lock<std::mutex> lock(_mutex);
183  _contentSizes[viewIdentifier] = CGSizeZero;
184 }

Referenced by TEST().

◆ shutdown

- (void) shutdown

Called when the engine shuts down.

Prevents any further synchronization and no longer blocks any threads.

Definition at line 192 of file FlutterThreadSynchronizer.mm.

192  {
193  dispatch_assert_queue(_mainQueue);
194  std::unique_lock<std::mutex> lock(_mutex);
195  _shuttingDown = YES;
196  _condBlockBeginResize.notify_all();
197  [self drain];
198 }

Referenced by TEST(), and flutter::testing::TEST_F().


The documentation for this class was generated from the following files:
FlutterViewIdentifier
int64_t FlutterViewIdentifier
Definition: FlutterViewController.h:21