Improve use of NeverDestroyed
[WebKit-https.git] / Source / WebCore / platform / network / NetworkStateNotifier.cpp
index ad15e5c..aa25bb0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "NetworkStateNotifier.h"
 
-#if PLATFORM(IOS)
-#include "Settings.h"
-#endif
-
-#include <mutex>
-#include <wtf/Assertions.h>
 #include <wtf/NeverDestroyed.h>
 
 namespace WebCore {
 
-NetworkStateNotifier& networkStateNotifier()
+static const Seconds updateStateSoonInterval { 2_s };
+
+NetworkStateNotifier& NetworkStateNotifier::singleton()
 {
-    static std::once_flag onceFlag;
-    static LazyNeverDestroyed<NetworkStateNotifier> networkStateNotifier;
+    static NeverDestroyed<NetworkStateNotifier> networkStateNotifier;
+    return networkStateNotifier;
+}
 
-    std::call_once(onceFlag, []{
-        networkStateNotifier.construct();
-    });
+NetworkStateNotifier::NetworkStateNotifier()
+    : m_updateStateTimer([] {
+        singleton().updateState();
+    })
+{
+}
 
-    return networkStateNotifier;
+bool NetworkStateNotifier::onLine()
+{
+    if (!m_isOnLine)
+        updateState();
+    return m_isOnLine.value_or(true);
 }
 
-void NetworkStateNotifier::addNetworkStateChangeListener(WTF::Function<void (bool)>&& listener)
+void NetworkStateNotifier::addListener(WTF::Function<void(bool)>&& listener)
 {
     ASSERT(listener);
-#if PLATFORM(IOS)
-    if (Settings::shouldOptOutOfNetworkStateObservation())
+    if (m_listeners.isEmpty())
+        startObserving();
+    m_listeners.append(WTFMove(listener));
+}
+
+void NetworkStateNotifier::updateState()
+{
+    auto wasOnLine = m_isOnLine;
+    updateStateWithoutNotifying();
+    if (m_isOnLine == wasOnLine)
         return;
-    registerObserverIfNecessary();
-#endif
+    for (auto& listener : m_listeners)
+        listener(m_isOnLine.value());
+}
 
-    m_listeners.append(WTFMove(listener));
+void NetworkStateNotifier::updateStateSoon()
+{
+    m_updateStateTimer.startOneShot(updateStateSoonInterval);
+}
+
+#if !PLATFORM(IOS) && !PLATFORM(MAC) && !PLATFORM(WIN)
+
+// Empty stubs for platforms where monitoring of network state is not yet implemented.
+
+void NetworkStateNotifier::updateStateWithoutNotifying()
+{
 }
 
-void NetworkStateNotifier::notifyNetworkStateChange() const
+void NetworkStateNotifier::startObserving()
 {
-    for (const auto& listener : m_listeners)
-        listener(m_isOnLine);
 }
 
+#endif
+
 } // namespace WebCore