Changeset 145741 in webkit


Ignore:
Timestamp:
Mar 13, 2013 1:10:05 PM (11 years ago)
Author:
Christophe Dumez
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):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r145736 r145741  
     12013-03-13  Christophe Dumez  <ch.dumez@sisa.samsung.com>
     2
     3        [EFL] Better error handling in NetworkStateNotifierEfl
     4        https://bugs.webkit.org/show_bug.cgi?id=112184
     5
     6        Reviewed by Kenneth Rohde Christiansen.
     7
     8        Improve error handling in for system calls in NetworkStateNotifierEfl.
     9        - EINTR errors are now properly handled for close() and recv() syscalls
     10        - recv() errors are now correctly detected, for e.g. if the socket was
     11        closed unexpectedly.
     12        - Make sure m_fdHandler is reset when the callback returns
     13        ECORE_CALLBACK_CANCEL to avoid double free in destructor. m_fdHandler
     14        gets destroyed when the callback returns ECORE_CALLBACK_CANCEL.
     15        - Keep netlink socket file descriptor as a class member so that we can
     16        close() it in the class destructor, even if m_fdHandler has already
     17        been destroyed.
     18
     19        No new tests, no behavior change for layout tests.
     20
     21        * platform/network/NetworkStateNotifier.h:
     22        (NetworkStateNotifier):
     23        * platform/network/efl/NetworkStateNotifierEfl.cpp:
     24        (WebCore::NetworkStateNotifier::readSocketCallback):
     25        (WebCore::NetworkStateNotifier::~NetworkStateNotifier):
     26        (WebCore::NetworkStateNotifier::NetworkStateNotifier):
     27
    1282013-03-13  Tony Chang  <tony@chromium.org>
    229
  • trunk/Source/WebCore/platform/network/NetworkStateNotifier.h

    r127258 r145741  
    4949
    5050typedef struct _Ecore_Fd_Handler Ecore_Fd_Handler;
     51typedef unsigned char Eina_Bool;
    5152
    5253#endif
     
    7374#elif PLATFORM(CHROMIUM)
    7475    void setOnLine(bool);
    75 #elif PLATFORM(EFL)
    76     void networkInterfaceChanged();
    7776#endif
    7877
     
    105104
    106105#elif PLATFORM(EFL)
     106    void networkInterfaceChanged();
     107    static Eina_Bool readSocketCallback(void* userData, Ecore_Fd_Handler*);
     108
     109    int m_netlinkSocket;
    107110    Ecore_Fd_Handler* m_fdHandler;
    108111
  • trunk/Source/WebCore/platform/network/efl/NetworkStateNotifierEfl.cpp

    r134537 r145741  
    11/*
    22 * Copyright (C) 2012 Intel Corporation. All rights reserved.
     3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    101102}
    102103
    103 static Eina_Bool readSocketCallback(void* userData, Ecore_Fd_Handler* handler)
     104Eina_Bool NetworkStateNotifier::readSocketCallback(void* userData, Ecore_Fd_Handler* handler)
    104105{
     106    NetworkStateNotifier* notifier = static_cast<NetworkStateNotifier*>(userData);
     107
    105108    int sock = ecore_main_fd_handler_fd_get(handler);
    106109    char buffer[bufferSize];
    107     ssize_t len;
     110
    108111    nlmsghdr* nlh = reinterpret_cast<nlmsghdr*>(buffer);
    109     while ((len = recv(sock, nlh, bufferSize, MSG_DONTWAIT)) > 0) {
    110         while ((NLMSG_OK(nlh, static_cast<unsigned>(len))) && (nlh->nlmsg_type != NLMSG_DONE)) {
     112    while (true) {
     113        ssize_t length = recv(sock, nlh, bufferSize, MSG_DONTWAIT);
     114        if (!length) {
     115            LOG_ERROR("NETLINK socket was closed unexpectedly.");
     116            notifier->m_fdHandler = 0;
     117            return ECORE_CALLBACK_CANCEL;
     118        }
     119        if (length == -1) {
     120            if (errno == EINTR)
     121                continue;
     122            if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
     123                break;
     124            LOG_ERROR("recv on NETLINK socket failed.");
     125            notifier->m_fdHandler = 0;
     126            return ECORE_CALLBACK_CANCEL;
     127        }
     128        while ((NLMSG_OK(nlh, static_cast<unsigned>(length))) && (nlh->nlmsg_type != NLMSG_DONE)) {
    111129            if (nlh->nlmsg_type == NLMSG_ERROR) {
    112                 LOG_ERROR("Error while reading socket, stop monitoring onLine state.");
     130                LOG_ERROR("Unexpected NETLINK error %d.", reinterpret_cast<struct nlmsgerr*>(NLMSG_DATA(nlh))->error);
     131                notifier->m_fdHandler = 0;
    113132                return ECORE_CALLBACK_CANCEL;
    114133            }
    115134            if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR) {
    116135                // We detected an IP address change, recheck onLine state.
    117                 static_cast<NetworkStateNotifier*>(userData)->networkInterfaceChanged();
     136                notifier->networkInterfaceChanged();
    118137            }
    119             nlh = NLMSG_NEXT(nlh, len);
     138            nlh = NLMSG_NEXT(nlh, length);
    120139        }
    121140    }
     
    126145NetworkStateNotifier::~NetworkStateNotifier()
    127146{
    128     if (m_fdHandler) {
    129         int sock = ecore_main_fd_handler_fd_get(m_fdHandler);
     147    if (m_fdHandler)
    130148        ecore_main_fd_handler_del(m_fdHandler);
    131         close(sock);
     149    if (m_netlinkSocket != -1) {
     150        int rv = 0;
     151        do {
     152            rv = close(m_netlinkSocket);
     153        } while (rv == -1 && errno == EINTR);
    132154    }
    133155    eeze_shutdown();
     
    137159    : m_isOnLine(false)
    138160    , m_networkStateChangedFunction(0)
     161    , m_netlinkSocket(-1)
    139162    , m_fdHandler(0)
    140163{
     
    147170
    148171    // Watch for network address changes to keep online state up-to-date.
    149     int sock;
    150     if ((sock = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) {
    151         LOG_ERROR("Couldn't open NETLINK_ROUTE socket.");
     172    m_netlinkSocket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
     173    if (m_netlinkSocket == -1) {
     174        LOG_ERROR("Couldn't create NETLINK socket.");
    152175        return;
    153176    }
     
    158181    addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
    159182
    160     if (bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
    161         LOG_ERROR("Couldn't bind to NETLINK_ROUTE socket.");
     183    if (bind(m_netlinkSocket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
     184        LOG_ERROR("Couldn't bind to NETLINK socket.");
    162185        return;
    163186    }
    164187
    165     m_fdHandler = ecore_main_fd_handler_add(sock, ECORE_FD_READ, readSocketCallback, this, 0, 0);
     188    m_fdHandler = ecore_main_fd_handler_add(m_netlinkSocket, ECORE_FD_READ, readSocketCallback, this, 0, 0);
    166189}
    167190
Note: See TracChangeset for help on using the changeset viewer.