Because QSocketNotifier doesn't seem to notify closed connections we
authorRoy Marples <roy@marples.name>
Tue, 2 Dec 2014 22:46:32 +0000 (22:46 +0000)
committerRoy Marples <roy@marples.name>
Tue, 2 Dec 2014 22:46:32 +0000 (22:46 +0000)
need to PING wpa_supplicant to ensure it's alive.
Use deleteLater instead of delete to avoid any threading errors.
Re-work the DhcpcdWi API as we don't try to re-open on error.

src/dhcpcd-qt/dhcpcd-qt.cpp
src/dhcpcd-qt/dhcpcd-qt.h
src/dhcpcd-qt/dhcpcd-wi.cpp
src/dhcpcd-qt/dhcpcd-wi.h

index 2b740264d22c4622ab49823bed80b7b45ab110b8..b84c17c9834816372396d41db97f04aa176744ee 100644 (file)
@@ -81,9 +81,10 @@ DhcpcdQt::DhcpcdQt()
 DhcpcdQt::~DhcpcdQt()
 {
 
-       /* This will have already been destroyed,
-        * but the reference may not be. */
-       ssidMenu = NULL;
+       if (ssidMenu) {
+               ssidMenu->setVisible(false);
+               ssidMenu->deleteLater();
+       }
 
        if (con != NULL) {
                dhcpcd_close(con);
@@ -92,9 +93,9 @@ DhcpcdQt::~DhcpcdQt()
 
        free(lastStatus);
 
-       qDeleteAll(*wis);
+       for (auto &wi : *wis)
+               wi->deleteLater();
        delete wis;
-
 }
 
 DHCPCD_CONNECTION *DhcpcdQt::getConnection()
@@ -201,18 +202,19 @@ void DhcpcdQt::statusCallback(const char *status)
                trayIcon->setToolTip(tr("Not connected to dhcpcd"));
                /* Close down everything */
                if (notifier) {
-                       delete notifier;
+                       notifier->setEnabled(false);
+                       notifier->deleteLater();
                        notifier = NULL;
                }
                if (ssidMenu) {
-                       delete ssidMenu;
+                       ssidMenu->deleteLater();
                        ssidMenu = NULL;
                }
+               preferencesAction->setEnabled(false);
                if (preferences) {
-                       delete preferences;
+                       preferences->deleteLater();
                        preferences = NULL;
                }
-               preferencesAction->setEnabled(false);
        } else {
                bool refresh;
 
@@ -340,7 +342,7 @@ void DhcpcdQt::scanCallback(DHCPCD_WPA *wpa)
                qCritical("No fd for WPA");
                if (wi) {
                        wis->removeOne(wi);
-                       delete wi;
+                       wi->deleteLater();
                }
                return;
        }
@@ -350,7 +352,7 @@ void DhcpcdQt::scanCallback(DHCPCD_WPA *wpa)
                qCritical("No interface for WPA");
                if (wi) {
                        wis->removeOne(wi);
-                       delete wi;
+                       wi->deleteLater();
                }
                return;
        }
@@ -359,8 +361,11 @@ void DhcpcdQt::scanCallback(DHCPCD_WPA *wpa)
        scans = dhcpcd_wi_scans(i);
        if (wi == NULL) {
                wi = new DhcpcdWi(this, wpa);
-               wis->append(wi);
-               wi->setScans(scans);
+               if (wi->open()) {
+                       wis->append(wi);
+                       wi->setScans(scans);
+               } else
+                       wi->deleteLater();
        } else
                processScans(wi, scans);
 
@@ -383,7 +388,7 @@ void DhcpcdQt::wpaStatusCallback(DHCPCD_WPA *wpa, const char *status)
                DhcpcdWi *wi = findWi(wpa);
                if (wi) {
                        wis->removeOne(wi);
-                       delete wi;
+                       wi->deleteLater();
                }
        }
 }
@@ -426,7 +431,8 @@ unprived:
        dhcpcd_wpa_start(con);
 
        if (retryOpenTimer) {
-               delete retryOpenTimer;
+               retryOpenTimer->stop();
+               retryOpenTimer->deleteLater();
                retryOpenTimer = NULL;
        }
 
@@ -436,12 +442,8 @@ unprived:
        preferencesAction->setEnabled(dhcpcd_privileged(con));
 }
 
-void DhcpcdQt::dispatch() {
-
-       if (dhcpcd_get_fd(con) == -1) {
-               qWarning("dhcpcd connection lost");
-               return;
-       }
+void DhcpcdQt::dispatch()
+{
 
        dhcpcd_dispatch(con);
 }
@@ -500,11 +502,18 @@ QIcon DhcpcdQt::icon()
        return getIcon("status", "network-transmit-receive");
 }
 
