Exemplo n.º 1
0
//return 0 on no error
static int tskDataSourceOpen(ScalpelInputReader * const reader) {
	printVerbose("tskDataSourceOpen()\n");

	JNIEnv * env = attachThread();
	TskInputStreamSourceInfo * tskData = castTskDataSource(reader);
	if (!tskData) {
		setThrowScalpelException(* (env), "tskDataSourceOpen() - ERROR object not initialized");
		detachThread();
		return -1;
	}

	if (reader->isOpen) {
		fprintf(stdout, "tskDataSourceOpen() WARNING stream already open\n");
		//already open, should really close first, reset
		jlong zerOff = env->CallLongMethod(tskData->jInputStream, tskData->jSeekMethodId, (jlong)0);
		fprintf(stdout, "tskDataSourceOpen() rewinded, new offset: %"PRI64 "\n", (long long) zerOff);
	}
	else if (!tskData->firstOpen) {
		//closed but had already been open, so need to rewind to start
		//const jlong jnewOff =
		jlong zerOff = env->CallLongMethod(tskData->jInputStream, tskData->jSeekMethodId, (jlong)0);
		fprintf(stdout, "tskDataSourceOpen() rewinded, new offset: %"PRI64 "\n", (long long) zerOff);
	}


	reader->isOpen = TRUE;
	tskData->firstOpen = FALSE;
	detachThread();

	return 0;
}
Exemplo n.º 2
0
//return 0 on no-error
static int tskDataSourceSeekO(ScalpelInputReader * const reader, long long offset,
		scalpel_SeekRel whence) {
	printVerbose("tskDataSourceSeekO()\n");
	//fprintf (stdout, "tskDataSourceSeekO() offset: %"PRI64 "whence: %d\n", offset, whence);
	JNIEnv * env = attachThread();
	const TskInputStreamSourceInfo * tskData = castTskDataSource(reader);
	if (!tskData) {
		setThrowScalpelException(* (env), "tskDataSourceSeekO() - ERROR object not initialized");
		detachThread();
		return -1;
	}

	jlong newOffset = 0;
	jlong joffRel = 0;
	switch (whence) {
	case SCALPEL_SEEK_SET:
		newOffset = offset;
		break;
	case SCALPEL_SEEK_CUR:
		//get cur
		joffRel = env->CallLongMethod(tskData->jInputStream, tskData->jGetPositionMethodId);
		newOffset = offset + joffRel;
		break;
	case SCALPEL_SEEK_END:
		//get size
		joffRel = env->CallLongMethod(tskData->jInputStream, tskData->jGetSizeMethodId);
		newOffset = joffRel - offset; //TODO verify if need -1
		break;
	default:
		break;
	}

	if (newOffset < 0) {
		setThrowScalpelException(* (env), "tskDataSourceSeekO() - ERROR invalid negative resulting offset.");
		detachThread();
		return -1;
	}

	//const jlong jnewOff =
	env->CallLongMethod(tskData->jInputStream, tskData->jSeekMethodId, newOffset);

	if (env->ExceptionCheck() ){
		env->ExceptionDescribe();
		env->ExceptionClear();
		setThrowScalpelException(* (env), "tskDataSourceSeekO() - ERROR seek failed.");
		detachThread();
		return -1;
	}

	detachThread();

	//fprintf(stdout, "tskDataSourceSeekO() deltaOffset: %"PRI64", new offset: %"PRI64 "\n", newOffset, (long long) jnewOff);

	return 0;

}
Exemplo n.º 3
0
void* WorkerThread::workerThread()
{
    {
        MutexLocker lock(m_threadCreationMutex);
        m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_userAgent);

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
           m_workerContext->script()->forbidExecution();
        }
    }

    WorkerScriptController* script = m_workerContext->script();
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData.clear();

    runEventLoop();

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerContext->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerContext = 0;
    
    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);

    return 0;
}
Exemplo n.º 4
0
// Creates a separate thread to handle dispatching timer events. That 'timer' thread registers a signal
// handler for SIGALRM signals and then waits on a semaphore indefinitely. The semaphore is unlocked when
// the signal handler is invoked. The timer thread subsequently gets unblocked from the semaphore wait
// and then invokes the 'timerEventCallback' callback which is used to indicate that a timer event has
// occurred. Upon timer notice, the platform should invoke the fireTimerIfNeeded() routine which basically
// invokes the 'sharedTimerFiredFunction' callback, which is the actual WebCore callback routine to
// execute upon timer expiration.
void setSharedTimerFiredFunction(void (*callbackFunc)())
{
    ASSERT(callbackFunc);
    
    if (timerEventCallback == NULL) {
        LOG_ERROR("timerEventCallback is NULL");
        exit(1);
    }
    
    if (sharedTimerFiredFunction == NULL) {
        sharedTimerFiredFunction = callbackFunc;
        
        LOG_ERROR_ON_FAILURE_AND_EXIT(sem_init(&threadReadySem, 0, 0));
        
        ASSERT(isMainThread());
        
        // Create a separate thread to signal timer events through the timerEventCallback function
        ThreadIdentifier timerThreadID = createThread(timerThreadEntryPoint, NULL, "WebCore: Timers");
        
        if (!timerThreadID) {
            LOG_ERROR("Timer thread creation failed\n");
            exit(1);
        }
        
        // Synchronously wait for the timer thread to signal it's now ready to handle timer signals -
        // this prevents dropping early timer requests from WebCore
        LOG_ERROR_ON_FAILURE(sem_wait(&threadReadySem));

        detachThread(timerThreadID);
    }
}
Exemplo n.º 5
0
void *threadStart(void *arg) {
    Thread *thread = (Thread *)arg;
    //Object *jThread = thread->ee->thread;
    Object *jThread = thread->thread;

    /* Parent thread created thread with suspension disabled.
       This is inherited so we need to enable */
    enableSuspend(thread);

    /* Complete initialisation of the thread structure, create the thread
       stack and add the thread to the thread list */
    initThread(thread, INST_DATA(jThread)[daemon_offset], &thread);

    /* Add thread to thread ID map hash table. */
    addThreadToHash(thread);

    /* Execute the thread's run method */
    DummyFrame dummy;
    executeMethod(&dummy, jThread, CLASS_CB(jThread->classobj)->method_table[run_mtbl_idx]);

    /* Run has completed.  Detach the thread from the VM and exit */
    detachThread(thread);

    TRACE("Thread 0x%x id: %d exited\n", thread, thread->id);
    return NULL;
}
Exemplo n.º 6
0
static
bool
attachThreadToForeground()
{
    // only attach threads if using low level hooks.  a low level hook
    // runs in the thread that installed the hook but we have to make
    // changes that require being attached to the target thread (which
    // should be the foreground window).  a regular hook runs in the
    // thread that just removed the event from its queue so we're
    // already in the right thread.
    if (g_hookThread != 0) {
        HWND window    = GetForegroundWindow();
        DWORD threadID = GetWindowThreadProcessId(window, NULL);
        // skip if no change
        if (g_attachedThread != threadID) {
            // detach from previous thread
            detachThread();

            // attach to new thread
            if (threadID != 0 && threadID != g_hookThread) {
                AttachThreadInput(g_hookThread, threadID, TRUE);
                g_attachedThread = threadID;
            }
            return true;
        }
    }
    return false;
}
void LocalFileTransferAPI::threadFct() {
	FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this);
	char buffer[BUFFER_SIZE];
	std::streamsize readSize = 1;
	try {
		mSourceFileStream.open(mSourceFileStr.c_str(), std::ios_base::in | std::ios_base::binary);
		if(mSourceFileStream.fail()) {
			FBLOG_DEBUG("LocalFileTransferAPI::start", "Can't open the source file: " << mSourceFileStr);
			onError("Can't open the source file");
			throw std::runtime_error("Can't open the source file");
		}
	
		mTargetFileStream.open(mTargetFileStr.c_str(), std::ios_base::out | std::ios_base::binary);
		if(mTargetFileStream.fail()) {
			FBLOG_DEBUG("LocalFileTransferAPI::start", "Can't open the target file: " << mTargetFileStr);
			onError("Can't open the target file");
			throw std::runtime_error("Can't open the target file");
		}
		mSourceFileStream.seekg (0, std::ifstream::end);
		mTotalBytes = mSourceFileStream.tellg();
		mSourceFileStream.seekg (0, std::ifstream::beg);

		boost::this_thread::disable_interruption di;
		while(!boost::this_thread::interruption_requested() && readSize > 0) {
			readSize = mTotalBytes - mTransferedBytes;
			if(readSize > BUFFER_SIZE) readSize = BUFFER_SIZE;
			mSourceFileStream.read(buffer, readSize);
			readSize = mSourceFileStream.gcount();
			if(mSourceFileStream.fail()) {
				FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this << " | Can't read the source file" << mSourceFileStream.rdstate());
				onError("Can't read the source file");
				throw std::runtime_error("Can't read the source file");
			}
			FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this << " | Read " << readSize << "(" << mTransferedBytes << " of " << mTotalBytes << ")");
			mTransferedBytes += readSize;
			mTargetFileStream.write(buffer, readSize);
			if(mTargetFileStream.fail()) {
				FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this << " | Can't write the target file " << mTargetFileStream.rdstate());
				onError("Can't write the target file");
				throw std::runtime_error("Can't write the target file");
			}
		}
		if(mTransferedBytes != mTotalBytes) {
			FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this << " | Incomplet transfer");
			onError("Incomplet transfer");
			throw std::runtime_error("Incomplet transfer");
		}

		mSourceFileStream.close();
		mTargetFileStream.close();
		FBLOG_DEBUG("LocalFileTransferAPI::threadFct", "this=" << this << " | Done");
		onSuccess(true);
	} catch(std::runtime_error&) {
		mSourceFileStream.close();
		mTargetFileStream.close();
		// Nothing to do
	}
	detachThread(boost::this_thread::get_id());
	mThread.reset();
}
Exemplo n.º 8
0
void* DatabaseThread::databaseThread()
{
    LOG(StorageAPI, "Starting DatabaseThread %p", this);

    AutodrainedPool pool;
    while (true) {
        RefPtr<DatabaseTask> task;
        if (!m_queue.waitForMessage(task))
            break;

        task->performTask();

        pool.cycle();
    }

    LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());

    // Detach the thread so its resources are no longer of any concern to anyone else
    detachThread(m_threadID);

    // Clear the self refptr, possibly resulting in deletion
    m_selfRef = 0;

    return 0;
}
Exemplo n.º 9
0
SteamCallbackAdapter::~SteamCallbackAdapter() {
    if (m_callback != 0) {
        JNIEnv* env = attachThread();
        env->DeleteGlobalRef(m_callback);
        detachThread();
    }
}
Exemplo n.º 10
0
void ThreadedCompositor::runCompositingThread()
{
    {
        LockHolder locker(m_initializeRunLoopConditionLock);

        m_compositingRunLoop = std::make_unique<CompositingRunLoop>([&] {
            renderLayerTree();
        });
        m_scene = adoptRef(new CoordinatedGraphicsScene(this));
        m_viewportController = std::make_unique<SimpleViewportController>(this);

        m_initializeRunLoopCondition.notifyOne();
    }

    m_compositingRunLoop->runLoop().run();

    m_compositingRunLoop->stopUpdates();
    m_scene->purgeGLResources();

    {
        LockHolder locker(m_terminateRunLoopConditionLock);
        m_compositingRunLoop = nullptr;
        m_context = nullptr;
        m_scene = nullptr;
        m_terminateRunLoopCondition.notifyOne();
    }

    detachThread(m_threadIdentifier);
}
Exemplo n.º 11
0
//return size, or -1 on error
static long long tskDataSourceGetSize(ScalpelInputReader * const reader) {
	printVerbose("tskDataSourceGetSize()\n");
	JNIEnv * env = attachThread();
	const TskInputStreamSourceInfo * tskData = castTskDataSource(reader);
	if (!tskData) {

		setThrowScalpelException(* (env), "tskDataSourceGetSize() - ERROR object not initialized");
		detachThread();
		return -1;
	}

	const jlong jsize = env->CallLongMethod(tskData->jInputStream, tskData->jGetSizeMethodId);

	detachThread();

	return (long long) jsize;
}
Exemplo n.º 12
0
static unsigned long long tskDataSourceTellO(ScalpelInputReader * const reader) {
	printVerbose("tskDataSourceTellO()\n");
	JNIEnv * env = attachThread();
	const TskInputStreamSourceInfo * tskData = castTskDataSource(reader);
	if (!tskData) {
		setThrowScalpelException(*env, "tskDataSourceTellO() - ERROR object not initialized");
		detachThread();
		return 0;
	}

	const jlong joff = env->CallLongMethod(tskData->jInputStream, tskData->jGetPositionMethodId);

	detachThread();

	fprintf(stdout, "tskDataSourceTellO() ret %"PRIu64 "\n", joff );

	return (unsigned long long) joff;
}
Exemplo n.º 13
0
void AutomaticThread::start(const LockHolder&)
{
    RELEASE_ASSERT(m_isRunning);

    RefPtr<AutomaticThread> preserveThisForThread = this;

    m_hasUnderlyingThread = true;

    ThreadIdentifier thread = createThread(
                                  "WTF::AutomaticThread",
    [=] () {
        if (verbose)
            dataLog(RawPointer(this), ": Running automatic thread!\n");
        ThreadScope threadScope(preserveThisForThread);

        if (!ASSERT_DISABLED) {
            LockHolder locker(*m_lock);
            ASSERT(!m_condition->contains(locker, this));
        }

        auto stop = [&] (const LockHolder&) {
            m_isRunning = false;
            m_isRunningCondition.notifyAll();
        };

        for (;;) {
            {
                LockHolder locker(*m_lock);
                for (;;) {
                    PollResult result = poll(locker);
                    if (result == PollResult::Work)
                        break;
                    if (result == PollResult::Stop)
                        return stop(locker);
                    RELEASE_ASSERT(result == PollResult::Wait);
                    // Shut the thread down after one second.
                    bool awokenByNotify =
                        m_condition->m_condition.waitFor(*m_lock, 1_s);
                    if (!awokenByNotify) {
                        if (verbose)
                            dataLog(RawPointer(this), ": Going to sleep!\n");
                        m_condition->add(locker, this);
                        return;
                    }
                }
            }

            WorkResult result = work();
            if (result == WorkResult::Stop) {
                LockHolder locker(*m_lock);
                return stop(locker);
            }
            RELEASE_ASSERT(result == WorkResult::Continue);
        }
    });
    detachThread(thread);
}
Exemplo n.º 14
0
void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone)
{
    ThreadIdentifier threadID = createThread(collect, 0, "WebCore: GCController");

    if (waitUntilDone) {
        waitForThreadCompletion(threadID);
        return;
    }

    detachThread(threadID);
}
void MemoryPressureHandler::uninstall()
{
    if (!m_installed)
        return;

    if (m_threadID) {
        detachThread(m_threadID);
        m_threadID = 0;
    }

    logErrorAndCloseFDs(nullptr);
    m_installed = false;
}
Exemplo n.º 16
0
void WorkerThread::workerThread()
{
    // Propagate the mainThread's fenv to workers.
#if PLATFORM(IOS)
    FloatingPointEnvironment::singleton().propagateMainThreadEnvironment();
#endif

#if PLATFORM(GTK)
    GRefPtr<GMainContext> mainContext = adoptGRef(g_main_context_new());
    g_main_context_push_thread_default(mainContext.get());
#endif

    {
        LockHolder lock(m_threadCreationMutex);
        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_shouldBypassMainWorldContentSecurityPolicy, WTFMove(m_startupData->m_topOrigin));

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
            m_workerGlobalScope->script()->forbidExecution();
        }
    }

    WorkerScriptController* script = m_workerGlobalScope->script();
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData = nullptr;

    runEventLoop();

