Commit 59d2320a authored by Matt Falkenhagen's avatar Matt Falkenhagen Committed by Commit Bot

Reland "Use typesafe helpers to pass WebEmbeddedWorker Mojo pipes across Blink public API"

This reverts commit 19d1314e.

Reason for revert: The speculative revert did not result in
improvement.

Original change's description:
> Revert "Use typesafe helpers to pass WebEmbeddedWorker Mojo pipes across Blink public API"
> 
> This reverts commit da054331.
> The code review was https://chromium-review.googlesource.com/c/chromium/src/+/2227103
> 
> Super speculative revert since we have no other clues about the perf
> regression which started in a range the CL landed in.
> 
> Bug: 1096423, 1059157
> Tbr: dcheng
> Change-Id: Ia291b0c16c0cacfcdd40387a6b8badd135fcf7b6
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2355630
> Commit-Queue: Matt Falkenhagen <falken@chromium.org>
> Reviewed-by: Makoto Shimazu <shimazu@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#798067}

TBR=falken@chromium.org,dcheng@chromium.org,shimazu@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 1096423
Bug: 1059157
Change-Id: Ibaa28a209cc2ac79d6e60b78c5b1d0860d65f4c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2366172Reviewed-by: default avatarMatt Falkenhagen <falken@chromium.org>
Reviewed-by: default avatarKenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799963}
parent d4899790
...@@ -108,8 +108,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker( ...@@ -108,8 +108,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
installed_scripts_manager_params = installed_scripts_manager_params =
std::make_unique<blink::WebServiceWorkerInstalledScriptsManagerParams>( std::make_unique<blink::WebServiceWorkerInstalledScriptsManagerParams>(
std::move(params->installed_scripts_info->installed_urls), std::move(params->installed_scripts_info->installed_urls),
params->installed_scripts_info->manager_receiver.PassPipe(), std::move(params->installed_scripts_info->manager_receiver),
params->installed_scripts_info->manager_host_remote.PassPipe()); std::move(params->installed_scripts_info->manager_host_remote));
} }
auto worker = auto worker =
...@@ -117,8 +117,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker( ...@@ -117,8 +117,8 @@ void EmbeddedWorkerInstanceClientImpl::StartWorker(
service_worker_context_client_->StartWorkerContextOnInitiatorThread( service_worker_context_client_->StartWorkerContextOnInitiatorThread(
std::move(worker), std::move(start_data), std::move(worker), std::move(start_data),
std::move(installed_scripts_manager_params), std::move(installed_scripts_manager_params),
params->content_settings_proxy.PassPipe(), cache_storage.PassPipe(), std::move(params->content_settings_proxy), std::move(cache_storage),
browser_interface_broker.PassPipe()); std::move(browser_interface_broker));
} }
void EmbeddedWorkerInstanceClientImpl::StopWorker() { void EmbeddedWorkerInstanceClientImpl::StopWorker() {
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "third_party/blink/public/common/service_worker/service_worker_utils.h" #include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/mojom/blob/blob.mojom.h" #include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/blink/public/mojom/blob/blob_registry.mojom.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom.h"
#include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
#include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom.h" #include "third_party/blink/public/mojom/loader/request_context_frame_type.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h" #include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
...@@ -178,14 +179,16 @@ void ServiceWorkerContextClient::StartWorkerContextOnInitiatorThread( ...@@ -178,14 +179,16 @@ void ServiceWorkerContextClient::StartWorkerContextOnInitiatorThread(
std::unique_ptr<blink::WebEmbeddedWorkerStartData> start_data, std::unique_ptr<blink::WebEmbeddedWorkerStartData> start_data,
std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams> std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams>
installed_scripts_manager_params, installed_scripts_manager_params,
mojo::ScopedMessagePipeHandle content_settings_handle, mojo::PendingRemote<blink::mojom::WorkerContentSettingsProxy>
mojo::ScopedMessagePipeHandle cache_storage, content_settings,
mojo::ScopedMessagePipeHandle browser_interface_broker) { mojo::PendingRemote<blink::mojom::CacheStorage> cache_storage,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker) {
DCHECK(initiator_thread_task_runner_->RunsTasksInCurrentSequence()); DCHECK(initiator_thread_task_runner_->RunsTasksInCurrentSequence());
worker_ = std::move(worker); worker_ = std::move(worker);
worker_->StartWorkerContext( worker_->StartWorkerContext(
std::move(start_data), std::move(installed_scripts_manager_params), std::move(start_data), std::move(installed_scripts_manager_params),
std::move(content_settings_handle), std::move(cache_storage), std::move(content_settings), std::move(cache_storage),
std::move(browser_interface_broker), initiator_thread_task_runner_); std::move(browser_interface_broker), initiator_thread_task_runner_);
} }
......
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom-forward.h" #include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom-forward.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-forward.h" #include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom-forward.h" #include "third_party/blink/public/mojom/worker/subresource_loader_updater.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom-forward.h"
#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h" #include "third_party/blink/public/platform/modules/service_worker/web_service_worker_error.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h" #include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_proxy.h"
...@@ -120,9 +122,11 @@ class CONTENT_EXPORT ServiceWorkerContextClient ...@@ -120,9 +122,11 @@ class CONTENT_EXPORT ServiceWorkerContextClient
std::unique_ptr<blink::WebEmbeddedWorker> worker, std::unique_ptr<blink::WebEmbeddedWorker> worker,
std::unique_ptr<blink::WebEmbeddedWorkerStartData> start_data, std::unique_ptr<blink::WebEmbeddedWorkerStartData> start_data,
std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams>, std::unique_ptr<blink::WebServiceWorkerInstalledScriptsManagerParams>,
mojo::ScopedMessagePipeHandle content_settings_handle, mojo::PendingRemote<blink::mojom::WorkerContentSettingsProxy>
mojo::ScopedMessagePipeHandle cache_storage, content_settings,
mojo::ScopedMessagePipeHandle browser_interface_broker); mojo::PendingRemote<blink::mojom::CacheStorage> cache_storage,
mojo::PendingRemote<blink::mojom::BrowserInterfaceBroker>
browser_interface_broker);
// Called on the initiator thread. // Called on the initiator thread.
blink::WebEmbeddedWorker& worker(); blink::WebEmbeddedWorker& worker();
......
...@@ -33,7 +33,11 @@ ...@@ -33,7 +33,11 @@
#include <memory> #include <memory>
#include "mojo/public/cpp/system/message_pipe.h" #include "third_party/blink/public/mojom/browser_interface_broker.mojom-shared.h"
#include "third_party/blink/public/mojom/cache_storage/cache_storage.mojom-shared.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-shared.h"
#include "third_party/blink/public/mojom/worker/worker_content_settings_proxy.mojom-shared.h"
#include "third_party/blink/public/platform/cross_variant_mojo_util.h"
#include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/public/platform/web_vector.h"
...@@ -43,23 +47,25 @@ class WebServiceWorkerContextClient; ...@@ -43,23 +47,25 @@ class WebServiceWorkerContextClient;
class WebURL; class WebURL;
struct WebEmbeddedWorkerStartData; struct WebEmbeddedWorkerStartData;
// TODO(crbug.com/1096423): Use CrossVariantMojoRemote if the perf regression is
// not caused by it.
struct BLINK_EXPORT WebServiceWorkerInstalledScriptsManagerParams { struct BLINK_EXPORT WebServiceWorkerInstalledScriptsManagerParams {
WebServiceWorkerInstalledScriptsManagerParams() = delete; WebServiceWorkerInstalledScriptsManagerParams() = delete;
WebServiceWorkerInstalledScriptsManagerParams( WebServiceWorkerInstalledScriptsManagerParams(
WebVector<WebURL> installed_scripts_urls, WebVector<WebURL> installed_scripts_urls,
mojo::ScopedMessagePipeHandle manager_receiver, CrossVariantMojoReceiver<
mojo::ScopedMessagePipeHandle manager_host_remote); mojom::ServiceWorkerInstalledScriptsManagerInterfaceBase>
manager_receiver,
CrossVariantMojoRemote<
mojom::ServiceWorkerInstalledScriptsManagerHostInterfaceBase>
manager_host_remote);
~WebServiceWorkerInstalledScriptsManagerParams() = default; ~WebServiceWorkerInstalledScriptsManagerParams() = default;
WebVector<WebURL> installed_scripts_urls; WebVector<WebURL> installed_scripts_urls;
// A handle for CrossVariantMojoReceiver<
// mojo::PendingReceiver<mojom::blink::ServiceWorkerInstalledScriptsManager>. mojom::ServiceWorkerInstalledScriptsManagerInterfaceBase>
mojo::ScopedMessagePipeHandle manager_receiver; manager_receiver;
// A handle for CrossVariantMojoRemote<
// mojo::PendingRemote<mojom::blink::ServiceWorkerInstalledScriptsManagerHost>. mojom::ServiceWorkerInstalledScriptsManagerHostInterfaceBase>
mojo::ScopedMessagePipeHandle manager_host_remote; manager_host_remote;
}; };
// An interface to start and terminate an embedded worker. // An interface to start and terminate an embedded worker.
...@@ -78,9 +84,11 @@ class BLINK_EXPORT WebEmbeddedWorker { ...@@ -78,9 +84,11 @@ class BLINK_EXPORT WebEmbeddedWorker {
virtual void StartWorkerContext( virtual void StartWorkerContext(
std::unique_ptr<WebEmbeddedWorkerStartData>, std::unique_ptr<WebEmbeddedWorkerStartData>,
std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>,
mojo::ScopedMessagePipeHandle content_settings_handle, CrossVariantMojoRemote<mojom::WorkerContentSettingsProxyInterfaceBase>
mojo::ScopedMessagePipeHandle cache_storage, content_settings,
mojo::ScopedMessagePipeHandle browser_interface_broker, CrossVariantMojoRemote<mojom::CacheStorageInterfaceBase> cache_storage,
CrossVariantMojoRemote<mojom::BrowserInterfaceBrokerInterfaceBase>
browser_interface_broker,
scoped_refptr<base::SingleThreadTaskRunner> scoped_refptr<base::SingleThreadTaskRunner>
initiator_thread_task_runner) = 0; initiator_thread_task_runner) = 0;
virtual void TerminateWorkerContext() = 0; virtual void TerminateWorkerContext() = 0;
......
...@@ -76,8 +76,12 @@ namespace blink { ...@@ -76,8 +76,12 @@ namespace blink {
WebServiceWorkerInstalledScriptsManagerParams:: WebServiceWorkerInstalledScriptsManagerParams::
WebServiceWorkerInstalledScriptsManagerParams( WebServiceWorkerInstalledScriptsManagerParams(
WebVector<WebURL> installed_scripts_urls, WebVector<WebURL> installed_scripts_urls,
mojo::ScopedMessagePipeHandle manager_receiver, CrossVariantMojoReceiver<
mojo::ScopedMessagePipeHandle manager_host_remote) mojom::blink::ServiceWorkerInstalledScriptsManagerInterfaceBase>
manager_receiver,
CrossVariantMojoRemote<
mojom::blink::ServiceWorkerInstalledScriptsManagerHostInterfaceBase>
manager_host_remote)
: installed_scripts_urls(std::move(installed_scripts_urls)), : installed_scripts_urls(std::move(installed_scripts_urls)),
manager_receiver(std::move(manager_receiver)), manager_receiver(std::move(manager_receiver)),
manager_host_remote(std::move(manager_host_remote)) { manager_host_remote(std::move(manager_host_remote)) {
...@@ -105,9 +109,12 @@ void WebEmbeddedWorkerImpl::StartWorkerContext( ...@@ -105,9 +109,12 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data, std::unique_ptr<WebEmbeddedWorkerStartData> worker_start_data,
std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams> std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>
installed_scripts_manager_params, installed_scripts_manager_params,
mojo::ScopedMessagePipeHandle content_settings_handle, CrossVariantMojoRemote<
mojo::ScopedMessagePipeHandle cache_storage, mojom::blink::WorkerContentSettingsProxyInterfaceBase> content_settings,
mojo::ScopedMessagePipeHandle browser_interface_broker, CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase>
cache_storage,
CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
browser_interface_broker,
scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) { scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) {
DCHECK(!asked_to_terminate_); DCHECK(!asked_to_terminate_);
...@@ -138,15 +145,8 @@ void WebEmbeddedWorkerImpl::StartWorkerContext( ...@@ -138,15 +145,8 @@ void WebEmbeddedWorkerImpl::StartWorkerContext(
StartWorkerThread( StartWorkerThread(
std::move(worker_start_data), std::move(installed_scripts_manager), std::move(worker_start_data), std::move(installed_scripts_manager),
std::make_unique<ServiceWorkerContentSettingsProxy>( std::make_unique<ServiceWorkerContentSettingsProxy>(
// Chrome doesn't use interface versioning. std::move(content_settings)),
// TODO(falken): Is that comment about versioning correct? std::move(cache_storage), std::move(browser_interface_broker),
mojo::PendingRemote<mojom::blink::WorkerContentSettingsProxy>(
std::move(content_settings_handle), 0u)),
mojo::PendingRemote<mojom::blink::CacheStorage>(
std::move(cache_storage), mojom::blink::CacheStorage::Version_),
mojo::PendingRemote<mojom::blink::BrowserInterfaceBroker>(
std::move(browser_interface_broker),
mojom::blink::BrowserInterfaceBroker::Version_),
std::move(initiator_thread_task_runner)); std::move(initiator_thread_task_runner));
} }
......
...@@ -66,9 +66,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker { ...@@ -66,9 +66,13 @@ class MODULES_EXPORT WebEmbeddedWorkerImpl final : public WebEmbeddedWorker {
void StartWorkerContext( void StartWorkerContext(
std::unique_ptr<WebEmbeddedWorkerStartData>, std::unique_ptr<WebEmbeddedWorkerStartData>,
std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>, std::unique_ptr<WebServiceWorkerInstalledScriptsManagerParams>,
mojo::ScopedMessagePipeHandle content_settings_handle, CrossVariantMojoRemote<
mojo::ScopedMessagePipeHandle cache_storage, mojom::blink::WorkerContentSettingsProxyInterfaceBase>
mojo::ScopedMessagePipeHandle browser_interface_broker, content_settings,
CrossVariantMojoRemote<mojom::blink::CacheStorageInterfaceBase>
cache_storage,
CrossVariantMojoRemote<mojom::blink::BrowserInterfaceBrokerInterfaceBase>
browser_interface_broker,
scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner) scoped_refptr<base::SingleThreadTaskRunner> initiator_thread_task_runner)
override; override;
void TerminateWorkerContext() override; void TerminateWorkerContext() override;
......
...@@ -262,10 +262,7 @@ ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager( ...@@ -262,10 +262,7 @@ ServiceWorkerInstalledScriptsManager::ServiceWorkerInstalledScriptsManager(
DCHECK(installed_scripts_manager_params->manager_host_remote); DCHECK(installed_scripts_manager_params->manager_host_remote);
manager_host_ = mojo::SharedRemote< manager_host_ = mojo::SharedRemote<
mojom::blink::ServiceWorkerInstalledScriptsManagerHost>( mojom::blink::ServiceWorkerInstalledScriptsManagerHost>(
mojo::PendingRemote< std::move(installed_scripts_manager_params->manager_host_remote));
mojom::blink::ServiceWorkerInstalledScriptsManagerHost>(
std::move(installed_scripts_manager_params->manager_host_remote),
mojom::blink::ServiceWorkerInstalledScriptsManagerHost::Version_));
// Don't touch |installed_urls_| after this point. We're on the initiator // Don't touch |installed_urls_| after this point. We're on the initiator
// thread now, but |installed_urls_| will be accessed on the // thread now, but |installed_urls_| will be accessed on the
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h" #include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
#include <utility>
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/synchronization/waitable_event.h" #include "base/synchronization/waitable_event.h"
#include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/receiver.h"
...@@ -144,8 +146,8 @@ class ServiceWorkerInstalledScriptsManagerTest : public testing::Test { ...@@ -144,8 +146,8 @@ class ServiceWorkerInstalledScriptsManagerTest : public testing::Test {
auto installed_scripts_manager_params = auto installed_scripts_manager_params =
std::make_unique<WebServiceWorkerInstalledScriptsManagerParams>( std::make_unique<WebServiceWorkerInstalledScriptsManagerParams>(
std::move(installed_scripts_info->installed_urls), std::move(installed_scripts_info->installed_urls),
installed_scripts_info->manager_receiver.PassPipe(), std::move(installed_scripts_info->manager_receiver),
installed_scripts_info->manager_host_remote.PassPipe()); std::move(installed_scripts_info->manager_host_remote));
installed_scripts_manager_ = installed_scripts_manager_ =
std::make_unique<ServiceWorkerInstalledScriptsManager>( std::make_unique<ServiceWorkerInstalledScriptsManager>(
std::move(installed_scripts_manager_params), std::move(installed_scripts_manager_params),
......
...@@ -299,9 +299,9 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) { ...@@ -299,9 +299,9 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) {
worker_->StartWorkerContext( worker_->StartWorkerContext(
CreateStartData(), CreateStartData(),
/*installed_scripts_manager_params=*/nullptr, /*installed_scripts_manager_params=*/nullptr,
/*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), /*content_settings_proxy=*/mojo::NullRemote(),
/*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), /*cache_storage_remote=*/mojo::NullRemote(),
browser_interface_broker.BindNewPipeAndPassRemote().PassPipe(), browser_interface_broker.BindNewPipeAndPassRemote(),
Thread::Current()->GetTaskRunner()); Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get()); testing::Mock::VerifyAndClearExpectations(mock_client_.get());
...@@ -318,9 +318,9 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) { ...@@ -318,9 +318,9 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) {
worker_->StartWorkerContext( worker_->StartWorkerContext(
std::move(start_data), std::move(start_data),
/*installed_scripts_manager_params=*/nullptr, /*installed_scripts_manager_params=*/nullptr,
/*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), /*content_settings_proxy=*/mojo::NullRemote(),
/*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), /*cache_storage_remote=*/mojo::NullRemote(),
browser_interface_broker.BindNewPipeAndPassRemote().PassPipe(), browser_interface_broker.BindNewPipeAndPassRemote(),
Thread::Current()->GetTaskRunner()); Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get()); testing::Mock::VerifyAndClearExpectations(mock_client_.get());
...@@ -340,9 +340,9 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) { ...@@ -340,9 +340,9 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
worker_->StartWorkerContext( worker_->StartWorkerContext(
std::move(start_data), std::move(start_data),
/*installed_scripts_manager_params=*/nullptr, /*installed_scripts_manager_params=*/nullptr,
/*content_settings_proxy=*/mojo::ScopedMessagePipeHandle(), /*content_settings_proxy=*/mojo::NullRemote(),
/*cache_storage_remote=*/mojo::ScopedMessagePipeHandle(), /*cache_storage_remote=*/mojo::NullRemote(),
browser_interface_broker.BindNewPipeAndPassRemote().PassPipe(), browser_interface_broker.BindNewPipeAndPassRemote(),
Thread::Current()->GetTaskRunner()); Thread::Current()->GetTaskRunner());
testing::Mock::VerifyAndClearExpectations(mock_client_.get()); testing::Mock::VerifyAndClearExpectations(mock_client_.get());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment