static ClRcT clJobQueuePushConditional(ClJobQueueT* hdl, ClCallbackT job, ClPtrT data, ClBoolT isEmpty)
{
    ClRcT rc = CL_OK;
    ClJobT* jb;

    if(!(hdl->flags & CreatedQueue)) return CL_JOBQUEUE_RC(CL_ERR_INVALID_STATE);

    JQ_PFX(hdl);

    if (!(hdl->flags & Running)) { rc = CL_JOBQUEUE_RC(CL_ERR_INVALID_STATE); goto out; }

    if(isEmpty)
    {
        ClUint32T queueSize = 0;
        (void)clQueueSizeGet(hdl->queue, &queueSize);
        if(queueSize) 
            goto out;
    }

    jb = getJob(hdl, job,data);
  
    if (!jb) { rc = CL_JOBQUEUE_RC(CL_ERR_NO_MEMORY); goto out; }

    rc = clQueueNodeInsert(hdl->queue,jb);

    if (rc != CL_OK) releaseJob(hdl,jb);
    else clTaskPoolWake(hdl->pool); /* Wake any idle pool tasks because there's work on the q (the idle callback handles the dequeuing) */
  
    out:
    JQ_SFX(hdl);
    return rc;
}
/*
 * clDispatchCbEnqueue enqueues the given callback data into the queue
 * associated with this particular registration of the dispatch library.
 * This API can be used by the service client to enqueue the callbacks,
 * and other thread can invoke clDispatchCbDispatch to dispatch the
 * enqueued callbacks.
 */
ClRcT   clDispatchCbEnqueue(
        CL_IN   ClHandleT           dispatchHandle,
        CL_IN   ClUint32T           callbackType,
        CL_IN   void*               callbackArgs)
{
    ClRcT   rc = CL_OK;
    ClDispatchDbEntryT* thisDbEntry = NULL;
    ClDispatchCbQueueDataT* queueData = NULL;
    ClCharT ch = pipeNotifyChar;

    CHECK_LIB_INIT;

    /* Checkout the handle */
    rc = clHandleCheckout(databaseHandle, dispatchHandle, (void *)&thisDbEntry);
    if (rc != CL_OK)
    {
        return CL_ERR_INVALID_HANDLE;
    }
    CL_ASSERT(thisDbEntry != NULL);

    /* Lock the mutex on the handle */
    rc = clOsalMutexLock(thisDbEntry->dispatchMutex);
    if (rc != CL_OK)
    {
        goto error_return;
    }

    /* Check if the handle is already finalized */
    if (thisDbEntry->shouldDelete == CL_TRUE)
    {
        clOsalMutexUnlock(thisDbEntry->dispatchMutex);
        rc = CL_ERR_INVALID_HANDLE;
        goto error_return;
    }

    queueData = clHeapAllocate(sizeof(ClDispatchCbQueueDataT));
    queueData->callbackType = callbackType;
    queueData->callbackArgs = callbackArgs;

    /* Insert the queue node */
    rc = clQueueNodeInsert(thisDbEntry->cbQueue,(ClQueueDataT)queueData);
    if (rc != CL_OK)
    {
        if (clOsalMutexUnlock(thisDbEntry->dispatchMutex) != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                    ("clOsalMutexUnlock failed"));
        }
        goto error_return;
    }

    /* 
     * Write a character into the pipe so that the reader thread is
     * awoken 
     */
    errno = 0;
    if (write(thisDbEntry->writeFd ,(void*)&ch, 1) < 0)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("write into pipe failed: %s",strerror(errno)));
        rc = CL_ERR_UNSPECIFIED;
        /* FIXME :Dequeue the last node inserted */

    }

    /* Unlock the mutex */
    if (clOsalMutexUnlock(thisDbEntry->dispatchMutex) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("clOsalMutexUnlock failed"));
    }

