Title: [145741] trunk/Source/WebCore
Revision
145741
Author
[email protected]
Date
2013-03-13 13:10:05 -0700 (Wed, 13 Mar 2013)

Log Message

[EFL] Better error handling in NetworkStateNotifierEfl
https://bugs.webkit.org/show_bug.cgi?id=112184

Reviewed by Kenneth Rohde Christiansen.

Improve error handling in for system calls in NetworkStateNotifierEfl.
- EINTR errors are now properly handled for close() and recv() syscalls
- recv() errors are now correctly detected, for e.g. if the socket was
closed unexpectedly.
- Make sure m_fdHandler is reset when the callback returns
ECORE_CALLBACK_CANCEL to avoid double free in destructor. m_fdHandler
gets destroyed when the callback returns ECORE_CALLBACK_CANCEL.
- Keep netlink socket file descriptor as a class member so that we can
close() it in the class destructor, even if m_fdHandler has already
been destroyed.

No new tests, no behavior change for layout tests.

* platform/network/NetworkStateNotifier.h:
(NetworkStateNotifier):
* platform/network/efl/NetworkStateNotifierEfl.cpp:
(WebCore::NetworkStateNotifier::readSocketCallback):
(WebCore::NetworkStateNotifier::~NetworkStateNotifier):
(WebCore::NetworkStateNotifier::NetworkStateNotifier):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (145740 => 145741)


--- trunk/Source/WebCore/ChangeLog	2013-03-13 19:58:06 UTC (rev 145740)
+++ trunk/Source/WebCore/ChangeLog	2013-03-13 20:10:05 UTC (rev 145741)
@@ -1,3 +1,30 @@
+2013-03-13  Christophe Dumez  <[email protected]>
+
+        [EFL] Better error handling in NetworkStateNotifierEfl
+        https://bugs.webkit.org/show_bug.cgi?id=112184
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Improve error handling in for system calls in NetworkStateNotifierEfl.
+        - EINTR errors are now properly handled for close() and recv() syscalls
+        - recv() errors are now correctly detected, for e.g. if the socket was
+        closed unexpectedly.
+        - Make sure m_fdHandler is reset when the callback returns
+        ECORE_CALLBACK_CANCEL to avoid double free in destructor. m_fdHandler
+        gets destroyed when the callback returns ECORE_CALLBACK_CANCEL.
+        - Keep netlink socket file descriptor as a class member so that we can
+        close() it in the class destructor, even if m_fdHandler has already
+        been destroyed.
+
+        No new tests, no behavior change for layout tests.
+
+        * platform/network/NetworkStateNotifier.h:
+        (NetworkStateNotifier):
+        * platform/network/efl/NetworkStateNotifierEfl.cpp:
+        (WebCore::NetworkStateNotifier::readSocketCallback):
+        (WebCore::NetworkStateNotifier::~NetworkStateNotifier):
+        (WebCore::NetworkStateNotifier::NetworkStateNotifier):
+
 2013-03-13  Tony Chang  <[email protected]>
 
         Regression(r143542): -webkit-align-items: center with overflow: auto/scroll has extra bottom padding

Modified: trunk/Source/WebCore/platform/network/NetworkStateNotifier.h (145740 => 145741)


--- trunk/Source/WebCore/platform/network/NetworkStateNotifier.h	2013-03-13 19:58:06 UTC (rev 145740)
+++ trunk/Source/WebCore/platform/network/NetworkStateNotifier.h	2013-03-13 20:10:05 UTC (rev 145741)
@@ -48,6 +48,7 @@
 #elif PLATFORM(EFL)
 
 typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler;
+typedef unsigned char Eina_Bool;
 
 #endif
 
@@ -72,8 +73,6 @@
     void setNetworkAccessAllowed(bool);
 #elif PLATFORM(CHROMIUM)
     void setOnLine(bool);
-#elif PLATFORM(EFL)
-    void networkInterfaceChanged();
 #endif
 
 #if PLATFORM(BLACKBERRY)
@@ -104,6 +103,10 @@
     OVERLAPPED m_overlapped;
 
 #elif PLATFORM(EFL)
+    void networkInterfaceChanged();
+    static Eina_Bool readSocketCallback(void* userData, Ecore_Fd_Handler*);
+
+    int m_netlinkSocket;
     Ecore_Fd_Handler* m_fdHandler;
 
 #elif (PLATFORM(QT) && !defined(QT_NO_BEARERMANAGEMENT))

Modified: trunk/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp (145740 => 145741)