#if PLATFORM(GTK)
    g_main_context_pop_thread_default(mainContext.get());
#endif

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerGlobalScope->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerGlobalScope = nullptr;

    // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
    threadGlobalData().destroy();

    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);
}
Exemplo n.º 17
0
void WorkQueue::platformInvalidate()
{
    {
        LockHolder locker(m_terminateRunLoopConditionMutex);
        if (m_runLoop) {
            m_runLoop->stop();
            m_terminateRunLoopCondition.wait(m_terminateRunLoopConditionMutex);
        }
    }

    if (m_workQueueThread) {
        detachThread(m_workQueueThread);
        m_workQueueThread = 0;
    }
}
Exemplo n.º 18
0
void DatabaseThread::databaseThread()
{
    {
        // Wait for DatabaseThread::start() to complete.
        LockHolder lock(m_threadCreationMutex);
        LOG(StorageAPI, "Started DatabaseThread %p", this);
    }

    while (auto task = m_queue.waitForMessage()) {
        AutodrainedPool pool;

        task->performTask();
    }

    // Clean up the list of all pending transactions on this database thread
    m_transactionCoordinator->shutdown();

    LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());

    // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
    // inconsistent or locked state.
    DatabaseSet openSetCopy;
    {
        LockHolder lock(m_openDatabaseSetMutex);
        if (m_openDatabaseSet.size() > 0) {
            // As the call to close will modify the original set, we must take a copy to iterate over.
            openSetCopy.swap(m_openDatabaseSet);
        }
    }

    for (auto& openDatabase : openSetCopy)
        openDatabase->close();

    // Detach the thread so its resources are no longer of any concern to anyone else
    detachThread(m_threadID);

    DatabaseTaskSynchronizer* cleanupSync = m_cleanupSync;

    // Clear the self refptr, possibly resulting in deletion
    m_selfRef = nullptr;

    if (cleanupSync) // Someone wanted to know when we were done cleaning up.
        cleanupSync->taskCompleted();
}
Exemplo n.º 19
0
void WorkerThread::workerThread()
{
    // Propagate the mainThread's fenv to workers.
#if PLATFORM(IOS)
    fesetenv(&mainThreadFEnv);
#endif

    {
        MutexLocker lock(m_threadCreationMutex);
        m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, std::move(m_startupData->m_groupSettings), m_startupData->m_contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupData->m_topOrigin.release());

        if (m_runLoop.terminated()) {
            // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
            // forbidExecution() couldn't be called from stop().
            m_workerGlobalScope->script()->forbidExecution();
        }
    }

    WorkerScriptController* script = m_workerGlobalScope->script();
