6#if defined(DART_HOST_OS_WINDOWS)
27static constexpr int kReadHandle = 0;
28static constexpr int kWriteHandle = 1;
30int Process::global_exit_code_ = 0;
31Mutex* Process::global_exit_code_mutex_ =
nullptr;
41 ProcessInfo(
DWORD process_id,
45 : process_id_(process_id),
46 process_handle_(process_handle),
47 wait_handle_(wait_handle),
48 exit_pipe_(exit_pipe) {}
51 BOOL success = CloseHandle(process_handle_);
53 FATAL(
"Failed to close process handle");
55 success = CloseHandle(exit_pipe_);
57 FATAL(
"Failed to close process exit code pipe");
61 DWORD pid() {
return process_id_; }
62 HANDLE process_handle() {
return process_handle_; }
63 HANDLE wait_handle() {
return wait_handle_; }
64 HANDLE exit_pipe() {
return exit_pipe_; }
65 ProcessInfo*
next() {
return next_; }
66 void set_next(ProcessInfo*
next) { next_ =
next; }
86class ProcessInfoList {
96 MutexLocker locker(mutex_);
98 BOOL success = RegisterWaitForSingleObject(
99 &wait_handle, handle, &ExitCodeCallback,
reinterpret_cast<PVOID>(pid),
100 INFINITE, WT_EXECUTEONLYONCE);
102 FATAL(
"Failed to register exit code wait operation.");
104 ProcessInfo*
info =
new ProcessInfo(pid, handle, wait_handle, pipe);
106 info->set_next(active_processes_);
107 active_processes_ =
info;
110 static bool LookupProcess(
DWORD pid,
114 MutexLocker locker(mutex_);
115 ProcessInfo* current = active_processes_;
116 while (current !=
nullptr) {
117 if (current->pid() == pid) {
118 *handle = current->process_handle();
119 *wait_handle = current->wait_handle();
120 *pipe = current->exit_pipe();
123 current = current->next();
128 static void RemoveProcess(
DWORD pid) {
129 MutexLocker locker(mutex_);
130 ProcessInfo*
prev =
nullptr;
131 ProcessInfo* current = active_processes_;
132 while (current !=
nullptr) {
133 if (current->pid() == pid) {
134 if (
prev ==
nullptr) {
135 active_processes_ = current->next();
137 prev->set_next(current->next());
143 current = current->next();
158 bool success = LookupProcess(pid, &handle, &wait_handle, &exit_pipe);
160 FATAL(
"Failed to lookup process in list of active processes");
163 BOOL ok = UnregisterWait(wait_handle);
165 FATAL(
"Failed unregistering wait operation");
169 ok = GetExitCodeProcess(handle,
reinterpret_cast<DWORD*
>(&exit_code));
175 exit_code =
abs(exit_code);
178 int message[2] = {exit_code, negative};
186 FATAL(
"Failed to write entire process exit message");
196 static ProcessInfo* active_processes_;
199 static Mutex* mutex_;
205ProcessInfo* ProcessInfoList::active_processes_ =
nullptr;
206Mutex* ProcessInfoList::mutex_ =
nullptr;
209enum NamedPipeType { kInheritRead, kInheritWrite, kInheritNone };
216static bool CreateProcessPipe(
HANDLE handles[2],
218 NamedPipeType
type) {
220 SECURITY_ATTRIBUTES inherit_handle;
221 inherit_handle.nLength =
sizeof(SECURITY_ATTRIBUTES);
222 inherit_handle.bInheritHandle =
TRUE;
223 inherit_handle.lpSecurityDescriptor =
nullptr;
225 if (
type == kInheritRead) {
226 handles[kWriteHandle] =
227 CreateNamedPipeW(pipe_name, PIPE_ACCESS_OUTBOUND | FILE_FLAG_OVERLAPPED,
228 PIPE_TYPE_BYTE | PIPE_WAIT,
240 handles[kReadHandle] =
241 CreateFileW(pipe_name, GENERIC_READ, 0, &inherit_handle, OPEN_EXISTING,
242 FILE_READ_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
nullptr);
249 handles[kReadHandle] =
250 CreateNamedPipeW(pipe_name, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
251 PIPE_TYPE_BYTE | PIPE_WAIT,
263 handles[kWriteHandle] = CreateFileW(
264 pipe_name, GENERIC_WRITE, 0,
265 (
type == kInheritWrite) ? &inherit_handle :
nullptr, OPEN_EXISTING,
266 FILE_WRITE_ATTRIBUTES | FILE_FLAG_OVERLAPPED,
nullptr);
275static void CloseProcessPipe(
HANDLE handles[2]) {
276 for (
int i = kReadHandle;
i < kWriteHandle;
i++) {
278 if (!CloseHandle(handles[
i])) {
286static void CloseProcessPipes(
HANDLE handles1[2],
290 CloseProcessPipe(handles1);
291 CloseProcessPipe(handles2);
292 CloseProcessPipe(handles3);
293 CloseProcessPipe(handles4);
296static int SetOsErrorMessage(
char** os_error_message) {
298 const int kMaxMessageLength = 256;
299 wchar_t message[kMaxMessageLength];
307 SECURITY_ATTRIBUTES inherit_handle;
308 inherit_handle.nLength =
sizeof(SECURITY_ATTRIBUTES);
309 inherit_handle.bInheritHandle =
TRUE;
310 inherit_handle.lpSecurityDescriptor =
nullptr;
312 &inherit_handle, OPEN_EXISTING, 0,
nullptr);
319const int kMaxPipeNameSize = 80;
321static int GenerateNames(
wchar_t pipe_names[Count][kMaxPipeNameSize]) {
323 RPC_STATUS status = UuidCreateSequential(&uuid);
324 if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
327 RPC_WSTR uuid_string;
328 status = UuidToStringW(&uuid, &uuid_string);
329 if (status != RPC_S_OK) {
332 for (
int i = 0;
i < Count;
i++) {
333 static const wchar_t*
prefix =
L"\\\\.\\Pipe\\dart";
334 _snwprintf(pipe_names[
i], kMaxPipeNameSize,
L"%s_%s_%d",
prefix,
337 status = RpcStringFreeW(&uuid_string);
338 if (status != RPC_S_OK) {
344class ProcessStarter {
346 ProcessStarter(
const char*
path,
348 intptr_t arguments_length,
349 const char* working_directory,
351 intptr_t environment_length,
357 intptr_t* exit_handler,
358 char** os_error_message)
360 working_directory_(working_directory),
366 exit_handler_(exit_handler),
367 os_error_message_(os_error_message) {
379 wchar_t** system_arguments;
380 system_arguments =
reinterpret_cast<wchar_t**
>(
382 for (
int i = 0;
i < arguments_length;
i++) {
387 int command_line_length = wcslen(system_path);
388 for (
int i = 0;
i < arguments_length;
i++) {
389 command_line_length += wcslen(system_arguments[
i]);
392 command_line_length += arguments_length + 1;
395 command_line_ =
reinterpret_cast<wchar_t*
>(
398 int remaining = command_line_length;
400 _snwprintf(command_line_ +
len, remaining,
L"%s", system_path);
404 for (
int i = 0;
i < arguments_length;
i++) {
405 written = _snwprintf(command_line_ +
len, remaining,
L" %s",
406 system_arguments[
i]);
413 environment_block_ =
nullptr;
415 wchar_t** system_environment;
416 system_environment =
reinterpret_cast<wchar_t**
>(
419 for (intptr_t
i = 0;
i < environment_length;
i++) {
425 intptr_t block_size = 1;
426 for (intptr_t
i = 0;
i < environment_length;
i++) {
427 block_size += wcslen(system_environment[
i]) + 1;
429 environment_block_ =
reinterpret_cast<wchar_t*
>(
431 intptr_t block_index = 0;
432 for (intptr_t
i = 0;
i < environment_length;
i++) {
433 intptr_t
len = wcslen(system_environment[
i]);
434 intptr_t
result = _snwprintf(environment_block_ + block_index,
len,
435 L"%s", system_environment[
i]);
438 environment_block_[block_index++] =
'\0';
441 environment_block_[block_index++] =
'\0';
442 ASSERT(block_index == block_size);
445 system_working_directory_ =
nullptr;
446 if (working_directory_ !=
nullptr) {
447 system_working_directory_ =
451 attribute_list_ =
nullptr;
455 if (attribute_list_ !=
nullptr) {
456 DeleteProcThreadAttributeList(attribute_list_);
462 int err = CreatePipes();
468 STARTUPINFOEXW startup_info;
469 ZeroMemory(&startup_info,
sizeof(startup_info));
470 startup_info.StartupInfo.cb =
sizeof(startup_info);
472 startup_info.StartupInfo.hStdInput = stdin_handles_[kReadHandle];
473 startup_info.StartupInfo.hStdOutput = stdout_handles_[kWriteHandle];
474 startup_info.StartupInfo.hStdError = stderr_handles_[kWriteHandle];
475 startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
482 if (!InitializeProcThreadAttributeList(
nullptr, 1, 0, &
size) &&
484 return CleanupAndReturnError();
486 attribute_list_ =
reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST
>(
488 ZeroMemory(attribute_list_,
size);
489 if (!InitializeProcThreadAttributeList(attribute_list_, 1, 0, &
size)) {
490 return CleanupAndReturnError();
492 inherited_handles_ = {stdin_handles_[kReadHandle],
493 stdout_handles_[kWriteHandle],
494 stderr_handles_[kWriteHandle]};
495 if (!UpdateProcThreadAttribute(
496 attribute_list_, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
497 inherited_handles_.data(),
498 inherited_handles_.size() *
sizeof(
HANDLE),
nullptr,
nullptr)) {
499 return CleanupAndReturnError();
501 startup_info.lpAttributeList = attribute_list_;
504 PROCESS_INFORMATION process_info;
505 ZeroMemory(&process_info,
sizeof(process_info));
508 DWORD creation_flags =
509 EXTENDED_STARTUPINFO_PRESENT | CREATE_UNICODE_ENVIRONMENT;
511 creation_flags |= DETACHED_PROCESS;
522 creation_flags |= CREATE_NO_WINDOW;
531 creation_flags, environment_block_, system_working_directory_,
532 reinterpret_cast<STARTUPINFOW*
>(&startup_info), &process_info);
535 return CleanupAndReturnError();
539 CloseHandle(stdin_handles_[kReadHandle]);
540 CloseHandle(stdout_handles_[kWriteHandle]);
541 CloseHandle(stderr_handles_[kWriteHandle]);
544 ProcessInfoList::AddProcess(process_info.dwProcessId,
545 process_info.hProcess,
546 exit_handles_[kWriteHandle]);
551 FileHandle* stdin_handle =
new FileHandle(stdin_handles_[kWriteHandle]);
552 FileHandle* stdout_handle =
553 new FileHandle(stdout_handles_[kReadHandle]);
554 FileHandle* stderr_handle =
555 new FileHandle(stderr_handles_[kReadHandle]);
556 *in_ =
reinterpret_cast<intptr_t
>(stdout_handle);
557 *out_ =
reinterpret_cast<intptr_t
>(stdin_handle);
558 *err_ =
reinterpret_cast<intptr_t
>(stderr_handle);
561 FileHandle* exit_handle =
new FileHandle(exit_handles_[kReadHandle]);
562 *exit_handler_ =
reinterpret_cast<intptr_t
>(exit_handle);
566 CloseHandle(process_info.hThread);
569 *id_ = process_info.dwProcessId;
575 wchar_t pipe_names[4][kMaxPipeNameSize];
576 int status = GenerateNames<4>(pipe_names);
578 SetOsErrorMessage(os_error_message_);
587 if (!CreateProcessPipe(stdin_handles_, pipe_names[0], kInheritRead) ||
588 !CreateProcessPipe(stdout_handles_, pipe_names[1], kInheritWrite) ||
589 !CreateProcessPipe(stderr_handles_, pipe_names[2], kInheritWrite)) {
590 return CleanupAndReturnError();
595 if (!CreateProcessPipe(exit_handles_, pipe_names[3], kInheritNone)) {
596 return CleanupAndReturnError();
601 stdin_handles_[kReadHandle] = OpenNul();
603 return CleanupAndReturnError();
606 stdout_handles_[kWriteHandle] = OpenNul();
608 return CleanupAndReturnError();
611 stderr_handles_[kWriteHandle] = OpenNul();
613 return CleanupAndReturnError();
619 int CleanupAndReturnError() {
620 int error_code = SetOsErrorMessage(os_error_message_);
621 CloseProcessPipes(stdin_handles_, stdout_handles_, stderr_handles_,
627 HANDLE stdout_handles_[2];
628 HANDLE stderr_handles_[2];
631 const wchar_t* system_working_directory_;
632 wchar_t* command_line_;
633 wchar_t* environment_block_;
634 std::vector<HANDLE> inherited_handles_;
635 LPPROC_THREAD_ATTRIBUTE_LIST attribute_list_;
638 const char* working_directory_;
644 intptr_t* exit_handler_;
645 char** os_error_message_;
655 intptr_t arguments_length,
656 const char* working_directory,
658 intptr_t environment_length,
664 intptr_t* exit_handler,
665 char** os_error_message) {
666 ProcessStarter starter(
path, arguments, arguments_length, working_directory,
668 id, exit_handler, os_error_message);
669 return starter.Start();
672class BufferList :
public BufferListBase {
674 BufferList() : read_pending_(
true) {}
678 void DataIsRead(intptr_t
size) {
679 ASSERT(read_pending_ ==
true);
680 set_data_size(data_size() +
size);
681 set_free_size(free_size() -
size);
683 read_pending_ =
false;
687 bool GetReadBuffer(uint8_t**
buffer, intptr_t*
size) {
689 if (free_size() == 0) {
696 *
buffer = FreeSpaceAddress();
698 read_pending_ =
true;
702 intptr_t GetDataSize() {
return data_size(); }
704 uint8_t* GetFirstDataBuffer() {
708 return head()->data();
711 void FreeDataBuffer() {
Free(); }
719class OverlappedHandle {
721 OverlappedHandle() {}
733 if (overlapped_.InternalHigh > 0) {
734 buffer_.DataIsRead(overlapped_.InternalHigh);
736 buffer_.DataIsRead(0);
751 buffer_.DataIsRead(overlapped_.InternalHigh);
755 Dart_Handle GetData() {
return buffer_.GetData(); }
757 intptr_t GetDataSize() {
return buffer_.GetDataSize(); }
759 uint8_t* GetFirstDataBuffer() {
return buffer_.GetFirstDataBuffer(); }
761 void FreeDataBuffer() {
return buffer_.FreeDataBuffer(); }
764 bool IsEmpty()
const {
return buffer_.IsEmpty(); }
775 void ClearOverlapped() {
776 memset(&overlapped_, 0,
sizeof(overlapped_));
777 overlapped_.hEvent = event_;
796 reinterpret_cast<FileHandle*
>(in)->
Close();
799 FileHandle* stdout_handle =
reinterpret_cast<FileHandle*
>(
out);
800 ASSERT(stdout_handle->SupportsOverlappedIO());
801 FileHandle* stderr_handle =
reinterpret_cast<FileHandle*
>(err);
802 ASSERT(stderr_handle->SupportsOverlappedIO());
803 FileHandle* exit_handle =
reinterpret_cast<FileHandle*
>(exit_event);
804 ASSERT(exit_handle->SupportsOverlappedIO());
808 const int kHandles = 3;
810 for (
int i = 0;
i < kHandles;
i++) {
815 OverlappedHandle oh[kHandles];
816 oh[0].Init(stdout_handle->handle(), events[0]);
817 oh[1].Init(stderr_handle->handle(), events[1]);
818 oh[2].Init(exit_handle->handle(), events[2]);
821 int alive = kHandles;
824 DWORD wait_result = WaitForMultipleObjects(alive, events,
FALSE, INFINITE);
827 int index = wait_result - WAIT_OBJECT_0;
828 for (
int i = 0;
i < kHandles;
i++) {
829 if (oh[
i].HasEvent(events[index])) {
830 bool ok = oh[
i].Read();
836 events[index] = events[alive];
838 }
else if (err != ERROR_IO_PENDING) {
853 result->set_stdout_data(oh[0].GetData());
854 result->set_stderr_data(oh[1].GetData());
859 ASSERT(oh[2].GetDataSize() == 8);
860 uint32_t exit_codes[2];
861 memmove(&exit_codes, oh[2].GetFirstDataBuffer(),
sizeof(exit_codes));
862 oh[2].FreeDataBuffer();
863 intptr_t exit_code = exit_codes[0];
864 intptr_t negative = exit_codes[1];
866 exit_code = -exit_code;
868 result->set_exit_code(exit_code);
878 bool success = ProcessInfoList::LookupProcess(
id, &process_handle,
879 &wait_handle, &exit_pipe);
883 process_handle = OpenProcess(PROCESS_TERMINATE,
FALSE,
id);
889 BOOL result = TerminateProcess(process_handle, -1);
906#ifdef DART_TARGET_OS_WINDOWS_UWP
909 PROCESS_MEMORY_COUNTERS pmc;
910 if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc,
sizeof(pmc))) {
913 return pmc.WorkingSetSize;
918#ifdef DART_TARGET_OS_WINDOWS_UWP
921 PROCESS_MEMORY_COUNTERS pmc;
922 if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc,
sizeof(pmc))) {
925 return pmc.PeakWorkingSetSize;
929static SignalInfo* signal_handlers =
nullptr;
930static Mutex* signal_mutex =
nullptr;
933 FileHandle* file_handle =
reinterpret_cast<FileHandle*
>(fd_);
934 file_handle->Close();
935 file_handle->Release();
939 MutexLocker lock(signal_mutex);
940 const SignalInfo* handler = signal_handlers;
941 bool handled =
false;
942 while (handler !=
nullptr) {
943 if (handler->signal() == signal) {
948 handler = handler->next();
953intptr_t GetWinSignal(intptr_t signal) {
956 return CTRL_CLOSE_EVENT;
965 signal = GetWinSignal(signal);
972 wchar_t pipe_name[kMaxPipeNameSize];
973 int status = GenerateNames<1>(&pipe_name);
979 if (!CreateProcessPipe(fds, pipe_name, kInheritNone)) {
981 CloseProcessPipe(fds);
985 MutexLocker lock(signal_mutex);
986 FileHandle* write_handle =
new FileHandle(fds[kWriteHandle]);
988 intptr_t write_fd =
reinterpret_cast<intptr_t
>(write_handle);
989 if (signal_handlers ==
nullptr) {
996 write_handle->Release();
997 write_handle->Release();
998 CloseProcessPipe(fds);
1004 new SignalInfo(write_fd, signal,
nullptr, signal_handlers);
1005 return reinterpret_cast<intptr_t
>(
new FileHandle(fds[kReadHandle]));
1009 signal = GetWinSignal(signal);
1013 MutexLocker lock(signal_mutex);
1014 SignalInfo* handler = signal_handlers;
1015 while (handler !=
nullptr) {
1017 if (handler->signal() == signal) {
1019 if (signal_handlers == handler) {
1020 signal_handlers = handler->next();
1023 FileHandle* file_handle =
reinterpret_cast<FileHandle*
>(handler->fd());
1024 file_handle->Release();
1028 SignalInfo*
next = handler->next();
1034 if (signal_handlers ==
nullptr) {
1040 MutexLocker lock(signal_mutex);
1041 SignalInfo* handler = signal_handlers;
1042 while (handler !=
nullptr) {
1044 if (handler->fd() == fd) {
1046 if (signal_handlers == handler) {
1047 signal_handlers = handler->next();
1050 FileHandle* file_handle =
reinterpret_cast<FileHandle*
>(handler->fd());
1051 file_handle->Release();
1055 SignalInfo*
next = handler->next();
1061 if (signal_handlers ==
nullptr) {
1067 active_processes_ =
nullptr;
1068 ASSERT(ProcessInfoList::mutex_ ==
nullptr);
1069 ProcessInfoList::mutex_ =
new Mutex();
1073 ASSERT(ProcessInfoList::mutex_ !=
nullptr);
1074 delete ProcessInfoList::mutex_;
1075 ProcessInfoList::mutex_ =
nullptr;
1081 signal_handlers =
nullptr;
1082 ASSERT(signal_mutex ==
nullptr);
1083 signal_mutex =
new Mutex();
1085 ASSERT(Process::global_exit_code_mutex_ ==
nullptr);
1086 Process::global_exit_code_mutex_ =
new Mutex();
1092 ASSERT(signal_mutex !=
nullptr);
1093 delete signal_mutex;
1094 signal_mutex =
nullptr;
1096 ASSERT(Process::global_exit_code_mutex_ !=
nullptr);
1097 delete Process::global_exit_code_mutex_;
1098 Process::global_exit_code_mutex_ =
nullptr;
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
static float next(float f)
static float prev(float f)
static bool ok(int result)
static const size_t kBufferSize
#define DEBUG_ASSERT(cond)
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static EventHandlerImplementation * delegate()
static bool ModeIsAttached(ProcessStartMode mode)
static void ClearSignalHandler(intptr_t signal, Dart_Port port)
static void ClearSignalHandlerByFd(intptr_t fd, Dart_Port port)
static bool ModeHasStdio(ProcessStartMode mode)
static int64_t CurrentRSS()
static intptr_t CurrentProcessId()
static void TerminateExitCodeHandler()
static bool Wait(intptr_t id, intptr_t in, intptr_t out, intptr_t err, intptr_t exit_handler, ProcessResult *result)
static bool Kill(intptr_t id, int signal)
static intptr_t SetSignalHandler(intptr_t signal)
void(* ExitHook)(int64_t exit_code)
static void ClearAllSignalHandlers()
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)
static intptr_t Write(intptr_t fd, const void *buffer, intptr_t num_bytes, SocketOpKind sync)
static char * WideToUtf8(wchar_t *wide, intptr_t len=-1, intptr_t *result_len=nullptr)
static wchar_t * Utf8ToWide(char *utf8, intptr_t len=-1, intptr_t *result_len=nullptr)
struct _Dart_Handle * Dart_Handle
SK_API bool Read(SkStreamSeekable *src, SkDocumentPage *dstArray, int dstArrayCount, const SkDeserialProcs *=nullptr)
void WriteFile(const void *buffer, intptr_t num_bytes, void *stream)
void ReadFile(uint8_t **data, intptr_t *file_len, void *stream)
void FormatMessageIntoBuffer(DWORD code, wchar_t *buffer, int buffer_length)
static dart::SimpleHashMap * environment
static void * Allocate(uword size, Zone *zone)
DART_EXPORT uint8_t * Dart_ScopeAllocate(intptr_t size)
static void Free(FreeList *free_list, uword address, intptr_t size, bool is_protected)
static int8_t data[kExtLength]
static zx_koid_t GetCurrentProcessId()
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
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
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
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
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
static void SignalHandler(int signal)
void Close(PathBuilder *builder)
SIN Vec< N, float > abs(const Vec< N, float > &x)
bool EMSCRIPTEN_KEEPALIVE IsEmpty(const SkPath &path)
__w64 unsigned int UINT_PTR
#define INVALID_HANDLE_VALUE
WINBASEAPI VOID WINAPI SetLastError(_In_ DWORD dwErrCode)
WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI GetLastError(VOID)
struct _OVERLAPPED OVERLAPPED