ossrs / srs

SRS is a simple, high-efficiency, real-time video server supporting RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH, and GB28181.

Home Page:https://ossrs.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

KERNEL: Correctly using ST threads, an HTTP request shorter than 10 milliseconds may cause a segmentation fault.

winlinvip opened this issue · comments

If the thread is terminated immediately after creation, interrupt can still take effect, for example:

void* pfn(void* arg)
{
    trace("Enter thread, sleep.");
    st_sleep(10);
    trace("Quit thread.");
    return NULL;
}

    trace("Create thread.");
    st_thread_t trd = st_thread_create(pfn, NULL, 1, 0);
    trace("Interrupt thread.");
    st_thread_interrupt(trd);
    trace("Join thread.");
    st_thread_join(trd, NULL);
    trace("Thread done.");

Output:

[T][76189][2017-03-01 12:17:08.33] Create thread.
[T][76189][2017-03-01 12:17:08.33] Interrupt thread.
[T][76189][2017-03-01 12:17:08.33] Join thread.
[T][76189][2017-03-01 12:17:08.33] Enter thread, sleep.
[T][76189][2017-03-01 12:17:08.33] Quit thread.
[T][76189][2017-03-01 12:17:08.33] Thread done.

This indicates that the thread function pfn does not need to consider the situation of being terminated before it is started.

  1. After the thread is started, it enters a blocking state, and the function can also be interrupted by an interrupt.
void* pfn(void* arg)
{
    trace("Enter thread, sleep.");
    st_sleep(10);
    trace("Quit thread.");
    return NULL;
}

    trace("Create thread.");
    st_thread_t trd = st_thread_create(pfn, NULL, 1, 0);
    st_sleep(1);
    trace("Interrupt thread.");
    st_thread_interrupt(trd);
    trace("Join thread.");
    st_thread_join(trd, NULL);
    trace("Thread done.");

After 1 second, the interrupt function is called. At this time, the thread has already started and entered the waiting state. The interrupt is effective and the output is as follows:

[T][76286][2017-03-01 12:19:24.95] Create thread.
[T][76286][2017-03-01 12:19:24.95] Enter thread, sleep.
[T][76286][2017-03-01 12:19:25.95] Interrupt thread.
[T][76286][2017-03-01 12:19:25.95] Join thread.
[T][76286][2017-03-01 12:19:25.95] Quit thread.
[T][76286][2017-03-01 12:19:25.95] Thread done.

This indicates that if it is only an IO operation (without a loop), there is no need to use a state variable. It can be directly handled.

  1. If there is a loop inside the thread, such as a thread that receives messages, then a variable is needed.
void* pfn(void* arg)
{
    bool* loop = (bool*)arg;
    trace("Enter thread.");
    while (*loop) {
        trace("Thread sleep");
        st_sleep(10);
        trace("Thread aweak");
    }
    trace("Quit thread.");
    return NULL;
}

    trace("Create thread.");
    bool loop = true;
    st_thread_t trd = st_thread_create(pfn, &loop, 1, 0);
    st_sleep(1);
    trace("Interrupt thread.");
    loop = false;
    st_thread_interrupt(trd);
    trace("Join thread.");
    st_thread_join(trd, NULL);
    trace("Thread done.");

Under the influence of the variables "loop" and "interrupt", the thread exits normally, and the result is as follows:

[T][76401][2017-03-01 12:22:27.07] Create thread.
[T][76401][2017-03-01 12:22:27.07] Enter thread.
[T][76401][2017-03-01 12:22:27.07] Thread sleep
[T][76401][2017-03-01 12:22:28.07] Interrupt thread.
[T][76401][2017-03-01 12:22:28.07] Join thread.
[T][76401][2017-03-01 12:22:28.07] Thread aweak
[T][76401][2017-03-01 12:22:28.07] Quit thread.
[T][76401][2017-03-01 12:22:28.07] Thread done.

Based on the above considerations, the lifecycle of the ST thread can be simplified: link

TRANS_BY_GPT3