Esempio n. 1
0
//--------------------------------------------------------------------------------------------------
le_result_t le_media_PlayDtmf
(
    le_audio_Stream_t*   streamPtr, ///< [IN] Stream object
    const char*          dtmfPtr,   ///< [IN] The DTMFs to play.
    uint32_t             duration,  ///< [IN] The DTMF duration in milliseconds.
    uint32_t             pause      ///< [IN] The pause duration between tones in milliseconds.
)
{
    le_result_t       res;
    DtmfThreadCtx_t*  threadCtxPtr = le_mem_ForceAlloc(DtmfThreadContextPool);

    memset(threadCtxPtr, 0, sizeof(DtmfThreadCtx_t));

    streamPtr->samplePcmConfig.sampleRate = 16000;
    streamPtr->samplePcmConfig.bitsPerSample = 16;
    streamPtr->samplePcmConfig.channelsCount = 1;
    streamPtr->samplePcmConfig.fileSize = -1;
    streamPtr->samplePcmConfig.pcmFormat = PCM_RAW;

    threadCtxPtr->duration = duration;
    threadCtxPtr->pause = pause;
    threadCtxPtr->sampleRate = 16000;
    threadCtxPtr->dtmfPtr = dtmfPtr;
    if (pipe(threadCtxPtr->pipefd) == -1)
    {
        LE_ERROR("Failed to create the pipe");
        le_mem_Release(threadCtxPtr);
        return LE_FAULT;
    }

    streamPtr->fd = threadCtxPtr->pipefd[0];

    if ((res=pa_audio_PlaySamples(streamPtr->audioInterface,
                                  streamPtr->fd,
                                  &streamPtr->samplePcmConfig)) == LE_OK)
    {
        LE_INFO("Spawn DTMF thread");
        if (DtmfTreadRef == NULL)
        {
            DtmfTreadRef = le_thread_Create("PlayDtmfs", PlayDtmfThread, threadCtxPtr);

            le_thread_AddChildDestructor(DtmfTreadRef,
                                        DestroyPlayDtmfThread,
                                        threadCtxPtr);

            le_thread_Start(DtmfTreadRef);
        }
    }
    else
    {
        le_mem_Release(threadCtxPtr);
        LE_ERROR("Cannot spawn DTMF thread!");
    }

    return res;
}
Esempio n. 2
0
// -------------------------------------------------------------------------------------------------
static void SpawnChildren
(
    size_t depth,           // Indicates what nesting level the thread is at.
                            // 1 = children of the process main thread.

    void*  completionObjPtr // Ptr to the object whose ref count is used to terminate the test.
)
// -------------------------------------------------------------------------------------------------
{
    int i;
    char childName[32];
    le_thread_Ref_t children[FAN_OUT];

    // Create and start all the children.
    for (i = 0; i < FAN_OUT; i++)
    {
        le_thread_Ref_t threadRef;

        Context_t* contextPtr = le_mem_ForceAlloc(ContextPoolRef);
        contextPtr->depth = depth;
        contextPtr->completionObjPtr = completionObjPtr;
        le_mem_AddRef(completionObjPtr);

        snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1);

        LE_INFO("Spawning thread '%s'.", childName);

        threadRef = le_thread_Create(childName, ThreadMainFunction, contextPtr);

        LE_INFO("Thread '%s' created.", childName);

        // Create a thread destructor that will release the Context object and the
        // Test Completion Object that we are going to pass to the child.
        le_thread_AddChildDestructor(threadRef, ThreadDestructor, contextPtr);

        LE_INFO("Thread '%s' destructor added.", childName);

        // Make every third child thread non-joinable and the rest joinable.
        if (((i + 1) % 3) != 0)
        {
            le_thread_SetJoinable(threadRef);
        }

        LE_INFO("Thread '%s' joinability set.", childName);

        // Start the child thread.
        le_thread_Start(threadRef);

        LE_INFO("Thread '%s' started.", childName);

        // Remember the child's thread reference for later join attempt.
        children[i] = threadRef;
    }

    // Join with all the children.
    for (i = 0; i < FAN_OUT; i++)
    {
        void* threadReturnValue;

        snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1);
        LE_INFO("Joining with thread '%s'.", childName);

        le_result_t result = le_thread_Join(children[i], &threadReturnValue);

        if (result != LE_OK)
        {
            LE_INFO("Failed to join with thread '%s'.", childName);
            LE_FATAL_IF(((i + 1) % 3) != 0, "Failed to join with joinable thread '%s'!", childName);
        }
        else
        {
            LE_INFO("Successfully joined with thread '%s', which returned %p.",
                    childName,
                    threadReturnValue);
            LE_FATAL_IF(((i + 1) % 3) == 0, "Joined with non-joinable thread '%s'!", childName);
            LE_FATAL_IF(threadReturnValue != completionObjPtr,
                        "Thread returned strange value %p.  Expected %p.",
                        threadReturnValue,
                        completionObjPtr);
        }
    }
}
Esempio n. 3
0
// -------------------------------------------------------------------------------------------------
static void SpawnChildren
(
    size_t depth            // Indicates what nesting level the thread is at.
                            // 1 = children of the process main thread.
)
// -------------------------------------------------------------------------------------------------
{
    int i, j, k;
    char childName[32];
    le_thread_Ref_t children[FAN_OUT];
    const char* threadName = le_thread_GetMyName();

    if (depth == 2)
    {
        LE_ASSERT(sscanf(threadName, "%*[^-]-%d", &j) == 1);
        // switch to zero-based
        j--;
        LE_TEST_INFO("depth 2: j=%d", j);
    }
    else if (depth == 3)
    {
        LE_ASSERT(sscanf(threadName, "%*[^-]-%d-%d", &k, &j) == 2);
        // switch to zero based
        k--;
        j--;
        LE_TEST_INFO("depth 3: j=%d,k=%d", j, k);
    }

    // Create and start all the children.
    for (i = 0; i < FAN_OUT; i++)
    {
        le_thread_Ref_t threadRef;

        Context_t* contextPtr = le_mem_ForceAlloc(ContextPoolRef);
        contextPtr->depth = depth;

        int item = 0;
        if (depth == 1)
        {
            item = i*(FAN_OUT+1)*(FAN_OUT+1);
        }
        if (depth == 2)
        {
            item = (j*(FAN_OUT+1)+(i+1))*(FAN_OUT+1);
        }
        else if (depth == 3)
        {
            item = (k*(FAN_OUT+1) + (j+1))*(FAN_OUT+1) + (i+1);
        }
        if (item >= FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1))
        {
            LE_TEST_FATAL("Result index %d outside test result array size %d!",
                item, FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1));
        }

        snprintf(childName, sizeof(childName), "%s-%d", threadName, i + 1);
        LE_TEST_INFO("Spawning thread '%s' (item %d).", childName, item);

        threadRef = le_thread_Create(childName, ThreadMainFunction, contextPtr);

        TestResults[item].createOk = !!threadRef;

        // Create a thread destructor that will release the Context object and the
        // Test Completion Object that we are going to pass to the child.
        le_thread_AddChildDestructor(threadRef, ThreadDestructor, contextPtr);

        LE_TEST_INFO("Thread '%s' destructor added.", childName);

        // Make every third leaf thread non-joinable and the rest joinable.
        // Non-leaves must be joinable to ensure join
        if (IsThreadJoinable(depth, i))
        {
            le_thread_SetJoinable(threadRef);
            LE_TEST_INFO("Thread '%s' joinability set.", childName);
        }


        // Start the child thread.
        le_thread_Start(threadRef);

        LE_TEST_INFO("Thread '%s' started.", childName);

        // Remember the child's thread reference for later join attempt.
        children[i] = threadRef;
    }

    // Join with all the children.
    for (i = 0; i < FAN_OUT; i++)
    {
        void* threadReturnValue;
        int item = 0;
        if (depth == 1)
        {
            item = i*(FAN_OUT+1)*(FAN_OUT+1);
        }
        if (depth == 2)
        {
            item = (j*(FAN_OUT+1)+(i+1))*(FAN_OUT+1);
        }
        else if (depth == 3)
        {
            item = (k*(FAN_OUT+1)+(j+1))*(FAN_OUT+1) + (i+1);
        }
        if (item >= FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1))
        {
            LE_TEST_FATAL("Result index %d outside test result array size %d!",
                item, FAN_OUT*(FAN_OUT+1)*(FAN_OUT+1));
        }

        snprintf(childName, sizeof(childName), "%s-%d", le_thread_GetMyName(), i + 1);

        if (IsThreadJoinable(depth, i))
        {
            le_result_t result = le_thread_Join(children[i], &threadReturnValue);
            TestResults[item].joinOk = (result == LE_OK);

            if (result != LE_OK)
            {
                LE_TEST_INFO("Failed to join with thread '%s'.", childName);
            }
            else
            {
                LE_TEST_INFO("Successfully joined with thread '%s', which returned %p.",
                             childName,
                             threadReturnValue);
                TestResults[item].expectedJoin = (void*)depth;
                TestResults[item].actualJoin = threadReturnValue;
            }
        }
        else
        {
            // Do not try to join non-joinable threads.  Result is undefined as thread
            // could have exited in the meantime and been recycled.
            TestResults[item].joinOk = false;
        }
    }
}