int clds_singly_linked_list_insert()

in src/clds_singly_linked_list.c [308:352]


int clds_singly_linked_list_insert(CLDS_SINGLY_LINKED_LIST_HANDLE clds_singly_linked_list, CLDS_HAZARD_POINTERS_THREAD_HANDLE clds_hazard_pointers_thread, CLDS_SINGLY_LINKED_LIST_ITEM* item)
{
    int result;

    (void)clds_hazard_pointers_thread;

    if (
        /* Codes_SRS_CLDS_SINGLY_LINKED_LIST_01_011: [ If clds_singly_linked_list is NULL, clds_singly_linked_list_insert shall fail and return a non-zero value. ]*/
        (clds_singly_linked_list == NULL) ||
        /* Codes_SRS_CLDS_SINGLY_LINKED_LIST_01_012: [ If item is NULL, clds_singly_linked_list_insert shall fail and return a non-zero value. ]*/
        (item == NULL) ||
        /* Codes_SRS_CLDS_SINGLY_LINKED_LIST_01_013: [ If clds_hazard_pointers_thread is NULL, clds_singly_linked_list_insert shall fail and return a non-zero value. ]*/
        (clds_hazard_pointers_thread == NULL)
        )
    {
        LogError("Invalid arguments: CLDS_SINGLY_LINKED_LIST_HANDLE clds_singly_linked_list=%p, CLDS_HAZARD_POINTERS_THREAD_HANDLE clds_hazard_pointers_thread=%p, CLDS_SINGLY_LINKED_LIST_ITEM* item=%p",
            clds_singly_linked_list, clds_hazard_pointers_thread, item);
        result = MU_FAILURE;
    }
    else
    {
        bool restart_needed;

        do
        {
            // get current head
            /* Codes_SRS_CLDS_SINGLY_LINKED_LIST_01_009: [ clds_singly_linked_list_insert inserts an item in the list. ]*/
            item->next = interlocked_compare_exchange_pointer((void* volatile_atomic*)&clds_singly_linked_list->head, NULL, NULL);

            if (interlocked_compare_exchange_pointer((void* volatile_atomic*)&clds_singly_linked_list->head, item, (void*)item->next) != item->next)
            {
                restart_needed = true;
            }
            else
            {
                restart_needed = false;
            }
        } while (restart_needed);

        /* Codes_SRS_CLDS_SINGLY_LINKED_LIST_01_010: [ On success clds_singly_linked_list_insert shall return 0. ]*/
        result = 0;
    }

    return result;
}