示例#1
0
void AssetDownloadTask::textureDownloaded(Transfer::URI uri, ResourceDownloadTaskPtr taskptr, Transfer::TransferRequestPtr request, Transfer::DenseDataPtr response) {
    // This could be triggered by any CDN thread, protect access
    // (mActiveDownloads, mDependencies)
    boost::mutex::scoped_lock lok(mDependentDownloadMutex);

    if (!taskptr) {
        SILOG(ogre, warn, "failed request dependent callback");
        failDownload();
        return;
    }

    if (!request) {
        SILOG(ogre, warn, "failed request dependent callback " << taskptr->getIdentifier());
        failDownload();
        return;
    }

    // Clear the download task
    mActiveDownloads.erase(taskptr->getIdentifier());
    mFinishedDownloads.push_back(taskptr->getIdentifier());

    // Lack of response data means failure of some sort
    if (!response) {
        SILOG(ogre, warn, "failed response dependent callback " << taskptr->getIdentifier());
        failDownload();
        return;
    }

    // Store data for later use
    mDependencies[uri].request = request;
    mDependencies[uri].response = response;

    if (mActiveDownloads.size() == 0)
        mCB();
}
示例#2
0
void DownloadManager::onFailed(UserConnection* aSource, const string& aError) {
    {
        Lock l(cs);
        idlers.erase(remove(idlers.begin(), idlers.end(), aSource), idlers.end());
    }
    failDownload(aSource, aError);
}
示例#3
0
void AssetDownloadTask::assetFileDownloaded(ResourceDownloadTaskPtr taskptr, Transfer::ChunkRequestPtr request, Transfer::DenseDataPtr response) {
    boost::mutex::scoped_lock lok(mDependentDownloadMutex);

    // Clear from the active download list
    assert(mActiveDownloads.size() == 1);
    mActiveDownloads.erase(taskptr->getIdentifier());
    mFinishedDownloads.push_back(taskptr->getIdentifier());

    // Lack of response data means failure of some sort
    if (!response) {
        SILOG(ogre, warn, "Failed to download resource for " << taskptr->getIdentifier());
        failDownload();
        return;
    }

    // FIXME here we could have another callback which lets them get
    // at the hash to try to use an existing copy. Even with the
    // eventual centralized loading we want, this may still be
    // beneficial since Ogre may have a copy even if we don't have a
    // copy of the raw data any more.

    mParseMeshHandle = mScene->parseMesh(
        request->getMetadata(), request->getMetadata().getFingerprint(),
        response, mIsAggregate,
        std::tr1::bind(&AssetDownloadTask::weakHandleAssetParsed, getWeakPtr(), _1)
    );
}
示例#4
0
void DownloadManager::noSlots(UserConnection* aSource) {
    if(aSource->getState() != UserConnection::STATE_SND) {
        dcdebug("DM::noSlots Bad state, disconnecting\n");
        aSource->disconnect();
        return;
    }

    failDownload(aSource, _("No slots available"));
}
示例#5
0
/** Download finished! */
void DownloadManager::endData(UserConnection* aSource) {
    dcassert(aSource->getState() == UserConnection::STATE_RUNNING);
    Download* d = aSource->getDownload();
    dcassert(d != NULL);

    if(d->getType() == Transfer::TYPE_TREE) {
        d->getFile()->flush();

        int64_t bl = 1024;
        while(bl * (int64_t)d->getTigerTree().getLeaves().size() < d->getTigerTree().getFileSize())
            bl *= 2;
        d->getTigerTree().setBlockSize(bl);
        d->getTigerTree().calcRoot();

        if(!(d->getTTH() == d->getTigerTree().getRoot())) {
            // This tree is for a different file, remove from queue...
            removeDownload(d);
            fire(DownloadManagerListener::Failed(), d, _("Full tree does not match TTH root"));

            QueueManager::getInstance()->removeSource(d->getPath(), aSource->getUser(), QueueItem::Source::FLAG_BAD_TREE, false);

            QueueManager::getInstance()->putDownload(d, false);

            checkDownloads(aSource);
            return;
        }
        d->setTreeValid(true);
    } else {
        // First, finish writing the file (flushing the buffers and closing the file...)
        try {
            d->getFile()->flush();
                } catch(const Exception& e) {
                        d->resetPos();
            failDownload(aSource, e.getError());
            return;
        }

        aSource->setSpeed(d->getAverageSpeed());
        aSource->updateChunkSize(d->getTigerTree().getBlockSize(), d->getSize(), GET_TICK() - d->getStart());

        dcdebug("Download finished: %s, size " I64_FMT ", downloaded " I64_FMT "\n", d->getPath().c_str(),
                static_cast<long long int>(d->getSize()), static_cast<long long int>(d->getPos()));

        if(BOOLSETTING(LOG_DOWNLOADS) && (BOOLSETTING(LOG_FILELIST_TRANSFERS) || d->getType() == Transfer::TYPE_FILE)) {
            logDownload(aSource, d);
        }
    }

    removeDownload(d);
    fire(DownloadManagerListener::Complete(), d);

    QueueManager::getInstance()->putDownload(d, true);
    checkDownloads(aSource);
}
示例#6
0
void DownloadManager::on(UserConnectionListener::Data, UserConnection* aSource, const uint8_t* aData, size_t aLen) noexcept {
    Download* d = aSource->getDownload();
    dcassert(d != NULL);

    try {
        d->addPos(d->getFile()->write(aData, aLen), aLen);
        d->tick();

        if(d->getFile()->eof()) {
            endData(aSource);
            aSource->setLineMode(0);
        }
    } catch(const Exception& e) {
        failDownload(aSource, e.getError());
    }
}
示例#7
0
void AssetDownloadTask::textureDownloaded(std::tr1::shared_ptr<ChunkRequest> request, std::tr1::shared_ptr<const DenseData> response) {
    // Clear the download task
    mActiveDownloads.erase(request->getURI());

    // Lack of response data means failure of some sort
    if (!response) {
        failDownload();
        return;
    }

    // Store data for later use
    mDependencies[request->getURI()].request = request;
    mDependencies[request->getURI()].response = response;

    mRemainingDownloads--;
    if (mRemainingDownloads == 0)
        mCB();
}
示例#8
0
void AssetDownloadTask::assetFileDownloaded(std::tr1::shared_ptr<ChunkRequest> request, std::tr1::shared_ptr<const DenseData> response) {
    // Clear from the active download list
    assert(mActiveDownloads.size() == 1);
    mActiveDownloads.erase(mAssetURI);

    // Lack of response data means failure of some sort
    if (!response) {
        failDownload();
        return;
    }

    // FIXME here we could have another callback which lets them get
    // at the hash to try to use an existing copy. Even with the
    // eventual centralized loading we want, this may still be
    // beneficial since Ogre may have a copy even if we don't have a
    // copy of the raw data any more.

    mScene->parseMesh(
        mAssetURI, request->getMetadata().getFingerprint(), response,
        std::tr1::bind(&AssetDownloadTask::weakHandleAssetParsed, getWeakPtr(), _1)
    );
}
示例#9
0
void DownloadManager::startData(UserConnection* aSource, int64_t start, int64_t bytes, bool z) {
    Download* d = aSource->getDownload();
    dcassert(d != NULL);

    dcdebug("Preparing " I64_FMT ":" I64_FMT ", " I64_FMT ":" I64_FMT"\n",
            static_cast<long long int>(d->getStartPos()), static_cast<long long int>(start),
            static_cast<long long int>(d->getSize()), static_cast<long long int>(bytes));
    if(d->getSize() == -1) {
        if(bytes >= 0) {
            d->setSize(bytes);
        } else {
            failDownload(aSource, _("Invalid size"));
            return;
        }
    } else if(d->getSize() != bytes || d->getStartPos() != start) {
        // This is not what we requested...
        failDownload(aSource, _("Response does not match request"));
        return;
    }

    try {
        QueueManager::getInstance()->setFile(d);
    } catch(const FileException& e) {
        failDownload(aSource, str(F_("Could not open target file: %1%") % e.getError()));
        return;
    } catch(const Exception& e) {
        failDownload(aSource, e.getError());
        return;
    }

    if((d->getType() == Transfer::TYPE_FILE || d->getType() == Transfer::TYPE_FULL_LIST) && SETTING(BUFFER_SIZE) > 0 ) {
        d->setFile(new BufferedOutputStream<true>(d->getFile()));
    }

    if(d->getType() == Transfer::TYPE_FILE) {
        typedef MerkleCheckOutputStream<TigerTree, true> MerkleStream;

        d->setFile(new MerkleStream(d->getTigerTree(), d->getFile(), d->getStartPos()));
        d->setFlag(Download::FLAG_TTH_CHECK);
    }

    // Check that we don't get too many bytes
    d->setFile(new LimitedOutputStream<true>(d->getFile(), bytes));

    if(z) {
        d->setFlag(Download::FLAG_ZDOWNLOAD);
        d->setFile(new FilteredOutputStream<UnZFilter, true>(d->getFile()));
    }

    d->setStart(GET_TICK());
    d->tick();
    aSource->setState(UserConnection::STATE_RUNNING);

    fire(DownloadManagerListener::Starting(), d);

    if(d->getPos() == d->getSize()) {
        try {
            // Already finished? A zero-byte file list could cause this...
            endData(aSource);
        } catch(const Exception& e) {
            failDownload(aSource, e.getError());
        }
    } else {
        aSource->setDataMode();
    }
}