ClRcT clJobQueueInit(ClJobQueueT* hdl, ClUint32T maxJobs, ClUint32T maxTasks)
{
    ClRcT rc;
    hdl->flags = 0;
    hdl->queue = 0;
    hdl->pool  = 0;

    rc = clOsalMutexInit(&hdl->mutex);
    if (rc != CL_OK) goto error;

    rc = clQueueCreate(maxJobs, deleteCallback, deleteCallback, &hdl->queue);
    if (rc != CL_OK) goto error;

    rc = clTaskPoolCreate(&hdl->pool, maxTasks, clJobQueuePreIdle, hdl);
    if (rc != CL_OK) goto error;

    hdl->flags |= CreatedQueue | CreatedPool | Running;
    return CL_OK;  

    error:
    clOsalMutexDestroy(&hdl->mutex);
    if (hdl->pool) clTaskPoolDelete(hdl->pool);
    if (hdl->queue) clQueueDelete(&hdl->queue);

    hdl->queue = 0;
    hdl->pool  = 0;
    return rc;
}
ClRcT   clDispatchRegister(
        CL_OUT  ClHandleT*                      pDispatchHandle,
        CL_IN   ClHandleT                       svcInstanceHandle,
        CL_IN   ClDispatchCallbackT             wrapperCallback,
        CL_IN   ClDispatchQueueDestroyCallbackT queueDestroyCallback)
{
    ClRcT   rc = CL_OK;
    ClDispatchDbEntryT* thisDbEntry = NULL;
    ClFdT   fds[2] = {0};

    if (svcInstanceHandle == CL_HANDLE_INVALID_VALUE)
    {
        return CL_ERR_INVALID_PARAMETER;
    }

    if ((wrapperCallback == NULL) || (pDispatchHandle == NULL))
    {
        return CL_ERR_NULL_POINTER;
    }

    CHECK_LIB_INIT;

    /* Create the handle for this initialization of the library */
    rc = clHandleCreate (databaseHandle,
                         sizeof(ClDispatchDbEntryT),
                         pDispatchHandle);
    if (rc != CL_OK)
    {
        return rc;
    }
    CL_ASSERT (*pDispatchHandle != CL_HANDLE_INVALID_VALUE);

    /* Checkout the handle */
    rc = clHandleCheckout(databaseHandle, *pDispatchHandle, (void *)&thisDbEntry);

    if (rc != CL_OK)
    {
        return rc;
    }
    CL_ASSERT (thisDbEntry != NULL);

    /* Store SVC instance handle */
    thisDbEntry->svcInstanceHandle = svcInstanceHandle;
    thisDbEntry->svcCallback = wrapperCallback;
    thisDbEntry->queueDestroyCallback = queueDestroyCallback;

    /* Create the queue */
    rc = clQueueCreate(0x0,
                       clDispatchQueueDequeueCallback,
                       clDispatchQueueDestroyCallback,
                       &thisDbEntry->cbQueue);
    if (rc != CL_OK)
    {
        goto error_return;
    }

    /* Create Mutex to protect the queue */
    rc = clOsalMutexCreate(&thisDbEntry->dispatchMutex);
    if (rc != CL_OK)
    {
        goto error_return;
    }

    errno = 0;
    /* Create the pipe */
    ClInt32T ec = pipe(fds); // since return code for system call can be -ve
    if (ec < 0)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("Unable to create pipe: %s",strerror(errno)));
        rc = CL_ERR_LIBRARY;
        goto error_return;
    }
    /* 
     * Reinitialize rc to CL_OK as it would have changed with
     * above assignment
     */
    rc = CL_OK;

    thisDbEntry->readFd = fds[0];
    thisDbEntry->writeFd = fds[1];

    thisDbEntry->shouldDelete = CL_FALSE;

error_return:
    if ((clHandleCheckin(databaseHandle, *pDispatchHandle)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("clHandleCheckin failed"));
    }
    return rc;
}
ClRcT
clTimerInitialize (ClPtrT pConfig)
{
    ClRcT returnCode = CL_ERR_INVALID_HANDLE;

    CL_FUNC_ENTER();
    /* TBD: check whether the OSAL has been initialized before going ahead with Timer init */
    returnCode = clOsalInitialize(NULL);
    if(CL_OK != returnCode) {
        CL_FUNC_EXIT();
        return(returnCode);
    }

    if (gActiveTimerQueue.timerServiceInitialized == 1) {
        CL_FUNC_EXIT();
        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nTimer already initialized"));
        return (CL_OK);
    }

#ifdef DEBUG
    returnCode= dbgAddComponent (COMP_PREFIX, COMP_NAME, COMP_DEBUG_VAR_PTR);
    if (CL_OK != returnCode)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("dbgAddComponent Failed \n "));
        CL_FUNC_EXIT();
        return (returnCode);
    }
#endif

    /* create a pool of free timers */
    returnCode = tsFreeTimersPoolCreate ();

    if (returnCode != CL_OK) {

        CL_DEBUG_PRINT (CL_DEBUG_ERROR,("\nTimer Init : NOT DONE"));
        CL_FUNC_EXIT();
        return (CL_ERR_UNSPECIFIED);
    }

    /* create the active timers queue */
    returnCode = tsActiveTimersQueueCreate ();

    if (returnCode != CL_OK) {
        /* debug message */
        returnCode = tsFreeTimersPoolDestroy ();
        CL_DEBUG_PRINT (CL_DEBUG_ERROR,("\nTimer Init : NOT DONE"));
        CL_FUNC_EXIT();
        return (CL_ERR_UNSPECIFIED);
    }

    /* create re-enqueue Queue */
    returnCode = clQueueCreate(0,
                               deQueueCallBack,
                               deQueueCallBack,
                               &(gActiveTimerQueue.reEnqueueQueue));

    if (returnCode != CL_OK) {
        /* debug message */
        returnCode = tsFreeTimersPoolDestroy ();
        returnCode = tsActiveTimersQueueDestroy ();
        CL_DEBUG_PRINT (CL_DEBUG_ERROR,("\nTimer Init : NOT DONE"));
        CL_FUNC_EXIT();
        return (CL_ERR_UNSPECIFIED);
    }

    CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nTimer Init : DONE"));
    CL_FUNC_EXIT();
    return (CL_OK);
}