Search code examples
c++macospthreads

Is it possible to use thread_info() or pthread_mach_thread_np() to know if a thread has been terminated on OSX?


I am trying to implement something similar to pthread_tryjoin_np on OSX. For this purpose I need a reliable way to find if a pthreat_t has been terminated.

I found the mach_port API and I am wondering if I can use thread_info() for this usecase. https://www.gnu.org/software/hurd/gnumach-doc/Thread-Information.html

#include <mach/mach_init.h>
#include <mach/thread_act.h>
#include <mach/mach_port.h>

bool info_available(mach_port_t thread)
{
    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
    thread_basic_info_data_t info;
    kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count);
    if (kr == KERN_SUCCESS && (info.flags & TH_FLAGS_IDLE) == 0) {
        std::cout << "thread runnable state: " << info.run_state << std::endl;
        return true;
    }
    else 
    {
        std::cout << "invalid call to display info, thread might not be available: " << kr << std::endl;
        return false;
    }
}

void* thread_info_func(void *parameters)
{
    info_available(mach_thread_self());
    sleep(8);
    pthread_exit(NULL);
}

int main()
{
    pthread_t thread;
    pthread_attr_t thread_attr;
    pthread_attr_init(&thread_attr);
    
    int create_result = pthread_create(&thread, &thread_attr, thread_info_func, NULL);
    mach_port_t test_port = pthread_mach_thread_np(thread);

    // works display running 1 or waiting 3
    info_available(test_port);

    pthread_join(m_thread, NULL);
    
    // return 0, is is standard ? Is it reliable ?
    mach_port_t test_port = pthread_mach_thread_np(thread);
    // bool thread_terminated = test_port == MACH_PORT_NULL;

    // doesn't work, kr == KERN_INVALID_ARGUMENT
    info_available(test_port);

    // reliable ?
    // thread_terminated = !info_available();
}

thread_info() should return TH_STATE_HALTED if the thread has been terminated but I suppose it fails if the thread doesn't exist anymore. In my case thread_info exits with KERN_INVALID_ARGUMENT. Should it mean the thread doesn't exist anymore?

On a side note can pthread_mach_thread_np(thread) returning 0 also mean the thread has been terminated?


Solution

  • macOS has a function called pthread_getschedparam which takes a pthread_t as a parameter and returns an error (ESRCH) if the thread ID passed in doesn't represent a running thread.

    You still run the risk that the thread you're interested in has ended and a new one has been launched which winds up with the same thread ID. I don't know how quickly they are recycled so you'd have to run some tests to see how much of a problem this actually is in practise.