zach zach - 10 months ago 45
C++ Question

why "boost.thread" call "intrusive_ptr_add_ref" manually?

In boost.thread's start function, the source code is something like that:

bool thread::start_thread_noexcept()
uintptr_t const new_thread = _beginthreadex(

if (!new_thread)
return false;

// why call this line?

thread_info->thread_handle = (detail::win32::handle)(new_thread);
return true;

thread_info is a intrusive smart pointer which points to the thread information data, before calling the intrusive_ptr_add_ref, the count is already 1, I don't know why call the intrusive_ptr_add_ref mannually here. I think Intrusive smart pointer's job should be calling the intrusive_ptr_add_ref and intrusive_ptr_release automatically.

I've tried to step through the source code but didn't find any clue.

Can anyone tell me
1. why call intrusive_ptr_add_ref manually here?
2. In what condition when using the intrusive_ptr, I should call intrusive_ptr_add_ref manually?

Thanks, Sincerely.


why call intrusive_ptr_add_ref manually here?

To represent the sharing of ownership of the pointer.

_beginthreadex was passed thread_info.get() as a parameter. This parameter will be passed to thread_start_function when the thread starts. And this function expects the pointer to remain valid until that happens.

Now, _beginthreadex is a simple function. It's not a variadic template that can take arbitrary parameters or anything. It takes exactly and only a naked pointer, and passes exactly that to the start function.

It is very possible for the person creating the boost::thread to call thread::detach before thread_start_function ever gets called. And if that happened, then the thread_info intrusive pointer would be destroyed, thus causing the destruction of its contained object.

And that leaves _beginthreadex with a destroyed pointer. That's bad.

What _beginthreadex needs to do is claim ownership of the intrusvie pointer. But since the API doesn't take a boost::intrusive_ptr, how do you do that?

By bumping the reference count. The reference count increase is how _beginthreadex claims ownership of the object.