#if ENABLE(INSPECTOR)
    InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), m_startupData->m_startMode);
#endif
    script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
    // Free the startup data to cause its member variable deref's happen on the worker's thread (since
    // all ref/derefs of these objects are happening on the thread at this point). Note that
    // WorkerThread::~WorkerThread happens on a different thread where it was created.
    m_startupData.clear();

    runEventLoop();

    ThreadIdentifier threadID = m_threadID;

    ASSERT(m_workerGlobalScope->hasOneRef());

    // The below assignment will destroy the context, which will in turn notify messaging proxy.
    // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
    m_workerGlobalScope = 0;

    // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
    threadGlobalData().destroy();

    // The thread object may be already destroyed from notification now, don't try to access "this".
    detachThread(threadID);
}
Exemplo n.º 20
0
void* LocalStorageThread::localStorageThread()
{
    while (true) {
        RefPtr<LocalStorageTask> task;
        if (!m_queue.waitForMessage(task))
            break;

        task->performTask();
    }

    // Detach the thread so its resources are no longer of any concern to anyone else
    detachThread(m_threadID);
    m_threadID = 0;

    // Clear the self refptr, possibly resulting in deletion
    m_selfRef = 0;

    return 0;
}
Exemplo n.º 21
0
static void* startThreadEntryPoint(void* _args) {
    ThreadEntryPointArgs* args = (ThreadEntryPointArgs*) _args;
    Env* env = args->env;
    Thread* thread = args->thread;
    JavaThread* threadObj = args->threadObj;

    rvmLockThreadsList();
    jboolean failure = TRUE;

    setThreadEnv(env);
    if (!rvmExceptionOccurred(env)) {
        if (initThread(env, thread, threadObj)) {
            if (rvmSetupSignals(env)) {
                failure = FALSE;
                thread->stackAddr = getStackAddress();
            }
        }
    }
    
    thread->status = THREAD_STARTING;
    pthread_cond_broadcast(&threadStartCond);
    while (thread->status != THREAD_VMWAIT) {
        pthread_cond_wait(&threadStartCond, &threadsLock);
    }
    rvmUnlockThreadsList();

    if (!failure) {
        rvmChangeThreadStatus(env, thread, THREAD_RUNNING);

        rvmChangeThreadPriority(env, thread, thread->threadObj->priority);

        Method* run = rvmGetInstanceMethod2(env, java_lang_Thread, "run", "()V");
        if (run) {
            jvalue emptyArgs[0];
            rvmCallVoidInstanceMethodA(env, (Object*) threadObj, run, emptyArgs);
        }
    }

    detachThread(env, TRUE);

    return NULL;
}
void* DatabaseThread::databaseThread()
{
    {
        // Wait for DatabaseThread::start() to complete.
        MutexLocker lock(m_threadCreationMutex);
        LOG(StorageAPI, "Started DatabaseThread %p", this);
    }

    AutodrainedPool pool;
    while (true) {
        RefPtr<DatabaseTask> task;
        if (!m_queue.waitForMessage(task))
            break;

        task->performTask();

        pool.cycle();
    }

    LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount());

    // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
    // inconsistent or locked state.
    if (m_openDatabaseSet.size() > 0) {
        // As the call to close will modify the original set, we must take a copy to iterate over.
        DatabaseSet openSetCopy;
        openSetCopy.swap(m_openDatabaseSet);
        DatabaseSet::iterator end = openSetCopy.end();
        for (DatabaseSet::iterator it = openSetCopy.begin(); it != end; ++it)
           (*it)->close();
    }

    // Detach the thread so its resources are no longer of any concern to anyone else
    detachThread(m_threadID);

    // Clear the self refptr, possibly resulting in deletion
    m_selfRef = 0;

    return 0;
}
void FileThread::runLoop()
{
    {
        // Wait for FileThread::start() to complete to have m_threadID
        // established before starting the main loop.
        MutexLocker lock(m_threadCreationMutex);
        LOG(FileAPI, "Started FileThread %p", this);
    }

    while (OwnPtr<Task> task = m_queue.waitForMessage()) {
        AutodrainedPool pool;

        task->performTask();
    }

    LOG(FileAPI, "About to detach thread %i and clear the ref to FileThread %p, which currently has %i ref(s)", m_threadID, this, refCount());

    detachThread(m_threadID);

    // Clear the self refptr, possibly resulting in deletion
    m_selfRef = 0;
}
void DownloadFileTransferAPI::threadFct(boost::shared_array<uint8_t> const &adata, size_t &size) {
	FBLOG_DEBUG("DownloadFileTransferAPI::threadFct", "this=" << this);
	
	mFileStream.open(mFileStr.c_str(), std::ios_base::out | std::ios_base::binary);
	if(mFileStream.fail()) {
		FBLOG_DEBUG("UploadFileTransferAPI::start", "Can't open the target file: " << mFileStr);
		onError("Can't open the target file");
		return;
	}
	
	try {
		// Write the file by chunck
		const char *data = (const char *)adata.get();
		size_t writeSize;
		while(!boost::this_thread::interruption_requested() && size > 0) {
			writeSize = size;
			if(writeSize > BUFFER_SIZE) writeSize = BUFFER_SIZE;
			mFileStream.write(data, writeSize);
			if(mFileStream.fail()) {
				FBLOG_DEBUG("DownloadFileTransferAPI::threadFct", "File write error");
				onError("File write error");
				throw std::runtime_error("File write error");
			}
			data += writeSize;
			size -= writeSize;
		}
		mFileStream.close();
		onSuccess(true);
	} catch(std::runtime_error&) {
		// Remove incomplete file
		mFileStream.close();
		boost::filesystem::remove(mFilePath);
	}
	
	detachThread(boost::this_thread::get_id());
	mThread.reset();
}
Exemplo n.º 25
0
    bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
                      int64 startSampleInFile, int numSamples)
    {
        JUCE_AUTORELEASEPOOL
        checkThreadIsAttached();
        bool ok = true;

        while (numSamples > 0)
        {
            if (lastSampleRead != startSampleInFile)
            {
                TimeRecord time;
                time.scale = (TimeScale) inputStreamDesc.mSampleRate;
                time.base = 0;
                time.value.hi = 0;
                time.value.lo = (UInt32) startSampleInFile;

                OSStatus err = MovieAudioExtractionSetProperty (extractor,
                                                                kQTPropertyClass_MovieAudioExtraction_Movie,
                                                                kQTMovieAudioExtractionMoviePropertyID_CurrentTime,
                                                                sizeof (time), &time);

                if (err != noErr)
                {
                    ok = false;
                    break;
                }
            }

            int framesToDo = jmin (numSamples, (int) (bufferList->mBuffers[0].mDataByteSize / inputStreamDesc.mBytesPerFrame));
            bufferList->mBuffers[0].mDataByteSize = inputStreamDesc.mBytesPerFrame * framesToDo;

            UInt32 outFlags = 0;
            UInt32 actualNumFrames = framesToDo;
            OSStatus err = MovieAudioExtractionFillBuffer (extractor, &actualNumFrames, bufferList, &outFlags);
            if (err != noErr)
            {
                ok = false;
                break;
            }

            lastSampleRead = startSampleInFile + actualNumFrames;
            const int samplesReceived = actualNumFrames;

            for (int j = numDestChannels; --j >= 0;)
            {
                if (destSamples[j] != nullptr)
                {
                    const short* src = ((const short*) bufferList->mBuffers[0].mData) + j;

                    for (int i = 0; i < samplesReceived; ++i)
                    {
                        destSamples[j][startOffsetInDestBuffer + i] = (*src << 16);
                        src += numChannels;
                    }
                }
            }

            startOffsetInDestBuffer += samplesReceived;
            startSampleInFile += samplesReceived;
            numSamples -= samplesReceived;

            if (((outFlags & kQTMovieAudioExtractionComplete) != 0 || samplesReceived == 0) && numSamples > 0)
            {
                for (int j = numDestChannels; --j >= 0;)
                    if (destSamples[j] != nullptr)
                        zeromem (destSamples[j] + startOffsetInDestBuffer, sizeof (int) * numSamples);

                break;
            }
        }

        detachThread();
        return ok;
    }