--- trunk/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp	2013-03-13 19:58:06 UTC (rev 145740)
+++ trunk/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp	2013-03-13 20:10:05 UTC (rev 145741)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ * Copyright (C) 2013 Samsung Electronics. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -100,23 +101,41 @@
         m_networkStateChangedFunction();
 }
 
-static Eina_Bool readSocketCallback(void* userData, Ecore_Fd_Handler* handler)
+Eina_Bool NetworkStateNotifier::readSocketCallback(void* userData, Ecore_Fd_Handler* handler)
 {
+    NetworkStateNotifier* notifier = static_cast<NetworkStateNotifier*>(userData);
+
     int sock = ecore_main_fd_handler_fd_get(handler);
     char buffer[bufferSize];
-    ssize_t len;
+
     nlmsghdr* nlh = reinterpret_cast<nlmsghdr*>(buffer);
-    while ((len = recv(sock, nlh, bufferSize, MSG_DONTWAIT)) > 0) {
-        while ((NLMSG_OK(nlh, static_cast<unsigned>(len))) && (nlh->nlmsg_type != NLMSG_DONE)) {
+    while (true) {
+        ssize_t length = recv(sock, nlh, bufferSize, MSG_DONTWAIT);
+        if (!length) {
+            LOG_ERROR("NETLINK socket was closed unexpectedly.");
+            notifier->m_fdHandler = 0;
+            return ECORE_CALLBACK_CANCEL;
+        }
+        if (length == -1) {
+            if (errno == EINTR)
+                continue;
+            if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+                break;
+            LOG_ERROR("recv on NETLINK socket failed.");
+            notifier->m_fdHandler = 0;
+            return ECORE_CALLBACK_CANCEL;
+        }
+        while ((NLMSG_OK(nlh, static_cast<unsigned>(length))) && (nlh->nlmsg_type != NLMSG_DONE)) {
             if (nlh->nlmsg_type == NLMSG_ERROR) {
-                LOG_ERROR("Error while reading socket, stop monitoring onLine state.");
+                LOG_ERROR("Unexpected NETLINK error %d.", reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(nlh))->error);
+                notifier->m_fdHandler = 0;
                 return ECORE_CALLBACK_CANCEL;
             }
             if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR) {
                 // We detected an IP address change, recheck onLine state.
-                static_cast<NetworkStateNotifier*>(userData)->networkInterfaceChanged();
+                notifier->networkInterfaceChanged();
             }
-            nlh = NLMSG_NEXT(nlh, len);
+            nlh = NLMSG_NEXT(nlh, length);
         }
     }
 
@@ -125,10 +144,13 @@
 
 NetworkStateNotifier::~NetworkStateNotifier()
 {
-    if (m_fdHandler) {
-        int sock = ecore_main_fd_handler_fd_get(m_fdHandler);
+    if (m_fdHandler)
         ecore_main_fd_handler_del(m_fdHandler);
-        close(sock);
+    if (m_netlinkSocket != -1) {
+        int rv = 0;
+        do {
+            rv = close(m_netlinkSocket);
+        } while (rv == -1 && errno == EINTR);
     }
     eeze_shutdown();
 }
@@ -136,6 +158,7 @@
 NetworkStateNotifier::NetworkStateNotifier()
     : m_isOnLine(false)
     , m_networkStateChangedFunction(0)
+    , m_netlinkSocket(-1)
     , m_fdHandler(0)
 {
     if (eeze_init() < 0) {
@@ -146,9 +169,9 @@
     updateState();
 
     // Watch for network address changes to keep online state up-to-date.
-    int sock;
-    if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
-        LOG_ERROR("Couldn't open NETLINK_ROUTE socket.");
+    m_netlinkSocket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+    if (m_netlinkSocket == -1) {
+        LOG_ERROR("Couldn't create NETLINK socket.");
         return;
     }
 
@@ -157,12 +180,12 @@
     addr.nl_family = AF_NETLINK;
     addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
 
-    if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
-        LOG_ERROR("Couldn't bind to NETLINK_ROUTE socket.");
+    if (bind(m_netlinkSocket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
+        LOG_ERROR("Couldn't bind to NETLINK socket.");
         return;
     }
 
-    m_fdHandler = ecore_main_fd_handler_add(sock, ECORE_FD_READ, readSocketCallback, this, 0, 0);
+    m_fdHandler = ecore_main_fd_handler_add(m_netlinkSocket, ECORE_FD_READ, readSocketCallback, this, 0, 0);
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to