+void DhcpcdQt::menuDeleted(QMenu *menu)
+{
+
+       if (ssidMenu == menu)
+               ssidMenu = NULL;
+}
+
 void DhcpcdQt::createSsidMenu()
 {
 
        if (ssidMenu) {
-               delete ssidMenu;
+               ssidMenu->deleteLater();
                ssidMenu = NULL;
        }
        if (wis->size() == 0)
index 1a96c36e5e396291da6c6747ae7f0712668061ae..1bd66fc8efb9e3944a465bfa03692d6a9d0ce8bb 100644 (file)
@@ -74,6 +74,7 @@ public:
 
        void closeAbout();
        void dialogClosed(QDialog *dialog);
+       void menuDeleted(QMenu *menu);
 
 protected:
        void closeEvent(QCloseEvent *event);
index 264743babddb9d8c45b9f6e2d53ea6f40502f426..568ce42e7d72737ab962b1e6794ba7cea51b5111 100644 (file)
@@ -50,25 +50,32 @@ DhcpcdWi::DhcpcdWi(DhcpcdQt *parent, DHCPCD_WPA *wpa)
        menu = NULL;
        scans = NULL;
 
-       int fd = dhcpcd_wpa_get_fd(wpa);
-       notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
-       connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
-       retryOpenTimer = NULL;
+       notifier = NULL;
+       pingTimer = NULL;
 }
 
 DhcpcdWi::~DhcpcdWi()
 {
 
        if (menu) {
-               delete menu;
+               dhcpcdQt->menuDeleted(menu);
+               menu->setVisible(false);
+               menu->deleteLater();
                menu = NULL;
        }
 
        if (notifier) {
-               delete notifier;
+               notifier->setEnabled(false);
+               notifier->deleteLater();
                notifier = NULL;
        }
 
+       if (pingTimer) {
+               pingTimer->stop();
+               pingTimer->deleteLater();
+               pingTimer = NULL;
+       }
+       
        dhcpcd_wi_scans_free(scans);
 }
 
@@ -193,55 +200,39 @@ QMenu *DhcpcdWi::createIfMenu(QMenu *parent)
        return menu;
 }
 
-void DhcpcdWi::wpaOpen()
+bool DhcpcdWi::open()
 {
        int fd = dhcpcd_wpa_open(wpa);
-       static int last_error;
 
        if (fd == -1) {
-               if (errno != last_error) {
-                       last_error = errno;
-                       qCritical("%s: dhcpcd_wpa_open: %s",
-                           dhcpcd_wpa_if(wpa)->ifname,
-                           strerror(last_error));
-               }
-               return;
+               qCritical("%s: dhcpcd_wpa_open: %s",
+                   dhcpcd_wpa_if(wpa)->ifname,
+                   strerror(errno));
+               dhcpcd_wpa_close(wpa);
+               return false;
        }
 
        notifier = new QSocketNotifier(fd, QSocketNotifier::Read);
        connect(notifier, SIGNAL(activated(int)), this, SLOT(dispatch()));
-       if (retryOpenTimer) {
-               delete retryOpenTimer;
-               retryOpenTimer = NULL;
-       }
+       pingTimer = new QTimer(this);
+       connect(pingTimer, SIGNAL(timeout()), this, SLOT(ping()));
+       pingTimer->start(DHCPCD_WPA_PING);
+       return true;
 }
 
 void DhcpcdWi::dispatch()
 {
 
-       if (dhcpcd_wpa_get_fd(wpa) == -1) {
-               delete notifier;
-               notifier = NULL;
-               DHCPCD_IF *i = dhcpcd_wpa_if(wpa);
-               if (i == NULL ||
-                   strcmp(i->reason, "DEPARTED") == 0 ||
-                   strcmp(i->reason, "STOPPED") == 0)
-                       return;
-               qWarning("%s: %s",
-                   i->ifname,
-                   qPrintable(tr("dhcpcd WPA connection lost")));
-               if (retryOpenTimer == NULL) {
-                       retryOpenTimer = new QTimer(this);
-                       connect(retryOpenTimer, SIGNAL(timeout()),
-                           this, SLOT(wpaOpen()));
-                       retryOpenTimer->start(DHCPCD_RETRYOPEN);
-               }
-               return;
-       }
-
        dhcpcd_wpa_dispatch(wpa);
 }
 
+void DhcpcdWi::ping()
+{
+
+       if (!dhcpcd_wpa_ping(wpa))
+               dhcpcd_wpa_close(wpa);
+}
+
 void DhcpcdWi::connectSsid(DHCPCD_WI_SCAN *scan)
 {
        DHCPCD_WI_SCAN s;
index 88ce6de3fcd5dcaa633ba629815a05fc12530007..516a9acfd0ff9863cff83eed2334630ec24b5edd 100644 (file)
@@ -48,6 +48,7 @@ public:
        DhcpcdWi(DhcpcdQt *dhcpcdQt, DHCPCD_WPA *wpa);
        ~DhcpcdWi();
        DHCPCD_WPA *getWpa();
+       bool open();
 
        DHCPCD_WI_SCAN *getScans();
        bool setScans(DHCPCD_WI_SCAN *scans);
@@ -57,7 +58,7 @@ public:
 
 private slots:
        void dispatch();
-       void wpaOpen();
+       void ping();
        void connectSsid(DHCPCD_WI_SCAN *scan);
 
 private:
@@ -66,7 +67,7 @@ private:
        DHCPCD_WI_SCAN *scans;
 
        QSocketNotifier *notifier;
-       QTimer *retryOpenTimer;
+       QTimer *pingTimer;
 
        QMenu *menu;
        void createMenuItem(QMenu *menu, DHCPCD_WI_SCAN *scan,