Exemplo n.º 26
0
jint rvmDetachCurrentThread(VM* vm, jboolean ignoreAttachCount) {
    Env* env = rvmGetEnv();
    if (!env) return JNI_EDETACHED;
    return detachThread(env, ignoreAttachCount);
}
Exemplo n.º 27
0
    QTAudioReader (InputStream* const input_, const int trackNum_)
        : AudioFormatReader (input_, TRANS (quickTimeFormatName)),
          ok (false),
          movie (0),
          trackNum (trackNum_),
          lastSampleRead (0),
          lastThreadId (0),
          extractor (0),
          dataHandle (0)
    {
        JUCE_AUTORELEASEPOOL
        bufferList.calloc (256, 1);

       #if JUCE_WINDOWS
        if (InitializeQTML (0) != noErr)
            return;
       #endif

        if (EnterMovies() != noErr)
            return;

        bool opened = juce_OpenQuickTimeMovieFromStream (input_, movie, dataHandle);

        if (! opened)
            return;

        {
            const int numTracks = GetMovieTrackCount (movie);
            int trackCount = 0;

            for (int i = 1; i <= numTracks; ++i)
            {
                track = GetMovieIndTrack (movie, i);
                media = GetTrackMedia (track);

                OSType mediaType;
                GetMediaHandlerDescription (media, &mediaType, 0, 0);

                if (mediaType == SoundMediaType
                     && trackCount++ == trackNum_)
                {
                    ok = true;
                    break;
                }
            }
        }

        if (! ok)
            return;

        ok = false;

        lengthInSamples = GetMediaDecodeDuration (media);
        usesFloatingPointData = false;

        samplesPerFrame = (int) (GetMediaDecodeDuration (media) / GetMediaSampleCount (media));

        trackUnitsPerFrame = GetMovieTimeScale (movie) * samplesPerFrame
                                / GetMediaTimeScale (media);

        OSStatus err = MovieAudioExtractionBegin (movie, 0, &extractor);

        unsigned long output_layout_size;
        err = MovieAudioExtractionGetPropertyInfo (extractor,
                                                   kQTPropertyClass_MovieAudioExtraction_Audio,
                                                   kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
                                                   0, &output_layout_size, 0);
        if (err != noErr)
            return;

        HeapBlock <AudioChannelLayout> qt_audio_channel_layout;
        qt_audio_channel_layout.calloc (output_layout_size, 1);

        err = MovieAudioExtractionGetProperty (extractor,
                                               kQTPropertyClass_MovieAudioExtraction_Audio,
                                               kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
                                               output_layout_size, qt_audio_channel_layout, 0);

        qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

        err = MovieAudioExtractionSetProperty (extractor,
                                               kQTPropertyClass_MovieAudioExtraction_Audio,
                                               kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
                                               output_layout_size,
                                               qt_audio_channel_layout);

        err = MovieAudioExtractionGetProperty (extractor,
                                               kQTPropertyClass_MovieAudioExtraction_Audio,
                                               kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
                                               sizeof (inputStreamDesc),
                                               &inputStreamDesc, 0);
        if (err != noErr)
            return;

        inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger
                                        | kAudioFormatFlagIsPacked
                                        | kAudioFormatFlagsNativeEndian;
        inputStreamDesc.mBitsPerChannel = sizeof (SInt16) * 8;
        inputStreamDesc.mChannelsPerFrame = jmin ((UInt32) 2, inputStreamDesc.mChannelsPerFrame);
        inputStreamDesc.mBytesPerFrame = sizeof (SInt16) * inputStreamDesc.mChannelsPerFrame;
        inputStreamDesc.mBytesPerPacket = inputStreamDesc.mBytesPerFrame;

        err = MovieAudioExtractionSetProperty (extractor,
                                               kQTPropertyClass_MovieAudioExtraction_Audio,
                                               kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
                                               sizeof (inputStreamDesc),
                                               &inputStreamDesc);
        if (err != noErr)
            return;

        Boolean allChannelsDiscrete = false;
        err = MovieAudioExtractionSetProperty (extractor,
                                               kQTPropertyClass_MovieAudioExtraction_Movie,
                                               kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete,
                                               sizeof (allChannelsDiscrete),
                                               &allChannelsDiscrete);

        if (err != noErr)
            return;

        bufferList->mNumberBuffers = 1;
        bufferList->mBuffers[0].mNumberChannels = inputStreamDesc.mChannelsPerFrame;
        bufferList->mBuffers[0].mDataByteSize =  jmax ((UInt32) 4096, (UInt32) (samplesPerFrame * inputStreamDesc.mBytesPerFrame) + 16);

        dataBuffer.malloc (bufferList->mBuffers[0].mDataByteSize);
        bufferList->mBuffers[0].mData = dataBuffer;

        sampleRate = inputStreamDesc.mSampleRate;
        bitsPerSample = 16;
        numChannels = inputStreamDesc.mChannelsPerFrame;

        detachThread();
        ok = true;
    }
