Exemple #1
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Pop
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Pop(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    struct     timespec timed;
    struct     timeval  now;

    // get current time from system
    if (gettimeofday(&now, NULL)) {
        return NPT_FAILURE;
    }

    now.tv_usec += timeout * 1000;
    if (now.tv_usec >= 1000000) {
        now.tv_sec += now.tv_usec / 1000000;
        now.tv_usec = now.tv_usec % 1000000;
    }

    // setup timeout
    timed.tv_sec  = now.tv_sec;
    timed.tv_nsec = now.tv_usec * 1000;

    // lock the mutex that protects the list
    if (pthread_mutex_lock(&m_Mutex)) {
        return NPT_FAILURE;
    }

    NPT_Result result;
    if (timeout) {
        while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) {
            // no item in the list, wait for one
            //NPT_Debug(":: NPT_PosixQueue::Pop - waiting for queue to fill up\n");
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPushOrPopCondition, &m_Mutex, &timed);
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }
        }
    } else {
        result = m_Items.PopHead(item);
    }
    
    // if the list was previously full, signal the condition
    // to wake up the waiting thread
    if (m_MaxItems && (result == NPT_SUCCESS)) {
        if (m_Items.GetItemCount() == m_MaxItems-1) {    
            pthread_cond_signal(&m_CanPushOrPopCondition);
        }
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);
 
    return result;
}
Exemple #2
0
/*----------------------------------------------------------------------
|       NPT_PosixQueue::Pop
+---------------------------------------------------------------------*/
NPT_Result
NPT_PosixQueue::Pop(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    struct timespec timed;
    if (timeout != NPT_TIMEOUT_INFINITE) {
        NPT_CHECK(GetTimeOut(timeout, timed));
    }

    // lock the mutex that protects the list
    if (pthread_mutex_lock(&m_Mutex)) {
        return NPT_FAILURE;
    }

    NPT_Result result;
    if (timeout) {
        while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) {
            // no item in the list, wait for one
            ++m_PoppersWaitingCount;
            if (timeout == NPT_TIMEOUT_INFINITE) {
                pthread_cond_wait(&m_CanPopCondition, &m_Mutex);
                --m_PoppersWaitingCount;
            } else {
                int wait_res = pthread_cond_timedwait(&m_CanPopCondition, 
                                                      &m_Mutex, 
                                                      &timed);
                --m_PoppersWaitingCount;
                if (wait_res == ETIMEDOUT) {
                    result = NPT_ERROR_TIMEOUT;
                    break;
                }
            }
            
            if (m_Aborting) {
                result = NPT_ERROR_INTERRUPTED;
                break;
            }
        }
    } else {
        result = m_Items.PopHead(item);
    }
    
    // wake up any thread that my be waiting to push
    if (m_MaxItems && (result == NPT_SUCCESS) && m_PushersWaitingCount) {
        pthread_cond_broadcast(&m_CanPushCondition);
    }

    // unlock the mutex
    pthread_mutex_unlock(&m_Mutex);
 
    return result;
}
Exemple #3
0
/*----------------------------------------------------------------------
|       NPT_PSPQueue::Pop
+---------------------------------------------------------------------*/
NPT_Result
NPT_PSPQueue::Pop(NPT_QueueItem*& item, NPT_Boolean blocking)
{
    // lock the mutex that protects the list
    m_Items.Lock();

    NPT_Result result;
    //if (blocking) {
    //    while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) {
    //        // no item in the list, wait for one
    //        //NPT_Debug(":: NPT_PSPQueue::Pop - waiting for queue to fill up\n");
    //        pthread_cond_wait(&m_CanPushOrPopCondition, &m_Mutex);
    //    }
    //} else {
        result = m_Items.PopHead(item);
    //}
    
    // if the list was previously full, signal the condition
    // to wake up the waiting thread
    //if (m_MaxItems && (result == NPT_SUCCESS)) {
    //    if (m_Items.GetItemCount() == m_MaxItems-1) {    
    //        pthread_cond_signal(&m_CanPushOrPopCondition);
    //    }
    //}

    // unlock the mutex
    m_Items.Unlock();
 
    return result;
}
/*----------------------------------------------------------------------
|   NPT_Win32Queue::Pop
+---------------------------------------------------------------------*/
NPT_Result
NPT_Win32Queue::Pop(NPT_QueueItem*& item, NPT_Timeout timeout)
{
    // default value
    item = NULL;

    // lock the mutex that protects the list
    NPT_CHECK(m_Mutex.Lock());

    NPT_Result result;
    if (timeout) {
        while ((result = m_Items.PopHead(item)) == NPT_ERROR_LIST_EMPTY) {
            // no item in the list, wait for one

            // reset the condition to indicate that the queue is empty
            m_CanPopCondition->Reset();

            // unlock the mutex so that another thread can push
            m_Mutex.Unlock();

            // wait for the condition to signal that we can pop
            NPT_Result result = m_CanPopCondition->Wait(timeout);
            if (NPT_FAILED(result)) return result;

            // relock the mutex so that we can check the list again
            NPT_CHECK(m_Mutex.Lock());
        }
    } else {
        result = m_Items.PopHead(item);
    }

    if (m_MaxItems && (result == NPT_SUCCESS)) {
        // wake up the threads waiting to push
        m_CanPushCondition->Signal();
    }

    // unlock the mutex
    m_Mutex.Unlock();

    return result;
}