Ejemplo n.º 1
0
VFSZipFileTLS* vfs_zipfile_get_tls(VFSNode *node, bool create) {
	VFSZipFileData *zdata = node->data1;
	VFSZipFileTLS *tls = SDL_TLSGet(zdata->tls_id);

	if(tls || !create) {
		return tls;
	}

	tls = calloc(1, sizeof(VFSZipFileTLS));
	SDL_TLSSet(zdata->tls_id, tls, (void(*)(void*))vfs_zipfile_free_tls);

	zip_source_t *src = zip_source_function_create(vfs_zipfile_srcfunc, node, &tls->error);
	zip_t *zip = tls->zip = zip_open_from_source(src, ZIP_RDONLY, &tls->error);

	// FIXME: Taisei currently doesn't handle zip files without explicit directory entries correctly (file listing will not work)

	if(!zip) {
		char *r = vfs_node_repr(zdata->source, true);
		vfs_set_error("Failed to open zip archive '%s': %s", r, zip_error_strerror(&tls->error));
		free(r);
		vfs_zipfile_free_tls(tls);
		SDL_TLSSet(zdata->tls_id, 0, NULL);
		zip_source_free(src);
		return NULL;
	}

	return tls;
}
/* Routine to get the thread-specific error variable */
SDL_error *
SDL_GetErrBuf(void)
{
    static SDL_SpinLock tls_lock;
    static SDL_bool tls_being_created;
    static SDL_TLSID tls_errbuf;
    static SDL_error SDL_global_errbuf;
    const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1;
    SDL_error *errbuf;

    /* tls_being_created is there simply to prevent recursion if SDL_TLSCreate() fails.
       It also means it's possible for another thread to also use SDL_global_errbuf,
       but that's very unlikely and hopefully won't cause issues.
     */
    if (!tls_errbuf && !tls_being_created) {
        SDL_AtomicLock(&tls_lock);
        if (!tls_errbuf) {
            SDL_TLSID slot;
            tls_being_created = SDL_TRUE;
            slot = SDL_TLSCreate();
            tls_being_created = SDL_FALSE;
            SDL_MemoryBarrierRelease();
            tls_errbuf = slot;
        }
        SDL_AtomicUnlock(&tls_lock);
    }
    if (!tls_errbuf) {
        return &SDL_global_errbuf;
    }

    SDL_MemoryBarrierAcquire();
    errbuf = (SDL_error *)SDL_TLSGet(tls_errbuf);
    if (errbuf == ALLOCATION_IN_PROGRESS) {
        return &SDL_global_errbuf;
    }
    if (!errbuf) {
        /* Mark that we're in the middle of allocating our buffer */
        SDL_TLSSet(tls_errbuf, ALLOCATION_IN_PROGRESS, NULL);
        errbuf = (SDL_error *)SDL_malloc(sizeof(*errbuf));
        if (!errbuf) {
            SDL_TLSSet(tls_errbuf, NULL, NULL);
            return &SDL_global_errbuf;
        }
        SDL_zerop(errbuf);
        SDL_TLSSet(tls_errbuf, errbuf, SDL_free);
    }
    return errbuf;
}
Ejemplo n.º 3
0
int
main(int argc, char *argv[])
{
    int arg = 1;
    SDL_Thread *thread;

    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* Load the SDL library */
    if (SDL_Init(0) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
        return (1);
    }

    while (argv[arg] && *argv[arg] == '-') {
        if (SDL_strcmp(argv[arg], "--prio") == 0) {
            testprio = 1;
        }
        ++arg;
    }

    tls = SDL_TLSCreate();
    SDL_assert(tls);
    SDL_TLSSet(tls, "main thread", NULL);
    SDL_Log("Main thread data initially: %s\n", (const char *)SDL_TLSGet(tls));

    alive = 1;
    thread = SDL_CreateThread(ThreadFunc, "One", "#1");
    if (thread == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError());
        quit(1);
    }
    SDL_Delay(5 * 1000);
    SDL_Log("Waiting for thread #1\n");
    alive = 0;
    SDL_WaitThread(thread, NULL);

    SDL_Log("Main thread data finally: %s\n", (const char *)SDL_TLSGet(tls));

    alive = 1;
    signal(SIGTERM, killed);
    thread = SDL_CreateThread(ThreadFunc, "Two", "#2");
    if (thread == NULL) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError());
        quit(1);
    }
    raise(SIGTERM);

    SDL_Quit();                 /* Never reached */
    return (0);                 /* Never reached */
}
Ejemplo n.º 4
0
int SDLCALL
ThreadFunc(void *data)
{
    SDL_TLSSet(tls, "baby thread", NULL);
    SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n",
           (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls));
    while (alive) {
        SDL_Log("Thread '%s' is alive!\n", (char *) data);
        SDL_Delay(1 * 1000);
    }
    SDL_Log("Thread '%s' exiting!\n", (char *) data);
    return (0);
}
Ejemplo n.º 5
0
int SDLCALL
ThreadFunc(void *data)
{
    SDL_ThreadPriority prio = SDL_THREAD_PRIORITY_NORMAL;

    SDL_TLSSet(tls, "baby thread", NULL);
    SDL_Log("Started thread %s: My thread id is %lu, thread data = %s\n",
           (char *) data, SDL_ThreadID(), (const char *)SDL_TLSGet(tls));
    while (alive) {
        SDL_Log("Thread '%s' is alive!\n", (char *) data);

        if (testprio) {
            SDL_Log("SDL_SetThreadPriority(%s):%d\n", getprioritystr(prio), SDL_SetThreadPriority(prio));
            if (++prio > SDL_THREAD_PRIORITY_TIME_CRITICAL)
                prio = SDL_THREAD_PRIORITY_LOW;
        }

        SDL_Delay(1 * 1000);
    }
    SDL_Log("Thread '%s' exiting!\n", (char *) data);
    return (0);
}
Ejemplo n.º 6
0
static void vfs_zipfile_free(VFSNode *node) {
	if(node) {
		VFSZipFileData *zdata = node->data1;

		if(zdata) {
			SDL_TLSID tls_id = ((VFSZipFileData*)node->data1)->tls_id;
			VFSZipFileTLS *tls = SDL_TLSGet(tls_id);

			if(tls) {
				vfs_zipfile_free_tls(tls);
				SDL_TLSSet(tls_id, NULL, NULL);
			}

			if(zdata->source) {
				vfs_decref(zdata->source);
			}

			ht_destroy(&zdata->pathmap);
			free(zdata);
		}
	}
}