error_return:
    /* Checkin the handle */
    if ((clHandleCheckin(databaseHandle, dispatchHandle)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("clHandleCheckin failed"));
    }

    return rc;
}
static void*
tsTimerTask (void* pArgument)
{
    ClRcT returnCode = CL_ERR_INVALID_HANDLE;
    ClTimerTimeOutT sleepTime = {0,0};
    ClTimerTypeT type ;
    TsTimer_t* pUserTimer = NULL;

    sleepTime.tsSec = 0;
    sleepTime.tsMilliSec = gActiveTimerQueue.tickInMilliSec;

    while (1) {
        /* run forever */
        ClInt64T diff;
        ClUint32T skewTicks;
        ClUint32T skewTicksTemp;
        struct timeval start;
        struct timeval end;
        gettimeofday(&start,NULL);
        returnCode = clOsalTaskDelay (sleepTime);
        gettimeofday(&end,NULL);
        /*
         *  If this ever return CL_OSAL_ERR_OS_ERROR, it means that gOsalFunction
         *  is un-initialized or been finalized. In case of finalized we can
         *  simply return from this thread. Ideally clOsalTaskDelay should
         *  not be used here. a better approach would be pthread_cond_timedwait.
         *  but right now this is the temporary stuff which will work
         */
        if(CL_GET_ERROR_CODE(returnCode) == CL_OSAL_ERR_OS_ERROR &&
                CL_GET_CID(returnCode) == CL_CID_OSAL)
        {
            break;
        }

        diff = clTimerTimeDiff(&start,&end,CL_TIMER_DRIFT_THRESHOLD);

        if(diff < CL_TIMER_TICK_USECS)
        {
            skewTicks = 1;
            diff = 0;
        }
        else
        {
            skewTicks = diff/CL_TIMER_TICK_USECS;
        }

        returnCode = clOsalMutexLock (gActiveTimerQueue.timerMutex);

        if (returnCode != CL_OK) {
            continue;
        }

        skewTicksTemp = skew/(iteration+1);

        skew += skewTicksTemp % CL_TIMER_TICK_USECS;

        skewTicksTemp/=CL_TIMER_TICK_USECS;

        skew += diff % CL_TIMER_TICK_USECS;

        skewTicks += skewTicksTemp;

        ++iteration;

        if(currentTime > currentTime+iteration+skewTicks)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Timer overflow detected.Exiting timer\n"));
            clOsalMutexUnlock(gActiveTimerQueue.timerMutex);
            break;
        }

        currentTime += skewTicks;

        if (gActiveTimerQueue.pFirstTimer == NULL) {
            returnCode = clOsalMutexUnlock (gActiveTimerQueue.timerMutex);
            continue;
        }

        if( (gActiveTimerQueue.pFirstTimer->timestamp > currentTime))
        {

        }
        else {
            gettimeofday(&start,NULL);
            for (pUserTimer = gActiveTimerQueue.pFirstTimer;
                    (pUserTimer != NULL) && (pUserTimer->timestamp <= currentTime);
                    pUserTimer = pUserTimer->pNextActiveTimer) {

                /* first remove the timer from the active queue */
                returnCode = tsActiveTimerDequeue (pUserTimer);

                /* check that the timer we are about to execute is valid */
                if ((pUserTimer->state != TIMER_ACTIVE) ||
                        (pUserTimer->fpTimeOutAction == NULL)) {
                    continue;
                } /* end of check to ensure that the timer we are about to execute is valid */

                if((type = pUserTimer->type) == CL_TIMER_ONE_SHOT)
                {
                    /* make the timer state as inactive if its a one-shot timer */
                    pUserTimer->state = TIMER_INACTIVE;
                }
                switch (pUserTimer->spawnTask) {
                case CL_TIMER_SEPARATE_CONTEXT:
                    /* spawn off a task to run the timer function */
                    returnCode = clOsalTaskCreateDetached ("USER TIMER TASK",
                                                           CL_OSAL_SCHED_OTHER,
                                                           CL_OSAL_THREAD_PRI_NOT_APPLICABLE,
                                                           TIMER_TASK_STACK_SIZE,
                                                           (void* (*) (void*)) pUserTimer->fpTimeOutAction,
                                                           pUserTimer->pActionArgument);

                    if (returnCode != CL_OK) {
                        /* do the appropriate thing here */
                        break;
                    }
                    break;

                case CL_TIMER_TASK_CONTEXT:
                    returnCode = pUserTimer->fpTimeOutAction (pUserTimer->pActionArgument);
                    break;

                default:
                    /* this should never happen! we should have verified this
                     * in create/newTimerActivate
                     */
                    break;
                }

                if (type == CL_TIMER_REPETITIVE) {

                    /* put the current time into this timer's timestamp */
                    pUserTimer->timestamp = currentTime+pUserTimer->timeInterval;

                    /* This timer needs to fire again. So put into re-enqueue Queue */
                    returnCode = clQueueNodeInsert(gActiveTimerQueue.reEnqueueQueue,
                                                   pUserTimer);

                    if (returnCode != CL_OK) {
                        /* do the appropriate thing here */
                        break;
                    }

                }

            } /* end of for (all timers with 0 expiry time) loop */
            gettimeofday(&end,NULL);

            skew += clTimerTimeDiff(&start,&end,CL_TIMER_DRIFT_THRESHOLD);

        } /* end of else: so there are expired timers */

        tsTimerReEnqueue();

        returnCode = clOsalMutexUnlock (gActiveTimerQueue.timerMutex);

    } /* end of while (1) */

    return (NULL);
}