void MPEGVS_Stop(struct __input_device * dr) { MPEGVSCTX; if ( rc->trd ) { rc->stop = 1; while ( gf_th_status(rc->trd) == GF_THREAD_STATUS_RUN ) gf_sleep(5); gf_th_del(rc->trd); rc->trd = NULL; rc->stop = 0; } }
GF_Err gf_th_run(GF_Thread *t, u32 (*Run)(void *param), void *param) { #ifdef WIN32 DWORD id; #else pthread_attr_t att; #endif if (!t || t->Run || t->_signal) return GF_BAD_PARAM; t->Run = Run; t->args = param; t->_signal = gf_sema_new(1, 0); #ifdef WIN32 t->threadH = CreateThread(NULL, t->stackSize, &(RunThread), (void *)t, 0, &id); if (t->threadH == NULL) { #else if ( pthread_attr_init(&att) != 0 ) return GF_IO_ERR; pthread_attr_setdetachstate(&att, PTHREAD_CREATE_JOINABLE); if ( pthread_create(&t->threadH, &att, RunThread, t) != 0 ) { #endif t->status = GF_THREAD_STATUS_DEAD; return GF_IO_ERR; } /*wait for the child function to call us - do NOT return before, otherwise the thread status would be unknown*/ gf_sema_wait(t->_signal); gf_sema_del(t->_signal); t->_signal = NULL; return GF_OK; } /* Stops a thread. If Destroy is not 0, thread is destroyed DANGEROUS as no cleanup */ void Thread_Stop(GF_Thread *t, Bool Destroy) { if (gf_th_status(t) == GF_THREAD_STATUS_RUN) { #ifdef WIN32 if (Destroy) { DWORD dw = 1; BOOL ret = TerminateThread(t->threadH, dw); if (!ret) { DWORD err = GetLastError(); GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] Couldn't stop thread ID 0x%08x, error code %d\n", t->log_name, t->id, err)); } t->threadH = NULL; } else { WaitForSingleObject(t->threadH, INFINITE); } #else if (Destroy) { #ifdef GPAC_ANDROID if (pthread_kill(t->threadH, SIGQUIT)) #else if (pthread_cancel(t->threadH)) #endif GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] Couldn't kill thread ID 0x%08x\n", t->log_name, t->id)); t->threadH = 0; } else { /*gracefully wait for Run to finish*/ if (pthread_join(t->threadH, NULL)) GF_LOG(GF_LOG_ERROR, GF_LOG_MUTEX, ("[Thread %s] pthread_join() returned an error with thread ID 0x%08x\n", t->log_name, t->id)); } #endif } t->status = GF_THREAD_STATUS_DEAD; } void gf_th_stop(GF_Thread *t) { Thread_Stop(t, 0); }