示例#1
0
static void flatten_tree(struct node *tree, struct emitter *emit,
			 void *etarget, struct data *strbuf,
			 struct version_info *vi)
{
	struct property *prop;
	struct node *child;
	int seen_name_prop = 0;

	emit->beginnode(etarget, tree->label);

	if (vi->flags & FTF_FULLPATH)
		emit->string(etarget, tree->fullpath, 0);
	else
		emit->string(etarget, tree->name, 0);

	emit->align(etarget, sizeof(cell_t));

	for_each_property(tree, prop) {
		int nameoff;

		if (streq(prop->name, "name"))
			seen_name_prop = 1;

		nameoff = stringtable_insert(strbuf, prop->name);

		emit->property(etarget, prop->label);
		emit->cell(etarget, prop->val.len);
		emit->cell(etarget, nameoff);

		if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
			emit->align(etarget, 8);

		emit->data(etarget, prop->val);
		emit->align(etarget, sizeof(cell_t));
	}
示例#2
0
void *loom_asset_lock(const char *name, unsigned int type, int block)
{
    const char *namePtr = stringtable_insert(name);

    loom_mutex_lock(gAssetLock);

    // Look it up.
    loom_asset_t *asset = loom_asset_getAssetByName(namePtr, 1);
    lmAssert(asset != NULL, "Didn't get asset even though we should have!");

    // If not loaded, and we aren't ready to block, return NULL.
    if ((block == 0) && (asset->state != loom_asset_t::Loaded))
    {
        lmLogDebug(gAssetLogGroup, "Not blocking and not loaded yet; lock of '%s' failed.", namePtr);
        loom_mutex_unlock(gAssetLock);
        return NULL;
    }

    // Otherwise, let's force it to load now.
    if (asset->state != loom_asset_t::Loaded)
    {
        lmLogDebug(gAssetLogGroup, "Blocking so forcing load of '%s'.", namePtr);

        loom_asset_preload(namePtr);

        lmAssert(loom_asset_isOnTrackToLoad(asset), "Preloaded but wasn't on track to load!");

        while (loom_asset_checkLoadedPercentage(namePtr) != 1.f && loom_asset_isOnTrackToLoad(asset))
        {
            lmLogDebug(gAssetLogGroup, "Pumping load of '%s'...", namePtr);
            loom_asset_pump();
        }

        if (asset->state != loom_asset_t::Loaded)
        {
            lmLogError(gAssetLogGroup, "Unable to load asset '%s'!", name);
            loom_mutex_unlock(gAssetLock);
            return NULL;
        }
    }

    // Check type.
    if (asset->type != type)
    {
        lmLogError(gAssetLogGroup, "Tried to lock asset '%s' with wrong type, assetType=%x, requestedType=%x", name, asset->type, type);
        loom_mutex_unlock(gAssetLock);
        return NULL;
    }

    // Inc count.
    asset->blob->incRef();

    loom_mutex_unlock(gAssetLock);

    lmLogDebug(gAssetLogGroup, "Locked asset '%s'...", namePtr);

    // Return ptr.
    return asset->blob->bits;
}
示例#3
0
文件: kp_util.c 项目: awreece/ktap
ktap_str_t *kp_str_new(const char *str, size_t l)
{
	ktap_str_t *ts = stringtable_search(str, l);

	if (ts)
		return ts;

	ts = createstrobj(str, l);
	stringtable_insert(ts);
	return ts;
}
示例#4
0
文件: main.cpp 项目: Y-way/LoomSDK
/**
 * Post all known files to all clients, or if specified, a single client.
 *
 * Useful for fully synching client with the current asset state.
 *
 * TODO: Optimize to use hashes to only transmit modified data, based on
 * client's starting assets.
 */
static void postAllFiles(int clientId = -1)
{
    lmLog(gAssetAgentLogGroup, "Queueing all files for client %d.", clientId);

    loom_mutex_lock(gFileScannerLock);

    // Walk all the files.
    utArray<FileEntry> *list = lmNew(NULL) utArray<FileEntry>();
    platform_walkFiles(".", handleFileStateWalkCallback, list);

    // Queue them all to be sent.
    for (UTsize i = 0; i < list->size(); i++)
    {
        FileModificationNote note;
        note.path          = stringtable_insert((*list)[i].path.c_str());
        note.lastSeenTime  = 0;
        note.onlyForClient = clientId;
        gPendingModifications.push_back(note);
    }

    loom_mutex_unlock(gFileScannerLock);
}
示例#5
0
LoomProfilerRoot::LoomProfilerRoot(const char *name)
{
    for (LoomProfilerRoot *walk = sRootList; walk; walk = walk->mNextRoot)
    {
        if (!strcmp(walk->mName, name))
        {
            lmAssert(false, "Duplicate profile name: %s", name);
        }
    }

    mName                   = name;
    mNameHash               = (int)(long long)stringtable_insert(name); // Poor man's hash
    mNextRoot               = sRootList;
    sRootList               = this;
    mTotalTime              = 0;
    mSubTime                = 0;
    mMaxTime                = 0;
    mMinTime                = INFINITY;
    mTotalInvokeCount       = 0;
    mFirstLoomProfilerEntry = NULL;
    mEnabled                = true;
}
示例#6
0
文件: main.cpp 项目: Y-way/LoomSDK
// Take a difference report from compareFileEntries and issue appropriate
// file modification notes, and check whether they have settled. If so,
// transmit updates to clients.
static void processFileEntryDeltas(utArray<FileEntryDelta> *deltas)
{
    int curTime = platform_getMilliseconds();

    loom_mutex_lock(gFileScannerLock);

    // Update the pending list with all the stuff we've seen.
    for (UTsize i = 0; i < deltas->size(); i++)
    {
        // Get the delta.
        const FileEntryDelta& fed = deltas->at(i);

        // If it's removal, we don't currently send a notification.
        if (fed.action == FileEntryDelta::Removed)
        {
            continue;
        }

        // If it's not whitelisted, ignore it.
        if (!checkInWhitelist(fed.path))
        {
            continue;
        }

        // Note it in the pending modification list.
        bool sawInList = false;
        for (UTsize i = 0; i < gPendingModifications.size(); i++)
        {
            FileModificationNote& fmn = gPendingModifications.at(i);
            if (strcmp(fmn.path, fed.path.c_str()))
            {
                continue;
            }

            // Match - update time.
            lmLogDebug(gAssetAgentLogGroup, "FILE CHANGING - '%s'", fed.path.c_str());
            fmn.lastSeenTime = curTime;
            sawInList        = true;
        }

        if (!sawInList)
        {
            FileModificationNote fmn;
            fmn.path         = stringtable_insert(fed.path.c_str());
            fmn.lastSeenTime = curTime;
            gPendingModifications.push_back(fmn);
            lmLogDebug(gAssetAgentLogGroup, "FILE CHANGED  - '%s'", fed.path.c_str());
        }
    }

    // Now, walk the pending list and send everyone who hasn't been touched for the settling period.

    // See how many files we're sending and note that state.
    const int settleTimeMs = 750;

    int transferStartTime     = platform_getMilliseconds();
    int totalPendingTransfers = 0;
    for (UTsize i = 0; i < gPendingModifications.size(); i++)
    {
        // Only consider pending items that have aged out.
        FileModificationNote& fmn = gPendingModifications.at(i);
        if (curTime - fmn.lastSeenTime < settleTimeMs)
        {
            continue;
        }

        totalPendingTransfers++;
    }

    bool didWeNotifyUserAboutPending = false;

    for (UTsize i = 0; i < gPendingModifications.size(); i++)
    {
        // Only consider pending items that have aged out.
        FileModificationNote& fmn = gPendingModifications.at(i);
        if (curTime - fmn.lastSeenTime < settleTimeMs)
        {
            continue;
        }

        // Make the path canonical.
        utString filename = fmn.path;
        char     canonicalFile[MAXPATHLEN];
        makeAssetPathCanonical(filename.c_str(), canonicalFile);

        // Note: we don't deal with deleted files properly (by uploading new state) because realpath
        // only works right when the file exists. So we just skip doing anything about it.
        // Note we are using gActiveHandlers.size() outside of a lock, but this is ok as it's a word.
        if ((strstr(canonicalFile, ".loom") || strstr(canonicalFile, ".ls")) && (gActiveHandlers.size() > 0))
        {
            lmLog(gAssetAgentLogGroup, "Changed '%s'", canonicalFile);
        }

        if (canonicalFile[0] == 0)
        {
            lmLog(gAssetAgentLogGroup, "   o Ignoring file missing from the asset folder!");

            // Remove from the pending list.
            gPendingModifications.erase(i);
            i--;

            continue;
        }

        // Queue the callback.
        enqueueFileChangeCallback(canonicalFile);

        // Map the file.
        void *fileBits      = NULL;
        long fileBitsLength = 0;
        if (!platform_mapFile(canonicalFile, &fileBits, &fileBitsLength))
        {
            lmLog(gAssetAgentLogGroup, "   o Skipping due to file failing to map.");
            continue;
        }

        // Loop over the active sockets.
        loom_mutex_lock(gActiveSocketsMutex);

        // Blast it out to all clients.
        for (UTsize j = 0; j < gActiveHandlers.size(); j++)
        {
            // If it's for a specific client then only send to that client.
            if ((fmn.onlyForClient != -1) && (fmn.onlyForClient != gActiveHandlers[j]->getId()))
            {
                continue;
            }

            gActiveHandlers[j]->sendFile(canonicalFile, fileBits, fileBitsLength, totalPendingTransfers);

            // If it has been more than a second, note that we are still working.
            const int remainingTransferCount = (totalPendingTransfers * gActiveHandlers.size()) - j;
            if (((platform_getMilliseconds() - transferStartTime) > 2000) && (remainingTransferCount > 1))
            {
                transferStartTime = platform_getMilliseconds();
                lmLog(gAssetAgentLogGroup, "Still transferring files. %d to go!", remainingTransferCount - 1);
                didWeNotifyUserAboutPending = true;
            }
        }

        loom_mutex_unlock(gActiveSocketsMutex);

        totalPendingTransfers--;

        // Unmap the file.
        platform_unmapFile(fileBits);

        // Remove from the pending list.
        gPendingModifications.erase(i);
        i--;
    }

    loom_mutex_unlock(gFileScannerLock);

    if (didWeNotifyUserAboutPending)
    {
        lmLog(gAssetAgentLogGroup, "Done transferring files!");
    }
}