/*!
    Looks up the IP address(es) associated with host name \a name, and
    returns an ID for the lookup. When the result of the lookup is
    ready, the slot or signal \a member in \a receiver is called with
    a QHostInfo argument. The QHostInfo object can then be inspected
    to get the results of the lookup.

    The lookup is performed by a single function call, for example:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 2

    The implementation of the slot prints basic information about the
    addresses returned by the lookup, or reports an error if it failed:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 3

    If you pass a literal IP address to \a name instead of a host name,
    QHostInfo will search for the domain name for the IP (i.e., QHostInfo will
    perform a \e reverse lookup). On success, the resulting QHostInfo will
    contain both the resolved domain name and IP addresses for the host
    name. Example:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 4

    \note There is no guarantee on the order the signals will be emitted
    if you start multiple requests with lookupHost().

    \sa abortHostLookup(), addresses(), error(), fromName()
*/
int QHostInfo::lookupHost(const QString &name, QObject *receiver,
                          const char *member)
{
#if defined QHOSTINFO_DEBUG
    qDebug("QHostInfo::lookupHost(\"%s\", %p, %s)",
           name.toLatin1().constData(), receiver, member ? member + 1 : 0);
#endif
    if (!QAbstractEventDispatcher::instance(QThread::currentThread())) {
        qWarning("QHostInfo::lookupHost() called with no event dispatcher");
        return -1;
    }

    qRegisterMetaType<QHostInfo>("QHostInfo");

    int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID

    if (name.isEmpty()) {
        QHostInfo hostInfo(id);
        hostInfo.setError(QHostInfo::HostNotFound);
        hostInfo.setErrorString(QCoreApplication::translate("QHostInfo", "No host name given"));
        QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
        QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
                         receiver, member, Qt::QueuedConnection);
        result.data()->emitResultsReady(hostInfo);
        return id;
    }

#ifdef QT_NO_THREAD
    QHostInfo hostInfo = QHostInfoAgent::fromName(name);
    hostInfo.setLookupId(id);
    QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
    QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
                     receiver, member, Qt::QueuedConnection);
    result.data()->emitResultsReady(hostInfo);
