diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc index c280fc8e2df..ce1b89ab34a 100644 --- a/runtime/bin/dart_embedder_api_impl.cc +++ b/runtime/bin/dart_embedder_api_impl.cc @@ -6,7 +6,11 @@ #include "bin/dartutils.h" #include "bin/eventhandler.h" +#if defined(DART_IO_SECURE_SOCKET_DISABLED) +#include "bin/io_service_no_ssl.h" +#else // defined(DART_IO_SECURE_SOCKET_DISABLED) #include "bin/io_service.h" +#endif // defined(DART_IO_SECURE_SOCKET_DISABLED) #include "bin/isolate_data.h" #include "bin/process.h" #include "bin/secure_socket_filter.h" diff --git a/runtime/bin/dart_io_api_impl.cc b/runtime/bin/dart_io_api_impl.cc index 369bf2d4a1c..d6acd6f3829 100644 --- a/runtime/bin/dart_io_api_impl.cc +++ b/runtime/bin/dart_io_api_impl.cc @@ -8,6 +8,11 @@ #include "bin/directory.h" #include "bin/eventhandler.h" #include "bin/io_natives.h" +#if defined(DART_IO_SECURE_SOCKET_DISABLED) +#include "bin/io_service_no_ssl.h" +#else // defined(DART_IO_SECURE_SOCKET_DISABLED) +#include "bin/io_service.h" +#endif // defined(DART_IO_SECURE_SOCKET_DISABLED) #include "bin/platform.h" #include "bin/process.h" #if !defined(DART_IO_SECURE_SOCKET_DISABLED) @@ -36,6 +41,7 @@ void CleanupDartIo() { SSLFilter::Cleanup(); #endif Process::Cleanup(); + IOService::Cleanup(); } void SetSystemTempDirectory(const char* system_temp) { diff --git a/runtime/bin/io_service_no_ssl.cc b/runtime/bin/io_service_no_ssl.cc index 406ad89b6df..d456cdf68f1 100644 --- a/runtime/bin/io_service_no_ssl.cc +++ b/runtime/bin/io_service_no_ssl.cc @@ -53,10 +53,22 @@ void IOServiceCallback(Dart_Port dest_port_id, Dart_CObject* message) { } intptr_t IOService::max_concurrency_ = 32; +std::atomic IOService::port_ = ILLEGAL_PORT; Dart_Port IOService::GetServicePort() { - return Dart_NewConcurrentNativePort("IOService", IOServiceCallback, - max_concurrency_); + Dart_Port port = port_; + if (port == ILLEGAL_PORT) { + port = Dart_NewConcurrentNativePort("IOService", IOServiceCallback, + max_concurrency_); + Dart_Port expected = ILLEGAL_PORT; + if (!port_.compare_exchange_strong(expected, port)) { + // Lost the initialization race. Use the winner's port and close our port. + // The winner's port is eventually implicitly closed by VM shutdown. + Dart_CloseNativePort(port); + return expected; + } + } + return port; } void FUNCTION_NAME(IOService_NewServicePort)(Dart_NativeArguments args) { diff --git a/runtime/bin/io_service_no_ssl.h b/runtime/bin/io_service_no_ssl.h index 9ab2762e6ad..db22cfde17d 100644 --- a/runtime/bin/io_service_no_ssl.h +++ b/runtime/bin/io_service_no_ssl.h @@ -9,6 +9,8 @@ #error "io_service_no_ssl.h can only be included on builds with IO enabled" #endif +#include + #include "bin/builtin.h" #include "bin/utils.h" @@ -70,12 +72,14 @@ class IOService { enum { IO_SERVICE_REQUEST_LIST(DECLARE_REQUEST) }; static Dart_Port GetServicePort(); + static void Cleanup() { port_ = ILLEGAL_PORT; } static intptr_t max_concurrency() { return max_concurrency_; } static void set_max_concurrency(intptr_t value) { max_concurrency_ = value; } private: static intptr_t max_concurrency_; + static std::atomic port_; DISALLOW_ALLOCATION(); DISALLOW_IMPLICIT_CONSTRUCTORS(IOService);