int mpsc_lock_free_queue_is_empty()

in src/mpsc_lock_free_queue.c [234:274]


int mpsc_lock_free_queue_is_empty(MPSC_LOCK_FREE_QUEUE_HANDLE mpsc_lock_free_queue, bool* is_empty)
{
    int result;

    if ((mpsc_lock_free_queue == NULL) ||
        (is_empty == NULL))
    {
        /* Codes_SRS_MPSC_LOCK_FREE_QUEUE_01_024: [ If mpsc_lock_free_queue or is_empty is NULL then mpsc_lock_free_queue_is_empty shall fail and return a non-zero value. ]*/
        LogError("Bad arguments: mpsc_lock_free_queue = %p, is_empty = %p",
            mpsc_lock_free_queue, is_empty);
        result = MU_FAILURE;
    }
    else
    {
        // it is assumed that destroy is not called concurrently with is_empty

        if (interlocked_compare_exchange_pointer((void* volatile_atomic*) &mpsc_lock_free_queue->dequeue_head, NULL, NULL) != NULL)
        {
            /* Codes_SRS_MPSC_LOCK_FREE_QUEUE_01_021: [ mpsc_lock_free_queue_is_empty shall set is_empty to false if at least one item is in the queue. ]*/
            *is_empty = false;
        }
        else
        {
            if (interlocked_compare_exchange_pointer((void* volatile_atomic*) &mpsc_lock_free_queue->enqueue_head, NULL, NULL) != NULL)
            {
                /* Codes_SRS_MPSC_LOCK_FREE_QUEUE_01_021: [ mpsc_lock_free_queue_is_empty shall set is_empty to false if at least one item is in the queue. ]*/
                *is_empty = false;
            }
            else
            {
                /* Codes_SRS_MPSC_LOCK_FREE_QUEUE_01_022: [ mpsc_lock_free_queue_is_empty shall set is_empty to true if no items are in the queue. ]*/
                *is_empty = true;
            }
        }

        /* Codes_SRS_MPSC_LOCK_FREE_QUEUE_01_023: [ On success it shall return 0. ]*/
        result = 0;
    }

    return result;
}