From 9ad6ae26f25bfd7bce69f66d1dc91cd1d37da379 Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 30 Jun 2025 00:27:41 +0300 Subject: [PATCH 1/2] [dotnet] [bidi] Initialize internal modules without Lazy --- dotnet/src/webdriver/BiDi/BiDi.cs | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index 9964b4e59cea8..d90c938740f01 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -27,14 +27,14 @@ public class BiDi : IAsyncDisposable { private readonly Broker _broker; - private readonly Lazy _sessionModule; - private readonly Lazy _browsingContextModule; - private readonly Lazy _browserModule; - private readonly Lazy _networkModule; - private readonly Lazy _inputModule; - private readonly Lazy _scriptModule; - private readonly Lazy _logModule; - private readonly Lazy _storageModule; + private readonly Session.SessionModule _sessionModule; + private readonly BrowsingContext.BrowsingContextModule _browsingContextModule; + private readonly Browser.BrowserModule _browserModule; + private readonly Network.NetworkModule _networkModule; + private readonly Input.InputModule _inputModule; + private readonly Script.ScriptModule _scriptModule; + private readonly Log.LogModule _logModule; + private readonly Storage.StorageModule _storageModule; internal BiDi(string url) { @@ -42,24 +42,24 @@ internal BiDi(string url) _broker = new Broker(this, uri); - _sessionModule = new Lazy(() => new Session.SessionModule(_broker)); - _browsingContextModule = new Lazy(() => new BrowsingContext.BrowsingContextModule(_broker)); - _browserModule = new Lazy(() => new Browser.BrowserModule(_broker)); - _networkModule = new Lazy(() => new Network.NetworkModule(_broker)); - _inputModule = new Lazy(() => new Input.InputModule(_broker)); - _scriptModule = new Lazy(() => new Script.ScriptModule(_broker)); - _logModule = new Lazy(() => new Log.LogModule(_broker)); - _storageModule = new Lazy(() => new Storage.StorageModule(_broker)); + _sessionModule = new Session.SessionModule(_broker); + _browsingContextModule = new BrowsingContext.BrowsingContextModule(_broker); + _browserModule = new Browser.BrowserModule(_broker); + _networkModule = new Network.NetworkModule(_broker); + _inputModule = new Input.InputModule(_broker); + _scriptModule = new Script.ScriptModule(_broker); + _logModule = new Log.LogModule(_broker); + _storageModule = new Storage.StorageModule(_broker); } - internal Session.SessionModule SessionModule => _sessionModule.Value; - public BrowsingContext.BrowsingContextModule BrowsingContext => _browsingContextModule.Value; - public Browser.BrowserModule Browser => _browserModule.Value; - public Network.NetworkModule Network => _networkModule.Value; - internal Input.InputModule InputModule => _inputModule.Value; - public Script.ScriptModule Script => _scriptModule.Value; - public Log.LogModule Log => _logModule.Value; - public Storage.StorageModule Storage => _storageModule.Value; + internal Session.SessionModule SessionModule => _sessionModule; + public BrowsingContext.BrowsingContextModule BrowsingContext => _browsingContextModule; + public Browser.BrowserModule Browser => _browserModule; + public Network.NetworkModule Network => _networkModule; + internal Input.InputModule InputModule => _inputModule; + public Script.ScriptModule Script => _scriptModule; + public Log.LogModule Log => _logModule; + public Storage.StorageModule Storage => _storageModule; public Task StatusAsync() { From 36a3c84da631d2edaa3190907206773d3ffbb9fe Mon Sep 17 00:00:00 2001 From: Nikolay Borisenko <22616990+nvborisenko@users.noreply.github.com> Date: Mon, 30 Jun 2025 00:43:00 +0300 Subject: [PATCH 2/2] Thread safe --- dotnet/src/webdriver/BiDi/BiDi.cs | 176 ++++++++++++++++++++++++++---- 1 file changed, 152 insertions(+), 24 deletions(-) diff --git a/dotnet/src/webdriver/BiDi/BiDi.cs b/dotnet/src/webdriver/BiDi/BiDi.cs index d90c938740f01..3e95a5e5e4144 100644 --- a/dotnet/src/webdriver/BiDi/BiDi.cs +++ b/dotnet/src/webdriver/BiDi/BiDi.cs @@ -27,39 +27,167 @@ public class BiDi : IAsyncDisposable { private readonly Broker _broker; - private readonly Session.SessionModule _sessionModule; - private readonly BrowsingContext.BrowsingContextModule _browsingContextModule; - private readonly Browser.BrowserModule _browserModule; - private readonly Network.NetworkModule _networkModule; - private readonly Input.InputModule _inputModule; - private readonly Script.ScriptModule _scriptModule; - private readonly Log.LogModule _logModule; - private readonly Storage.StorageModule _storageModule; + private Session.SessionModule? _sessionModule; + private BrowsingContext.BrowsingContextModule? _browsingContextModule; + private Browser.BrowserModule? _browserModule; + private Network.NetworkModule? _networkModule; + private Input.InputModule? _inputModule; + private Script.ScriptModule? _scriptModule; + private Log.LogModule? _logModule; + private Storage.StorageModule? _storageModule; + + private readonly object _moduleLock = new(); internal BiDi(string url) { var uri = new Uri(url); _broker = new Broker(this, uri); + } + + internal Session.SessionModule SessionModule + { + get + { + if (_sessionModule is null) + { + lock (_moduleLock) + { + if (_sessionModule is null) + { + _sessionModule = new Session.SessionModule(_broker); + } + } + } + return _sessionModule; + } + } + + public BrowsingContext.BrowsingContextModule BrowsingContext + { + get + { + if (_browsingContextModule is null) + { + lock (_moduleLock) + { + if (_browsingContextModule is null) + { + _browsingContextModule = new BrowsingContext.BrowsingContextModule(_broker); + } + } + } + return _browsingContextModule; + } + } + + public Browser.BrowserModule Browser + { + get + { + if (_browserModule is null) + { + lock (_moduleLock) + { + if (_browserModule is null) + { + _browserModule = new Browser.BrowserModule(_broker); + } + } + } + return _browserModule; + } + } - _sessionModule = new Session.SessionModule(_broker); - _browsingContextModule = new BrowsingContext.BrowsingContextModule(_broker); - _browserModule = new Browser.BrowserModule(_broker); - _networkModule = new Network.NetworkModule(_broker); - _inputModule = new Input.InputModule(_broker); - _scriptModule = new Script.ScriptModule(_broker); - _logModule = new Log.LogModule(_broker); - _storageModule = new Storage.StorageModule(_broker); + public Network.NetworkModule Network + { + get + { + if (_networkModule is null) + { + lock (_moduleLock) + { + if (_networkModule is null) + { + _networkModule = new Network.NetworkModule(_broker); + } + } + } + return _networkModule; + } } - internal Session.SessionModule SessionModule => _sessionModule; - public BrowsingContext.BrowsingContextModule BrowsingContext => _browsingContextModule; - public Browser.BrowserModule Browser => _browserModule; - public Network.NetworkModule Network => _networkModule; - internal Input.InputModule InputModule => _inputModule; - public Script.ScriptModule Script => _scriptModule; - public Log.LogModule Log => _logModule; - public Storage.StorageModule Storage => _storageModule; + internal Input.InputModule InputModule + { + get + { + if (_inputModule is null) + { + lock (_moduleLock) + { + if (_inputModule is null) + { + _inputModule = new Input.InputModule(_broker); + } + } + } + return _inputModule; + } + } + + public Script.ScriptModule Script + { + get + { + if (_scriptModule is null) + { + lock (_moduleLock) + { + if (_scriptModule is null) + { + _scriptModule = new Script.ScriptModule(_broker); + } + } + } + return _scriptModule; + } + } + + public Log.LogModule Log + { + get + { + if (_logModule is null) + { + lock (_moduleLock) + { + if (_logModule is null) + { + _logModule = new Log.LogModule(_broker); + } + } + } + return _logModule; + } + } + + public Storage.StorageModule Storage + { + get + { + if (_storageModule is null) + { + lock (_moduleLock) + { + if (_storageModule is null) + { + _storageModule = new Storage.StorageModule(_broker); + } + } + } + return _storageModule; + } + } public Task StatusAsync() {