void SingleThreadedApplication::run() { signalDone(); boost::mutex::scoped_lock lock(newEventMutex_); eventLock_ = &lock; for (;;) { if (!newEvent_) { log("debug") << "STA" << ": [thread] waiting for event"; newEventCondition_.wait(lock); } log("debug") << "STA" << ": [thread] handling event"; attachThread(true); try { threadNotify(*event_); } catch (std::exception& e) { log("error") << "STA" << ": [thread] Caught exception: " << e.what(); exception_ = true; } catch (...) { log("error") << "STA" << ": [thread] Caught exception"; exception_ = true; } attachThread(false); signalDone(); if (finalized_) break; newEvent_ = false; } signalDone(); }
//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; }
SteamCallbackAdapter::~SteamCallbackAdapter() { if (m_callback != 0) { JNIEnv* env = attachThread(); env->DeleteGlobalRef(m_callback); detachThread(); } }
/** * Attach a thread to an interpreter instance, returning the * activity thread context. * * @param attachedContext * The pointer for returning the thread context. * * @return 0 indicates success. */ int InterpreterInstance::attachThread(RexxThreadContext *&attachedContext) { RexxActivity *activity = attachThread(); attachedContext = activity->getThreadContext(); // When we attach, we get the current lock. We need to ensure we // release this before returning control to the outside world. activity->releaseAccess(); return 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; }
void DownloadFileTransferAPI::callbackFct(bool success, FB::HeaderMap const &headers, boost::shared_array<uint8_t> const &data, const size_t size) { FBLOG_DEBUG("UploadFileTransferAPI::callbackFct", "this=" << this); if(!success) { mFileStream.close(); FBLOG_DEBUG("UploadFileTransferAPI::callbackFct", "HTTP error"); onError("HTTP error"); return; } // Run thread mThread = boost::make_shared<boost::thread>(boost::bind(DownloadFileTransferAPI::threadFctHolder, boost::static_pointer_cast<DownloadFileTransferAPI>(shared_from_this()), data, size)); attachThread(mThread); }
jboolean rvmInitThreads(Env* env) { if (rvmInitMutex(&threadsLock) != 0) return FALSE; if (pthread_key_create(&tlsEnvKey, NULL) != 0) return FALSE; if (pthread_cond_init(&threadStartCond, NULL) != 0) return FALSE; if (pthread_cond_init(&threadsChangedCond, NULL) != 0) return FALSE; getUncaughtExceptionHandlerMethod = rvmGetInstanceMethod2(env, java_lang_Thread, "getUncaughtExceptionHandler", "()Ljava/lang/Thread$UncaughtExceptionHandler;"); if (!getUncaughtExceptionHandlerMethod) return FALSE; Class* uncaughtExceptionHandler = rvmFindClassInClasspathForLoader(env, "java/lang/Thread$UncaughtExceptionHandler", NULL); if (!uncaughtExceptionHandler) return FALSE; uncaughtExceptionMethod = rvmGetInstanceMethod2(env, uncaughtExceptionHandler, "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V"); if (!uncaughtExceptionMethod) return FALSE; removeThreadMethod = rvmGetInstanceMethod2(env, java_lang_ThreadGroup, "removeThread", "(Ljava/lang/Thread;)V"); if (!removeThreadMethod) return FALSE; return attachThread(env->vm, &env, "main", NULL, FALSE) == JNI_OK; }
/** * Enter on the current thread context, making sure the interpreter * lock is obtained. * * @return The activity object associated with this thread/instance * combination. */ RexxActivity *InterpreterInstance::enterOnCurrentThread() { RexxActivity *activity; { ResourceSection lock("InterpreterInstance::enterOnCurrentThread", 0); // lock the outer control block access // attach this thread to the current activity activity = attachThread(); // this will also get us the kernel lock, and take care of nesting activity->activate(); } // we need to ensure the resource lock is released before we attempt to // acquire the kernel lock activity->requestAccess(); // return the activity in case the caller needs it. return activity; }
static void *shell(void *args) { void *start = ((void**)args)[1]; Thread *self = ((Thread**)args)[2]; if(main_exited) return NULL; /* VM helper threads should be added to the system group, but this doesn't exist. As the root group is main, we add it to that for now... */ attachThread(((char**)args)[0], TRUE, &self, self, //(Object*)INST_DATA(main_ee.thread)[group_offset]); (Object*)INST_DATA(main_thread.thread)[group_offset]); sysFree(args); (*(void(*)(Thread*))start)(self); return NULL; }
//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; }
Thread *attachJNIThread(char *name, char is_daemon, Object *group) { Thread *thread = new Thread; void *stack_base = nativeStackBase(); /* If no group is given add it to the main group */ if(group == NULL) //group = (Object*)INST_DATA(main_ee.thread)[group_offset]; group = (Object*)INST_DATA(main_thread.thread)[group_offset]; /* Initialise internal thread structure */ // memset(thread, 0, sizeof(Thread)); /* Externally created threads will not inherit signal state */ initialiseSignals(); /* Initialise the thread and add it to the VM thread list */ return attachThread(name, is_daemon, stack_base, thread, group); }
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; }
void LocalFileTransferAPI::start() { FBLOG_DEBUG("LocalFileTransferAPI::start", "this=" << this); mSourceFileStr = getFactory()->getFileManager()->uriToFile(mSourceUri); if(mSourceFileStr.empty()) { FBLOG_DEBUG("LocalFileTransferAPI::start", "Invalid source path"); onError("Invalid source path"); return; } FBLOG_DEBUG("LocalFileTransferAPI::start", "sourceFile=" << mSourceFileStr); mTargetFileStr = getFactory()->getFileManager()->uriToFile(mTargetUri); if(mTargetFileStr.empty()) { FBLOG_DEBUG("LocalFileTransferAPI::start", "Invalid target path"); onError("Invalid target path"); return; } FBLOG_DEBUG("LocalFileTransferAPI::start", "targetFile=" << mTargetFileStr); mSourceFilePath = boost::filesystem::path(mSourceFileStr); if(!boost::filesystem::exists(mSourceFilePath)) { FBLOG_DEBUG("LocalFileTransferAPI::start", "The source path \"" << mSourceFileStr << "\" doesn't exist"); onError("The source path doesn't exist"); return; } mTargetFilePath = boost::filesystem::path(mTargetFileStr); if(boost::filesystem::exists(mTargetFilePath)) { FBLOG_DEBUG("LocalFileTransferAPI::start", "The target path \"" << mTargetFileStr << "\" already exists"); onError("The target path already exists"); return; } mTransferedBytes = 0; // Run thread mThread = boost::make_shared<boost::thread>(boost::bind(&LocalFileTransferAPI::threadFctHolder, boost::static_pointer_cast<LocalFileTransferAPI>(shared_from_this()))); attachThread(mThread); }
JNIEnv* jmePhysicsSpace::getEnv() { attachThread(); return this->env; }
void SteamCallbackAdapter::attach(SteamInvokeCallbackFunction fn) const { JNIEnv* env = attachThread(); fn(env); detachThread(); }
jint rvmAttachCurrentThreadAsDaemon(VM* vm, Env** env, char* name, Object* group) { *env = NULL; return attachThread(vm, env, name, group, TRUE); }
//needs be thread safe static int tskDataSourceRead(ScalpelInputReader * const reader, void * buf, size_t size, size_t count) { printVerbose("tskDataSourceRead()\n"); JNIEnv *env = NULL; if (size == 0 || count == 0) { return 0; } env = attachThread(); if (!env) { fprintf(stdout, "ERROR tskDataSourceRead, cannot get env\n"); return 0; } const TskInputStreamSourceInfo * tskData = castTskDataSource(reader); if (!tskData) { setThrowScalpelException(*env, "tskDataSourceRead() - ERROR object not initialized"); return 0; } //tskData->env->MonitorEnter(tskData->jInputStream); const size_t bytesToReadTotal = size * count; size_t bytesReadTotal = 0; //need to read small chunks from java into a smaller java buffer //because we can't allocate huge buffers libscalpel might be requesting //at the same time we are reusing a single preallocated buffer, which might help performance //read: reader is C and writer is java, so need to write to java buffer and then copy back to user C buffer //calling ReadInputContentStream method: public int read(byte[], int, int) throws java.io.IOException; //char tempBuf[JAVA_READ_BUFFER_SIZE]; //temporary C buffer to copy chunk to, before inserting the chunk in user C buffer jvalue args[3]; jvalue * argsP = args; memset((void*)argsP, 0, sizeof(jvalue)); memset((void*) ((jvalue*)argsP+1), 0, sizeof(jvalue)); memset((void*)((jvalue*)argsP+2), 0, sizeof(jvalue));; while (bytesReadTotal < bytesToReadTotal) { jint remainToRead = bytesToReadTotal - bytesReadTotal; jint bytesToRead = remainToRead < JAVA_READ_BUFFER_SIZE ? remainToRead : JAVA_READ_BUFFER_SIZE; args[0].l = tskData->jReadBuffer; args[1].i = 0; args[2].i = bytesToRead; jint bytesRead = 0; bytesRead = env->CallIntMethod(tskData->jInputStream, tskData->jReadMethodId, tskData->jReadBuffer, 0, bytesToRead ); //check read exception from java and throw it back to java as scalpel exception jthrowable readExc = env->ExceptionOccurred(); if (readExc) { setThrowScalpelException(*env, "tskDataSourceRead() - ERROR while reading from the input stream"); env->ExceptionDescribe(); //log to stderr env->ExceptionClear(); //tskData->env->MonitorExit(tskData->jInputStream); detachThread(); return bytesReadTotal; } else if (bytesRead > 0) { //copy java buffer into right offset in C buffer jboolean isCopy; jbyte * tempBuf = env->GetByteArrayElements(tskData->jReadBuffer, &isCopy); if (!tempBuf) { setThrowScalpelException(*env, "tskDataSourceRead() - ERROR copying buffers while reading from the input stream "); env->ExceptionDescribe(); //log to stderr env->ExceptionClear(); //tskData->env->MonitorExit(tskData->jInputStream); detachThread(); return bytesReadTotal; } memcpy( (void*)((char*)buf + bytesReadTotal*sizeof(char)), (void*)tempBuf, bytesRead); env->ReleaseByteArrayElements(tskData->jReadBuffer, tempBuf, 0); } else { //fprintf(stdout, "tskDataSourceRead() - read less than expected, must be eof read: %d\n", bytesReadTotal); return bytesReadTotal; } bytesReadTotal += bytesRead; } if (bytesReadTotal < 0) { //adapt return value bytesReadTotal = 0; } //tskData->env->MonitorExit(tskData->jInputStream); fprintf(stdout, "\ntskDataSourceRead() BEFORE DETACH\n" ); detachThread(); fprintf(stdout, "\ntskDataSourceRead() AFTER DETACH, read %d bytes\n", bytesReadTotal ); return bytesReadTotal; }