Changeset 117094 in webkit


Ignore:
Timestamp:
May 15, 2012 11:00:13 AM (12 years ago)
Author:
caio.oliveira@openbossa.org
Message:

[Qt] WebKit with Qt5 hangs on Mac
https://bugs.webkit.org/show_bug.cgi?id=79785

Reviewed by Tor Arne Vestbø.

Delay the initialization of our QNetworkConfigurationManager used in
NetworkStateNotifierPrivate. On Mac it was causing a race condition because it
spawns a thread that triggers a static initializer in Qt, while in the main
thread NetworkStateNotifier is being static initialized. On Mac the lock for
static initializers is shared between all of them, causing a deadlock.

The issue was also reported in http://openradar.appspot.com/11217150.

  • platform/network/qt/NetworkStateNotifierPrivate.h:

(NetworkStateNotifierPrivate):
(WebCore::NetworkStateNotifierPrivate::effectivelyOnline):

  • platform/network/qt/NetworkStateNotifierQt.cpp:

(WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate):
(WebCore::NetworkStateNotifierPrivate::setNetworkAccessAllowed):
(WebCore::NetworkStateNotifierPrivate::setOnlineState):
(WebCore::NetworkStateNotifierPrivate::initialize):
(WebCore):
(WebCore::NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate):
(WebCore::NetworkStateNotifier::updateState):
(WebCore::NetworkStateNotifier::NetworkStateNotifier):
(WebCore::NetworkStateNotifier::setNetworkAccessAllowed):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r117091 r117094  
     12012-05-15  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
     2
     3        [Qt] WebKit with Qt5 hangs on Mac
     4        https://bugs.webkit.org/show_bug.cgi?id=79785
     5
     6        Reviewed by Tor Arne Vestbø.
     7
     8        Delay the initialization of our QNetworkConfigurationManager used in
     9        NetworkStateNotifierPrivate. On Mac it was causing a race condition because it
     10        spawns a thread that triggers a static initializer in Qt, while in the main
     11        thread NetworkStateNotifier is being static initialized. On Mac the lock for
     12        static initializers is shared between all of them, causing a deadlock.
     13
     14        The issue was also reported in http://openradar.appspot.com/11217150.
     15
     16        * platform/network/qt/NetworkStateNotifierPrivate.h:
     17        (NetworkStateNotifierPrivate):
     18        (WebCore::NetworkStateNotifierPrivate::effectivelyOnline):
     19        * platform/network/qt/NetworkStateNotifierQt.cpp:
     20        (WebCore::NetworkStateNotifierPrivate::NetworkStateNotifierPrivate):
     21        (WebCore::NetworkStateNotifierPrivate::setNetworkAccessAllowed):
     22        (WebCore::NetworkStateNotifierPrivate::setOnlineState):
     23        (WebCore::NetworkStateNotifierPrivate::initialize):
     24        (WebCore):
     25        (WebCore::NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate):
     26        (WebCore::NetworkStateNotifier::updateState):
     27        (WebCore::NetworkStateNotifier::NetworkStateNotifier):
     28        (WebCore::NetworkStateNotifier::setNetworkAccessAllowed):
     29
    1302012-05-15  Allan Sandfeld Jensen  <allan.jensen@nokia.com>
    231
  • trunk/Source/WebCore/platform/network/qt/NetworkStateNotifierPrivate.h

    r95901 r117094  
    2222
    2323#include <QObject>
     24#include <wtf/OwnPtr.h>
    2425
    2526QT_BEGIN_NAMESPACE
     
    3637    NetworkStateNotifierPrivate(NetworkStateNotifier* notifier);
    3738    ~NetworkStateNotifierPrivate();
     39
     40    void setNetworkAccessAllowed(bool);
     41    bool effectivelyOnline() const { return m_online && m_networkAccessAllowed; }
     42
    3843public slots:
    39     void onlineStateChanged(bool);
    40     void networkAccessPermissionChanged(bool);
     44    void setOnlineState(bool);
     45
     46private slots:
     47    void initialize();
    4148
    4249public:
    43     QNetworkConfigurationManager* m_configurationManager;
     50    OwnPtr<QNetworkConfigurationManager> m_configurationManager;
    4451    bool m_online;
    4552    bool m_networkAccessAllowed;
  • trunk/Source/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp

    r95901 r117094  
    2424
    2525#include "NetworkStateNotifierPrivate.h"
    26 #include "qnetworkconfigmanager.h"
     26#include <QNetworkConfigurationManager>
     27#include <QTimer>
     28#include <wtf/PassOwnPtr.h>
    2729
    2830namespace WebCore {
    2931
    3032NetworkStateNotifierPrivate::NetworkStateNotifierPrivate(NetworkStateNotifier* notifier)
    31     : m_configurationManager(new QNetworkConfigurationManager())
    32     , m_online(m_configurationManager->isOnline())
     33    : m_online(false)
    3334    , m_networkAccessAllowed(true)
    3435    , m_notifier(notifier)
    3536{
    36     Q_ASSERT(notifier);
    37     connect(m_configurationManager, SIGNAL(onlineStateChanged(bool)), this, SLOT(onlineStateChanged(bool)));
     37    ASSERT(notifier);
     38
     39    // Initialization is delayed because QNetworkConfigurationManager starts a new thread that causes
     40    // deadlock on Mac because all the static initializers share the same lock. Both NetworkStateNotifier and Qt internals
     41    // triggered in new thread use static initializer. See also: http://openradar.appspot.com/11217150.
     42    QTimer::singleShot(0, this, SLOT(initialize()));
    3843}
    3944
    40 void NetworkStateNotifierPrivate::onlineStateChanged(bool isOnline)
     45void NetworkStateNotifierPrivate::setNetworkAccessAllowed(bool isAllowed)
     46{
     47    if (isAllowed == m_networkAccessAllowed)
     48        return;
     49
     50    m_networkAccessAllowed = isAllowed;
     51    if (m_online)
     52        m_notifier->updateState();
     53}
     54
     55void NetworkStateNotifierPrivate::setOnlineState(bool isOnline)
    4156{
    4257    if (m_online == isOnline)
     
    4863}
    4964
    50 void NetworkStateNotifierPrivate::networkAccessPermissionChanged(bool isAllowed)
     65void NetworkStateNotifierPrivate::initialize()
    5166{
    52     if (isAllowed == m_networkAccessAllowed)
    53         return;
    54 
    55     m_networkAccessAllowed = isAllowed;
    56     if (m_online)
    57         m_notifier->updateState();
     67    m_configurationManager = adoptPtr(new QNetworkConfigurationManager());
     68    setOnlineState(m_configurationManager->isOnline());
     69    connect(m_configurationManager.get(), SIGNAL(onlineStateChanged(bool)), this, SLOT(setOnlineState(bool)));
    5870}
    5971
    6072NetworkStateNotifierPrivate::~NetworkStateNotifierPrivate()
    6173{
    62     delete m_configurationManager;
    6374}
    6475
    6576void NetworkStateNotifier::updateState()
    6677{
    67     if (m_isOnLine == (p->m_online && p->m_networkAccessAllowed))
     78    if (m_isOnLine == p->effectivelyOnline())
    6879        return;
    6980
    70     m_isOnLine = p->m_online && p->m_networkAccessAllowed;
     81    m_isOnLine = p->effectivelyOnline();
    7182    if (m_networkStateChangedFunction)
    7283        m_networkStateChangedFunction();
     
    7889{
    7990    p = new NetworkStateNotifierPrivate(this);
    80     m_isOnLine = p->m_online && p->m_networkAccessAllowed;
     91    m_isOnLine = p->effectivelyOnline();
    8192}
    8293
    8394void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed)
    8495{
    85     p->networkAccessPermissionChanged(isAllowed);
     96    p->setNetworkAccessAllowed(isAllowed);
    8697}
    8798
Note: See TracChangeset for help on using the changeset viewer.