Example #1
0
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;
    }
Example #4
0
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);
    }
}