#else
    QHostInfoLookupManager *manager = theHostInfoLookupManager();
    if (manager) {
        // the application is still alive
        if (manager->cache.isEnabled()) {
            // check cache first
            bool valid = false;
            QHostInfo info = manager->cache.get(name, &valid);
            if (valid) {
                info.setLookupId(id);
                QHostInfoResult result;
                QObject::connect(&result, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
                result.emitResultsReady(info);
                return id;
            }
        }
        // cache is not enabled or it was not in the cache, do normal lookup
        QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
        QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
        manager->scheduleLookup(runnable);
    }
#endif

    return id;
}
示例#2
0
文件: qhostinfo.cpp 项目: BGmot/Qt
// the QHostInfoLookupManager will at some point call this via a QThreadPool
void QHostInfoRunnable::run()
{
    QHostInfoLookupManager *manager = theHostInfoLookupManager();
    // check aborted
    if (manager->wasAborted(id)) {
        manager->lookupFinished(this);
        return;
    }

    QHostInfo hostInfo;

    // QHostInfo::lookupHost already checks the cache. However we need to check
    // it here too because it might have been cache saved by another QHostInfoRunnable
    // in the meanwhile while this QHostInfoRunnable was scheduled but not running
    if (manager->cache.isEnabled()) {
        // check the cache first
        bool valid = false;
        hostInfo = manager->cache.get(toBeLookedUp, &valid);
        if (!valid) {
            // not in cache, we need to do the lookup and store the result in the cache
            hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
            manager->cache.put(toBeLookedUp, hostInfo);
        }
    } else {
        // cache is not enabled, just do the lookup and continue
        hostInfo = QHostInfoAgent::fromName(toBeLookedUp);
    }

    // check aborted again
    if (manager->wasAborted(id)) {
        manager->lookupFinished(this);
        return;
    }

    // signal emission
    hostInfo.setLookupId(id);
    resultEmitter.emitResultsReady(hostInfo);

    // now also iterate through the postponed ones
    {
        QMutexLocker locker(&manager->mutex);
        QMutableListIterator<QHostInfoRunnable*> iterator(manager->postponedLookups);
        while (iterator.hasNext()) {
            QHostInfoRunnable* postponed = iterator.next();
            if (toBeLookedUp == postponed->toBeLookedUp) {
                // we can now emit
                iterator.remove();
                hostInfo.setLookupId(postponed->id);
                postponed->resultEmitter.emitResultsReady(hostInfo);
                delete postponed;
            }
        }
    }

    manager->lookupFinished(this);

    // thread goes back to QThreadPool
}
示例#3
0
// the QHostInfoLookupManager will at some point call this via a QThreadPool
void QHostInfoRunnable::run()
{
    QHostInfoLookupManager *manager = theHostInfoLookupManager();
    // check aborted
    if (manager->wasAborted(id)) {
        manager->lookupFinished(this);
        return;
    }

    // check cache
    // FIXME

    // if not in cache: OS lookup
    QHostInfo hostInfo = QHostInfoAgent::fromName(toBeLookedUp);

    // save to cache
    // FIXME

    // check aborted again
    if (manager->wasAborted(id)) {
        manager->lookupFinished(this);
        return;
    }

    // signal emission
    hostInfo.setLookupId(id);
    resultEmitter.emitResultsReady(hostInfo);

    manager->lookupFinished(this);

    // thread goes back to QThreadPool
}
/*!
    \internal
    Pops a query off the queries list, performs a blocking call to
    QHostInfoAgent::lookupHost(), and emits the resultsReady()
    signal. This process repeats until the queries list is empty.
*/
void QHostInfoAgent::run()
{
#ifndef QT_NO_THREAD
    // Dont' allow thread termination during event delivery, but allow it
    // during the actual blocking host lookup stage.
    setTerminationEnabled(false);
    forever
#endif
    {
        QHostInfoQuery *query;
        {
#ifndef QT_NO_THREAD
            // the queries list is shared between threads. lock all
            // access to it.
            QMutexLocker locker(&mutex);
            if (!quit && queries.isEmpty())
                cond.wait(&mutex);
            if (quit) {
                // Reset the quit variable in case QCoreApplication is
                // destroyed and recreated.
                quit = false;
                break;
            }
	    if (queries.isEmpty())
		continue;
#else
	    if (queries.isEmpty())
		return;
#endif
            query = queries.takeFirst();
            pendingQueryId = query->object->lookupId;
        }

#if defined(QHOSTINFO_DEBUG)
        qDebug("QHostInfoAgent::run(%p): looking up \"%s\"", this,
               query->hostName.toLatin1().constData());
#endif

#ifndef QT_NO_THREAD
        // Start query - allow termination at this point, but not outside. We
        // don't want to all termination during event delivery, but we don't
        // want the lookup to prevent the app from quitting (the agent
        // destructor terminates the thread).
        setTerminationEnabled(true);
#endif
        QHostInfo info = fromName(query->hostName);
#ifndef QT_NO_THREAD
        setTerminationEnabled(false);
#endif

        int id = query->object->lookupId;
        info.setLookupId(id);
        if (pendingQueryId == id)
            query->object->emitResultsReady(info);
        delete query;
    }
}
示例#5
0
/*!
    Looks up the IP address(es) associated with host name \a name, and
    returns an ID for the lookup. When the result of the lookup is
    ready, the slot or signal \a member in \a receiver is called with
    a QHostInfo argument. The QHostInfo object can then be inspected
    to get the results of the lookup.

    The lookup is performed by a single function call, for example:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 2

    The implementation of the slot prints basic information about the
    addresses returned by the lookup, or reports an error if it failed:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 3

    If you pass a literal IP address to \a name instead of a host name,
    QHostInfo will search for the domain name for the IP (i.e., QHostInfo will
    perform a \e reverse lookup). On success, the resulting QHostInfo will
    contain both the resolved domain name and IP addresses for the host
    name. Example:

    \snippet doc/src/snippets/code/src_network_kernel_qhostinfo.cpp 4

    \note There is no guarantee on the order the signals will be emitted
    if you start multiple requests with lookupHost().

    \sa abortHostLookup(), addresses(), error(), fromName()
*/
int QHostInfo::lookupHost(const QString &name, QObject *receiver,
                          const char *member)
{
#if defined QHOSTINFO_DEBUG
    qDebug("QHostInfo::lookupHost(\"%s\", %p, %s)",
           name.toLatin1().constData(), receiver, member ? member + 1 : 0);
#endif
    if (!QAbstractEventDispatcher::instance(QThread::currentThread())) {
        qWarning("QHostInfo::lookupHost() called with no event dispatcher");
        return -1;
    }

    qRegisterMetaType<QHostInfo>("QHostInfo");

    int id = theIdCounter.fetchAndAddRelaxed(1); // generate unique ID

    if (name.isEmpty()) {
        QHostInfo hostInfo(id);
        hostInfo.setError(QHostInfo::HostNotFound);
        hostInfo.setErrorString(QObject::tr("No host name given"));
        QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
        QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
                         receiver, member, Qt::QueuedConnection);
        result.data()->emitResultsReady(hostInfo);
        return id;
    }

#ifdef QT_NO_THREAD
    QHostInfo hostInfo = QHostInfoAgent::fromName(name);
    hostInfo.setLookupId(id);
    QScopedPointer<QHostInfoResult> result(new QHostInfoResult);
    QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)),
                     receiver, member, Qt::QueuedConnection);
    result.data()->emitResultsReady(hostInfo);
#else
    QHostInfoRunnable* runnable = new QHostInfoRunnable(name, id);
    QObject::connect(&runnable->resultEmitter, SIGNAL(resultsReady(QHostInfo)), receiver, member, Qt::QueuedConnection);
    theHostInfoLookupManager()->scheduleLookup(runnable);
#endif

    return id;
}
示例#6
0
void QHostInfoProto::setLookupId(int id)
{
    QHostInfo *item = qscriptvalue_cast<QHostInfo*>(thisObject());
    if (item)
        item->setLookupId(id);
}