Skip to content

shutdown issue with ristsender wrt pthread version

To get a feel for this library I played around with the wiki examples building a simple chain:

  • generate UDP stream
  • feed stream to ristsender and generate a rist stream
  • back to UDP with ristreceiver
  • display UDP

Works fine. Problem occurred when I shutdown ristsender (core dump). Turns out that the thread_started array holds too many entries set to true which then causes potentially invalid thread_main_loop entries passed to pthread_join(). I came across different versions of libpthread being used. Some accept 0 as a valid handle (but flagging it as unused) others can't cope and go down with a core dump. ristsender.c around line 913:

for (size_t i = 0; i < MAX_INPUT_COUNT; i++) {
    if (((rist_listens && i == 0) || !rist_listens) &&
         callback_object[i].sender_ctx && rist_start(callback_object[i].sender_ctx) == -1) {
        rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start rist sender\n");
        goto shutdown;
    }
    if (callback_object[i].receiver_ctx && rist_start(callback_object[i].receiver_ctx) == -1) {
        rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start rist receiver\n");
        goto shutdown;
    }
    if (callback_object[i].receiver_ctx && pthread_create(&thread_main_loop[i+1], NULL, input_loop, (void *)callback_object) != 0)
    {
        rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start send rist receiver thread\n");
        goto shutdown;
    }
    thread_started[i+1] = true;
}

As you can see here, the thread_started entries are set regardless of whether the threads are in fact started (receiver_ctx = false). A minor restructuring can resolve this.

for (size_t i = 0; i < MAX_INPUT_COUNT; i++) {
    if (((rist_listens && i == 0) || !rist_listens) &&
         callback_object[i].sender_ctx && rist_start(callback_object[i].sender_ctx) == -1) {
        rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start rist sender\n");
        goto shutdown;
    }
    if (callback_object[i].receiver_ctx) {
        if (rist_start(callback_object[i].receiver_ctx) == -1) {
            rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start rist receiver\n");
            goto shutdown;
        }
        if (pthread_create(&thread_main_loop[i+1], NULL, input_loop, (void *)callback_object) != 0) {
            rist_log(&logging_settings, RIST_LOG_ERROR, "Could not start rist receiver thread\n");
            goto shutdown;
        }
        thread_started[i+1] = true;
    }
}