Flutter Engine
The Flutter Engine
process.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_BIN_PROCESS_H_
6#define RUNTIME_BIN_PROCESS_H_
7
8#include <errno.h>
9
10#include "bin/builtin.h"
11#include "bin/io_buffer.h"
12#include "bin/lockers.h"
13#include "bin/namespace.h"
14#include "bin/thread.h"
15#include "platform/globals.h"
16#if !defined(DART_HOST_OS_WINDOWS)
18#endif
19#include "platform/utils.h"
20
21namespace dart {
22namespace bin {
23
25 public:
26 ProcessResult() : exit_code_(0) {}
27
30
31 void set_exit_code(intptr_t exit_code) { exit_code_ = exit_code; }
32
33 Dart_Handle stdout_data() { return stdout_data_; }
34 Dart_Handle stderr_data() { return stderr_data_; }
35 intptr_t exit_code() { return exit_code_; }
36
37 private:
38 Dart_Handle stdout_data_;
39 Dart_Handle stderr_data_;
40 intptr_t exit_code_;
41
42 DISALLOW_ALLOCATION();
43};
44
45// To be kept in sync with ProcessSignal consts in sdk/lib/io/process.dart
46// Note that this map is as on Linux.
69 kSigurg = 23,
76 kSigsys = 31,
78};
79
80// To be kept in sync with ProcessStartMode consts in sdk/lib/io/process.dart.
86};
87
88class Process {
89 public:
90 static void Init();
91 static void Cleanup();
92
93 // Start a new process providing access to stdin, stdout, stderr and
94 // process exit streams.
95 static int Start(Namespace* namespc,
96 const char* path,
97 char* arguments[],
98 intptr_t arguments_length,
99 const char* working_directory,
100 char* environment[],
101 intptr_t environment_length,
103 intptr_t* in,
104 intptr_t* out,
105 intptr_t* err,
106 intptr_t* id,
107 intptr_t* exit_handler,
108 char** os_error_message);
109
110 static bool Wait(intptr_t id,
111 intptr_t in,
112 intptr_t out,
113 intptr_t err,
114 intptr_t exit_handler,
116
117 // Kill a process with a given pid.
118 static bool Kill(intptr_t id, int signal);
119
120 // Terminate the exit code handler thread. Does not return before
121 // the thread has terminated.
123
124 static int GlobalExitCode() {
125 MutexLocker ml(global_exit_code_mutex_);
126 return global_exit_code_;
127 }
128
129 static void SetGlobalExitCode(int exit_code) {
130 MutexLocker ml(global_exit_code_mutex_);
131 global_exit_code_ = exit_code;
132 }
133
134 typedef void (*ExitHook)(int64_t exit_code);
135 static void SetExitHook(ExitHook hook) { exit_hook_ = hook; }
136 static void RunExitHook(int64_t exit_code) {
137 if (exit_hook_ != nullptr) {
138 exit_hook_(exit_code);
139 }
140 }
141
142 static intptr_t CurrentProcessId();
143
144 static intptr_t SetSignalHandler(intptr_t signal);
145 // When there is a current Isolate and the 'port' argument is
146 // Dart_GetMainPortId(), this clears the signal handler for the current
147 // isolate. When 'port' is ILLEGAL_PORT, this clears all signal handlers for
148 // 'signal' for all Isolates.
149 static void ClearSignalHandler(intptr_t signal, Dart_Port port);
150 static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port);
151 static void ClearAllSignalHandlers();
152
154 intptr_t* pid);
156
157 static int64_t CurrentRSS();
158 static int64_t MaxRSS();
159 static void GetRSSInformation(int64_t* max_rss, int64_t* current_rss);
160
163
164 private:
165 static int global_exit_code_;
166 static Mutex* global_exit_code_mutex_;
167 static ExitHook exit_hook_;
168
169 DISALLOW_ALLOCATION();
170 DISALLOW_IMPLICIT_CONSTRUCTORS(Process);
171};
172
173typedef void (*sa_handler_t)(int);
174
176 public:
177 SignalInfo(intptr_t fd,
178 intptr_t signal,
181 : fd_(fd),
182 signal_(signal),
183 oldact_(oldact),
184 // SignalInfo is expected to be created when in a isolate.
185 port_(Dart_GetMainPortId()),
186 next_(next),
187 prev_(nullptr) {
188 if (next_ != nullptr) {
189 next_->prev_ = this;
190 }
191 }
192
194
195 void Unlink() {
196 if (prev_ != nullptr) {
197 prev_->next_ = next_;
198 }
199 if (next_ != nullptr) {
200 next_->prev_ = prev_;
201 }
202 }
203
204 intptr_t fd() const { return fd_; }
205 intptr_t signal() const { return signal_; }
206 sa_handler_t oldact() const { return oldact_; }
207 Dart_Port port() const { return port_; }
208 SignalInfo* next() const { return next_; }
209
210 private:
211 intptr_t fd_;
212 intptr_t signal_;
213 sa_handler_t oldact_;
214 // The port_ is used to identify what isolate the signal-info belongs to.
215 Dart_Port port_;
216 SignalInfo* next_;
217 SignalInfo* prev_;
218
219 DISALLOW_COPY_AND_ASSIGN(SignalInfo);
220};
221
222// Utility class for collecting the output when running a process
223// synchronously by using Process::Wait. This class is sub-classed in
224// the platform specific files to implement reading into the buffers
225// allocated.
227 protected:
228 static constexpr intptr_t kBufferSize = 16 * 1024;
229
231 public:
232 explicit BufferListNode(intptr_t size) {
233 data_ = new uint8_t[size];
234 // We check for a failed allocation below in Allocate()
235 next_ = nullptr;
236 }
237
238 ~BufferListNode() { delete[] data_; }
239
240 bool Valid() const { return data_ != nullptr; }
241
242 uint8_t* data() const { return data_; }
243 BufferListNode* next() const { return next_; }
244 void set_next(BufferListNode* n) { next_ = n; }
245
246 private:
247 uint8_t* data_;
248 BufferListNode* next_;
249
250 DISALLOW_IMPLICIT_CONSTRUCTORS(BufferListNode);
251 };
252
253 public:
255 : head_(nullptr), tail_(nullptr), data_size_(0), free_size_(0) {}
257 Free();
259 }
260
261 // Returns the collected data as a Uint8List. If an error occurs an
262 // error handle is returned.
264 uint8_t* buffer;
265 intptr_t buffer_position = 0;
267 if (Dart_IsNull(result)) {
269 }
270 if (Dart_IsError(result)) {
271 Free();
272 return result;
273 }
274 for (BufferListNode* current = head_; current != nullptr;
275 current = current->next()) {
276 intptr_t to_copy = dart::Utils::Minimum(data_size_, kBufferSize);
277 memmove(buffer + buffer_position, current->data(), to_copy);
278 buffer_position += to_copy;
279 data_size_ -= to_copy;
280 }
281 ASSERT(data_size_ == 0);
282 Free();
283 return result;
284 }
285
286#if defined(DEBUG)
287 bool IsEmpty() const { return (head_ == nullptr) && (tail_ == nullptr); }
288#endif
289
290 protected:
291 bool Allocate() {
292 ASSERT(free_size_ == 0);
294 if ((node == nullptr) || !node->Valid()) {
295 // Failed to allocate a buffer for the node.
296 delete node;
297 return false;
298 }
299 if (head_ == nullptr) {
300 head_ = node;
301 tail_ = node;
302 } else {
303 ASSERT(tail_->next() == nullptr);
304 tail_->set_next(node);
305 tail_ = node;
306 }
307 free_size_ = kBufferSize;
308 return true;
309 }
310
311 void Free() {
312 BufferListNode* current = head_;
313 while (current != nullptr) {
314 BufferListNode* tmp = current;
315 current = current->next();
316 delete tmp;
317 }
318 head_ = nullptr;
319 tail_ = nullptr;
320 data_size_ = 0;
321 free_size_ = 0;
322 }
323
324 // Returns the address of the first byte in the free space.
325 uint8_t* FreeSpaceAddress() {
326 return tail_->data() + (kBufferSize - free_size_);
327 }
328
329 intptr_t data_size() const { return data_size_; }
330 void set_data_size(intptr_t size) { data_size_ = size; }
331
332 intptr_t free_size() const { return free_size_; }
333 void set_free_size(intptr_t size) { free_size_ = size; }
334
335 BufferListNode* head() const { return head_; }
336 BufferListNode* tail() const { return tail_; }
337
338 private:
339 // Linked list for data collected.
340 BufferListNode* head_;
341 BufferListNode* tail_;
342
343 // Number of bytes of data collected in the linked list.
344 intptr_t data_size_;
345
346 // Number of free bytes in the last node in the list.
347 intptr_t free_size_;
348
349 DISALLOW_COPY_AND_ASSIGN(BufferListBase);
350};
351
352#if defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA) || \
353 defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS)
354class BufferList : public BufferListBase {
355 public:
356 BufferList() {}
357
358 bool Read(int fd, intptr_t available) {
359 // Read all available bytes.
360 while (available > 0) {
361 if (free_size() == 0) {
362 if (!Allocate()) {
363 errno = ENOMEM;
364 return false;
365 }
366 }
367 ASSERT(free_size() > 0);
368 ASSERT(free_size() <= kBufferSize);
369 intptr_t block_size = dart::Utils::Minimum(free_size(), available);
370#if defined(DART_HOST_OS_FUCHSIA)
371 intptr_t bytes = NO_RETRY_EXPECTED(
372 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
373#else
374 intptr_t bytes = TEMP_FAILURE_RETRY(
375 read(fd, reinterpret_cast<void*>(FreeSpaceAddress()), block_size));
376#endif // defined(DART_HOST_OS_FUCHSIA)
377 if (bytes < 0) {
378 return false;
379 }
380 set_data_size(data_size() + bytes);
381 set_free_size(free_size() - bytes);
382 available -= bytes;
383 }
384 return true;
385 }
386
387 private:
388 DISALLOW_COPY_AND_ASSIGN(BufferList);
389};
390#endif // defined(DART_HOST_OS_ANDROID) ...
391
392} // namespace bin
393} // namespace dart
394
395#endif // RUNTIME_BIN_PROCESS_H_
static bool read(SkStream *stream, void *buffer, size_t amount)
static const size_t kBufferSize
Definition: SkString.cpp:27
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
static T Minimum(T x, T y)
Definition: utils.h:36
void set_next(BufferListNode *n)
Definition: process.h:244
BufferListNode * next() const
Definition: process.h:243
BufferListNode * tail() const
Definition: process.h:336
static constexpr intptr_t kBufferSize
Definition: process.h:228
uint8_t * FreeSpaceAddress()
Definition: process.h:325
intptr_t free_size() const
Definition: process.h:332
intptr_t data_size() const
Definition: process.h:329
Dart_Handle GetData()
Definition: process.h:263
void set_free_size(intptr_t size)
Definition: process.h:333
BufferListNode * head() const
Definition: process.h:335
void set_data_size(intptr_t size)
Definition: process.h:330
static Dart_Handle NewDartOSError()
Definition: dartutils.cc:702
static Dart_Handle Allocate(intptr_t size, uint8_t **buffer)
Definition: io_buffer.cc:12
Dart_Handle stderr_data()
Definition: process.h:34
void set_stdout_data(Dart_Handle stdout_data)
Definition: process.h:28
void set_stderr_data(Dart_Handle stderr_data)
Definition: process.h:29
Dart_Handle stdout_data()
Definition: process.h:33
intptr_t exit_code()
Definition: process.h:35
void set_exit_code(intptr_t exit_code)
Definition: process.h:31
static bool ModeIsAttached(ProcessStartMode mode)
Definition: process.cc:62
static void ClearSignalHandler(intptr_t signal, Dart_Port port)
static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port)
static void Cleanup()
static void SetGlobalExitCode(int exit_code)
Definition: process.h:129
static bool ModeHasStdio(ProcessStartMode mode)
Definition: process.cc:66
static Dart_Handle GetProcessIdNativeField(Dart_Handle process, intptr_t *pid)
Definition: process.cc:318
static int64_t CurrentRSS()
static void GetRSSInformation(int64_t *max_rss, int64_t *current_rss)
Definition: process.cc:393
static intptr_t CurrentProcessId()
static void TerminateExitCodeHandler()
static int GlobalExitCode()
Definition: process.h:124
static bool Wait(intptr_t id, intptr_t in, intptr_t out, intptr_t err, intptr_t exit_handler, ProcessResult *result)
static void Init()
static int64_t MaxRSS()
static bool Kill(intptr_t id, int signal)
static intptr_t SetSignalHandler(intptr_t signal)
static void SetExitHook(ExitHook hook)
Definition: process.h:135
static Dart_Handle SetProcessIdNativeField(Dart_Handle process, intptr_t pid)
Definition: process.cc:323
void(* ExitHook)(int64_t exit_code)
Definition: process.h:134
static void ClearAllSignalHandlers()
Definition: process.cc:70
static void RunExitHook(int64_t exit_code)
Definition: process.h:136
static int Start(Namespace *namespc, const char *path, char *arguments[], intptr_t arguments_length, const char *working_directory, char *environment[], intptr_t environment_length, ProcessStartMode mode, intptr_t *in, intptr_t *out, intptr_t *err, intptr_t *id, intptr_t *exit_handler, char **os_error_message)
SignalInfo(intptr_t fd, intptr_t signal, sa_handler_t oldact, SignalInfo *next)
Definition: process.h:177
intptr_t signal() const
Definition: process.h:205
intptr_t fd() const
Definition: process.h:204
SignalInfo * next() const
Definition: process.h:208
sa_handler_t oldact() const
Definition: process.h:206
Dart_Port port() const
Definition: process.h:207
int64_t Dart_Port
Definition: dart_api.h:1525
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
#define ASSERT(E)
GAsyncResult * result
SK_API bool Read(SkStreamSeekable *src, SkDocumentPage *dstArray, int dstArrayCount, const SkDeserialProcs *=nullptr)
dictionary to_copy
Definition: create.py:30
void(* sa_handler_t)(int)
Definition: process.h:173
ProcessStartMode
Definition: process.h:81
@ kDetached
Definition: process.h:84
@ kInheritStdio
Definition: process.h:83
@ kNormal
Definition: process.h:82
@ kDetachedWithStdio
Definition: process.h:85
ProcessSignals
Definition: process.h:47
@ kSigtrap
Definition: process.h:52
@ kSigtstp
Definition: process.h:66
@ kSigstop
Definition: process.h:65
@ kSigbus
Definition: process.h:54
@ kSighup
Definition: process.h:48
@ kSigpoll
Definition: process.h:75
@ kSigttin
Definition: process.h:67
@ kSigxcpu
Definition: process.h:70
@ kSigkill
Definition: process.h:56
@ kSigquit
Definition: process.h:50
@ kSigusr1
Definition: process.h:57
@ kSigvtalrm
Definition: process.h:72
@ kSigabrt
Definition: process.h:53
@ kSigcont
Definition: process.h:64
@ kSigterm
Definition: process.h:62
@ kSigusr2
Definition: process.h:59
@ kSigfpe
Definition: process.h:55
@ kSigxfsz
Definition: process.h:71
@ kSigchld
Definition: process.h:63
@ kSigsegv
Definition: process.h:58
@ kSigill
Definition: process.h:51
@ kLastSignal
Definition: process.h:77
@ kSigwinch
Definition: process.h:74
@ kSigprof
Definition: process.h:73
@ kSigttou
Definition: process.h:68
@ kSigalrm
Definition: process.h:61
@ kSigint
Definition: process.h:49
@ kSigsys
Definition: process.h:76
@ kSigurg
Definition: process.h:69
@ kSigpipe
Definition: process.h:60
static dart::SimpleHashMap * environment
Definition: gen_snapshot.cc:59
Definition: dart_vm.cc:33
DART_EXPORT Dart_Port Dart_GetMainPortId()
static void * Allocate(uword size, Zone *zone)
Definition: allocation.cc:14
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
Definition: switches.h:87
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
bool EMSCRIPTEN_KEEPALIVE IsEmpty(const SkPath &path)
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
#define NO_RETRY_EXPECTED(expression)
#define TEMP_FAILURE_RETRY(expression)
static void process(const char *inPath, const char *lexer, const char *token, const char *hPath, const char *cppPath)
Definition: Main.cpp:114