Skip to content

Commit

Permalink
Performance|Network|libcore: Keep local IP addresses cached
Browse files Browse the repository at this point in the history
On some platforms it takes a while to query the IP addresses of all the
available network interfaces. Now this query is done in the background and
the results are cached for quick access.
  • Loading branch information
skyjake committed Feb 2, 2017
1 parent 486ef37 commit efac964
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 4 deletions.
6 changes: 3 additions & 3 deletions doomsday/sdk/libcore/src/net/address.cpp
Expand Up @@ -19,9 +19,9 @@

#include "de/Address"
#include "de/String"
#include "networkinterfaces.h"

#include <QHostInfo>
#include <QNetworkInterface>
#include <QRegularExpression>

namespace de {
Expand Down Expand Up @@ -171,9 +171,9 @@ bool Address::isHostLocal(QHostAddress const &host) // static
if (host.isLoopback()) return true;

QHostAddress const hostv6(host.toIPv6Address());
foreach (QHostAddress addr, QNetworkInterface::allAddresses())
foreach (QHostAddress addr, internal::NetworkInterfaces::get().allAddresses())
{
if (QHostAddress(addr.toIPv6Address()) == hostv6)
if (addr == hostv6)
return true;
}
return false;
Expand Down
1 change: 0 additions & 1 deletion doomsday/sdk/libcore/src/net/beacon.cpp
Expand Up @@ -22,7 +22,6 @@
#include "de/LogBuffer"
#include <QUdpSocket>
#include <QHostInfo>
#include <QNetworkInterface>
#include <QTimer>
#include <QMap>

Expand Down
97 changes: 97 additions & 0 deletions doomsday/sdk/libcore/src/net/networkinterfaces.cpp
@@ -0,0 +1,97 @@
/** @file networkinterfaces.cpp Information about network interfaces.
*
* @authors Copyright (c) 2017 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#include "networkinterfaces.h"
#include "de/Task"
#include "de/TaskPool"

#include <QNetworkInterface>
#include <QTimer>

namespace de {
namespace internal {

DENG2_PIMPL(NetworkInterfaces), public Lockable
{
struct AddressQueryTask : public Task
{
NetworkInterfaces::Impl *d;

AddressQueryTask(NetworkInterfaces::Impl *d) : d(d) {}

void runTask() override
{
QList<QHostAddress> ipv6;
foreach (QHostAddress addr, QNetworkInterface::allAddresses())
{
ipv6 << QHostAddress(addr.toIPv6Address());
}

// Submit the updated information.
{
DENG2_GUARD(d);
d->addresses = ipv6;
d->gotAddresses = true;
}

qDebug() << "Local IP addresses:" << ipv6;
}
};

QList<QHostAddress> addresses; // lock before access
TaskPool tasks;
QTimer updateTimer;
bool gotAddresses = false;

Impl(Public *i) : Base(i)
{
updateTimer.setInterval(1000 * 60 * 1);
updateTimer.setSingleShot(false);
QObject::connect(&updateTimer, &QTimer::timeout, [this] ()
{
tasks.start(new AddressQueryTask(this));
});
updateTimer.start();
tasks.start(new AddressQueryTask(this));
}
};

NetworkInterfaces::NetworkInterfaces()
: d(new Impl(this))
{}

QList<QHostAddress> NetworkInterfaces::allAddresses() const
{
if (!d->gotAddresses)
{
// Too early...
d->tasks.waitForDone();
}

DENG2_GUARD(d);
return d->addresses;
}

NetworkInterfaces &NetworkInterfaces::get() // static
{
static NetworkInterfaces nif;
return nif;
}

} // namespace internal
} // namespace de
57 changes: 57 additions & 0 deletions doomsday/sdk/libcore/src/net/networkinterfaces.h
@@ -0,0 +1,57 @@
/** @file networkinterfaces.h Information about network interfaces.
*
* @authors Copyright (c) 2017 Jaakko Keränen <jaakko.keranen@iki.fi>
*
* @par License
* LGPL: http://www.gnu.org/licenses/lgpl.html
*
* <small>This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at your
* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBDENG2_NETWORKINTERFACES_H
#define LIBDENG2_NETWORKINTERFACES_H

#include "de/libcore.h"
#include <QList>
#include <QHostAddress>

namespace de {
namespace internal {

/**
* Information abuot network interfaces.
*
* Maintains a quickly-accessible copy of the network interface data.
*/
class NetworkInterfaces
{
public:
static NetworkInterfaces &get();

public:
NetworkInterfaces();

/**
* Returns a cached copy of the list of network addresses for all of the currently
* available network interfaces. Updated periodically in the background.
*
* @return Network interface addresses, in IPv6 format.
*/
QList<QHostAddress> allAddresses() const;

private:
DENG2_PRIVATE(d)
};

} // namespace internal
} // namespace de

#endif // LIBDENG2_NETWORKINTERFACES_H

0 comments on commit efac964

Please sign in to comment.