Exemplo n.º 28
0
void detachJNIThread(Thread *thread) {
    /* The JNI spec says we should release all locks held by this thread.
       We don't do this (yet), and only remove the thread from the VM. */
    detachThread(thread);
}
Exemplo n.º 29
0
void SteamCallbackAdapter::attach(SteamInvokeCallbackFunction fn) const {
    JNIEnv* env = attachThread();
    fn(env);
    detachThread();
}
Exemplo n.º 30
0
void AutomaticThread::start(const LockHolder&)
{
    RELEASE_ASSERT(m_isRunning);
    
    RefPtr<AutomaticThread> preserveThisForThread = this;
    
    m_hasUnderlyingThread = true;
    
    ThreadIdentifier thread = createThread(
        "WTF::AutomaticThread",
        [=] () {
            if (verbose)
                dataLog(RawPointer(this), ": Running automatic thread!\n");
            
            RefPtr<AutomaticThread> thread = preserveThisForThread;
            thread->threadDidStart();
            
            if (!ASSERT_DISABLED) {
                LockHolder locker(*m_lock);
                ASSERT(m_condition->contains(locker, this));
            }
            
            auto stopImpl = [&] (const LockHolder& locker) {
                thread->threadIsStopping(locker);
                thread->m_hasUnderlyingThread = false;
            };
            
            auto stopPermanently = [&] (const LockHolder& locker) {
                m_isRunning = false;
                m_isRunningCondition.notifyAll();
                stopImpl(locker);
            };
            
            auto stopForTimeout = [&] (const LockHolder& locker) {
                stopImpl(locker);
            };
            
            for (;;) {
                {
                    LockHolder locker(*m_lock);
                    for (;;) {
                        PollResult result = poll(locker);
                        if (result == PollResult::Work)
                            break;
                        if (result == PollResult::Stop)
                            return stopPermanently(locker);
                        RELEASE_ASSERT(result == PollResult::Wait);
                        // Shut the thread down after one second.
                        m_isWaiting = true;
                        bool awokenByNotify =
                            m_waitCondition.waitFor(*m_lock, 1_s);
                        if (verbose && !awokenByNotify && !m_isWaiting)
                            dataLog(RawPointer(this), ": waitFor timed out, but notified via m_isWaiting flag!\n");
                        if (m_isWaiting) {
                            m_isWaiting = false;
                            if (verbose)
                                dataLog(RawPointer(this), ": Going to sleep!\n");
                            // It's important that we don't release the lock until we have completely
                            // indicated that the thread is kaput. Otherwise we'll have a a notify
                            // race that manifests as a deadlock on VM shutdown.
                            return stopForTimeout(locker);
                        }
                    }
                }
                
                WorkResult result = work();
                if (result == WorkResult::Stop) {
                    LockHolder locker(*m_lock);
                    return stopPermanently(locker);
                }
                RELEASE_ASSERT(result == WorkResult::Continue);
            }
        });
    detachThread(thread);
}