COMPLETION_PORT_HANDLE completion_port_create()

in linux/src/completion_port_linux.c [201:250]


COMPLETION_PORT_HANDLE completion_port_create(void)
{
    COMPLETION_PORT_HANDLE result;

    // Codes_SRS_COMPLETION_PORT_LINUX_11_001: [ completion_port_create shall allocate memory for a completion port object. ]
    result = REFCOUNT_TYPE_CREATE(COMPLETION_PORT);
    if (result == NULL)
    {
        LogError("failure REFCOUNT_TYPE_CREATE completion port");
    }
    else
    {
        (void)interlocked_exchange(&result->worker_thread_continue, 0);
        (void)interlocked_exchange(&result->recv_data_access, 0);
        (void)interlocked_exchange(&result->pending_calls, 0);

        if (s_list_initialize(&result->alloc_data_list) != 0)
        {
            LogError("failure initializing recv list");
        }
        else
        {
            // Codes_SRS_COMPLETION_PORT_LINUX_11_002: [ completion_port_create shall create the epoll instance by calling epoll_create. ]
            result->epoll = epoll_create(MAX_EVENTS_NUM);
            if (result->epoll == -1)
            {
                LogErrorNo("failure epoll_create MAX_EVENTS_NUM: %d", MAX_EVENTS_NUM);
            }
            else
            {
                // Codes_SRS_COMPLETION_PORT_LINUX_11_003: [ completion_port_create shall create a thread that runs epoll_worker_func to handle the epoll events. ]
                if (ThreadAPI_Create(&result->thread_handle, epoll_worker_func, result) != THREADAPI_OK)
                {
                    LogCritical("Failure creating thread");
                }
                else
                {
                    // Codes_SRS_COMPLETION_PORT_LINUX_11_004: [ On success completion_port_create shall return the allocated COMPLETION_PORT_HANDLE. ]
                    goto all_ok;
                }
            }
            (void)close(result->epoll);
        }
        // Codes_SRS_COMPLETION_PORT_LINUX_11_005: [ If there are any errors then completion_port_create shall fail and return NULL. ]
        REFCOUNT_TYPE_DESTROY(COMPLETION_PORT, result);
        result = NULL;
    }
all_ok:
    return result;
}