static void jnienv_detach_thread(void * /*arg*/) { FRAME_TRACER; //DBG("env=%p, jvm=%p", reinterpret_cast<JNIEnv*>(arg), jvm()); if (jvm()) jvm()->DetachCurrentThread(); }
static void jnienv_detach_thread(void *arg) { (void)arg; if (!jvm()) return; __android_log_print(ANDROID_LOG_VERBOSE, "XBMC","detaching thread"); jvm()->DetachCurrentThread(); }
JNIEnv *jnienv() { ::pthread_once(&s_jnienv_key_once, &jnienv_key_create); JNIEnv *env = reinterpret_cast<JNIEnv *>(::pthread_getspecific(s_jnienv_key)); if (!env && jvm()) { jvm()->AttachCurrentThread(&env, NULL); if (!save_jnienv(env)) ::abort(); } return env; }
RHO_GLOBAL void *rho_nativethread_start() { JNIEnv *env; jvm()->AttachCurrentThread(&env, NULL); store_thr_jnienv(env); return NULL; }
//-------------------------------------------------------------------------------------------------- RHO_GLOBAL void *rho_nativethread_start() { JNIEnv *env; jvm()->AttachCurrentThread(&env, NULL); RAWTRACE2("Starting new thread - env: 0x%.8x, functions: 0x%.8x ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^", env, env->functions); store_thr_jnienv(env); return NULL; }
RHO_GLOBAL void rho_nativethread_end(void *) { jvm()->DetachCurrentThread(); }
//-------------------------------------------------------------------------------------------------- RHO_GLOBAL void rho_nativethread_end(void *) { RAWTRACE1("Thread ended - env: 0x%.8x ===================================================", jnienv()); jvm()->DetachCurrentThread(); store_thr_jnienv(0); }
int WorkerThread::svc(void) { madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " checking thread existence\n", name_.c_str()); if (thread_) { started_ = 1; #ifdef _MADARA_JAVA_ // try detaching one more time, just to make sure. utility::java::Acquire_VM jvm(false); #endif #ifndef MADARA_NO_THREAD_LOCAL madara::logger::Logger::set_thread_name(name_); #endif thread_->init(data_); { utility::TimeValue current = utility::get_time_value(); utility::TimeValue next_epoch; utility::Duration frequency; // only allow one-way communication of durations. We never read control int64_t min_duration = -1; int64_t max_duration = 0; int64_t last_duration = 0; bool max_duration_changed = true; bool min_duration_changed = true; bool one_shot = true; bool blaster = false; bool debug = debug_.is_true(); knowledge::VariableReference terminated; knowledge::VariableReference paused; terminated = control_.get_ref(name_ + ".terminated"); paused = control_.get_ref(name_ + ".paused"); // change thread frequency change_frequency( hertz_, current, frequency, next_epoch, one_shot, blaster); #ifndef MADARA_NO_THREAD_LOCAL madara::logger::Logger::set_thread_hertz(hertz_); #endif if (debug) { start_time_ = utility::get_time(); } while (control_.get(terminated).is_false()) { madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread checking for pause\n", name_.c_str()); if (control_.get(paused).is_false()) { madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread calling run function\n", name_.c_str()); try { int64_t start_time = 0, end_time = 0; debug = debug_.is_true(); if (debug) { start_time = utility::get_time(); ++executions_; } thread_->run(); if (debug) { end_time = utility::get_time(); // update duration information last_duration = end_time - start_time; if (min_duration == -1 || last_duration < min_duration) { min_duration = last_duration; min_duration_changed = true; } if (last_duration > max_duration) { max_duration = last_duration; max_duration_changed = true; } // lock control plane and update { // write updates to control knowledge::ContextGuard guard(control_); last_start_time_ = start_time; end_time_ = end_time; last_duration_ = last_duration; if (max_duration_changed) { max_duration_ = max_duration; } if (min_duration_changed) { min_duration_ = min_duration; } } // end lock of control plane } // end if debug } // end try of the run catch (const std::exception& e) { madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_EMERGENCY, "WorkerThread(%s)::svc:" " exception thrown: %s\n", name_.c_str(), e.what()); } } if (one_shot) break; // check for a change in frequency/hertz if (new_hertz_ != hertz_) { change_frequency( *new_hertz_, current, frequency, next_epoch, one_shot, blaster); } if (!blaster) { current = utility::get_time_value(); madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread checking for next hertz epoch\n", name_.c_str()); if (current < next_epoch) utility::sleep(next_epoch - current); madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread past epoch\n", name_.c_str()); next_epoch += frequency; } } // end while !terminated madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread has been terminated\n", name_.c_str()); } madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " calling thread cleanup method\n", name_.c_str()); thread_->cleanup(); madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " deleting thread\n", name_.c_str()); madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " setting finished to 1\n", finished_.get_name().c_str()); finished_ = 1; } else { madara_logger_ptr_log(logger::global_logger.get(), logger::LOG_MAJOR, "WorkerThread(%s)::svc:" " thread creation failed\n", name_.c_str()); } return 0; }