void WorkQueue::StopWork(void) { /* discard all scheduled works */ pthread_mutex_lock(&wlock); while (works) works = __list_delete(works, works); pthread_mutex_unlock(&wlock); /* wakeup DoWork() if it's sleeping */ /* * FIXME * * if DoWork() is sleeping, Work()'s called one more time at this moment. * if DoWork()::wi->Work() called ScheduleWork() (self-rescheduling), * this function would be sleeping forever at Join() because works list * never be empty. */ ResumeWork(); pthread_mutex_lock(&wlock); stop = true; pthread_cond_signal(&wcond); /* wakeup Run() if it's sleeping */ pthread_mutex_unlock(&wlock); Join(); }
PortBase::~PortBase() { struct list *entry, *temp; /* should've been already freed at FreeBuffer() */ list_foreach_safe(buffer_hdrs, entry, temp) { free(entry->data); /* OMX_BUFFERHEADERTYPE */ __list_delete(buffer_hdrs, entry); }
static struct list *destruct_components(struct list *head) { struct list *entry, *next; list_foreach_safe(head, entry, next) { CModule *cmodule = static_cast<CModule *>(entry->data); head = __list_delete(head, entry); delete cmodule; }
void WorkQueue::Run(void) { while (!stop) { pthread_mutex_lock(&wlock); if (!works) { pthread_mutex_lock(&executing_lock); wait_for_works = true; /* wake up PauseWork() if it's sleeping */ pthread_cond_signal(&paused_wait); pthread_mutex_unlock(&executing_lock); /* * sleeps until works're available. * wokeup by ScheduleWork() or FlushWork() or ~WorkQueue() */ pthread_cond_wait(&wcond, &wlock); pthread_mutex_lock(&executing_lock); wait_for_works = false; pthread_mutex_unlock(&executing_lock); } while (works) { struct list *entry = works; WorkableInterface *wi = static_cast<WorkableInterface *>(entry->data); works = __list_delete(works, entry); pthread_mutex_unlock(&wlock); /* * 1. if PauseWork() locks executing_lock right before Run() locks * the lock, Run() sends the paused signal and go to sleep. * 2. if Run() locks executing_lock first, DoWork() is called and * PausedWork() waits for paused_wait signal. Run() sends the * signal during next loop processing or at the end of loop * in case of works're not available. */ pthread_mutex_lock(&executing_lock); if (!executing) { pthread_cond_signal(&paused_wait); pthread_cond_wait(&executing_wait, &executing_lock); } pthread_mutex_unlock(&executing_lock); DoWork(wi); pthread_mutex_lock(&wlock); } pthread_mutex_unlock(&wlock); } }