Commit 54bfa36a authored by Davis King's avatar Davis King

Added the unregister_thread_end_handler() function and also used it to

fix a bug that can trigger when the thread_specific_data object is destructed.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402483
parent 66a3e292
......@@ -31,6 +31,9 @@ namespace dlib
~thread_specific_data (
)
{
unregister_thread_end_handler(const_cast<thread_specific_data&>(*this),&thread_specific_data::thread_end_handler);
auto_mutex M(m);
items.reset();
while (items.move_next())
{
......@@ -94,8 +97,11 @@ namespace dlib
thread_id_type junk;
T* item;
auto_mutex M(m);
items.remove(id,junk,item);
delete item;
if (items[id])
{
items.remove(id,junk,item);
delete item;
}
}
mutable typename binary_search_tree<thread_id_type,T*>::kernel_2a items;
......
......@@ -113,6 +113,26 @@ namespace dlib
If this exception is thrown then the call to this function had no effect.
!*/
// ----------------------------------------------------------------------------------------
template <
typename T
>
void unregister_thread_end_handler (
T& obj,
void (T::*handler)()
);
/*!
requires
- handler == a valid member function pointer for class T
ensures
- Undoes all previous calls to register_thread_end_handler(obj,handler).
So the given handler won't be called when any threads end.
throws
- std::bad_alloc
If this exception is thrown then the call to this function had no effect.
!*/
// ----------------------------------------------------------------------------------------
template <
......
......@@ -81,6 +81,32 @@ namespace dlib
void* param
);
template <
typename T
>
void unregister_thread_end_handler (
T& obj,
void (T::*handler)()
)
{
member_function_pointer<>::kernel_1a mfp, junk_mfp;
mfp.set(obj,handler);
thread_id_type junk_id;
// find any member function pointers in the registry that point to the same
// thing as mfp and remove them
auto_mutex M(reg.m);
reg.reg.reset();
while (reg.reg.move_next())
{
while (reg.reg.current_element_valid() && reg.reg.element().value() == mfp)
{
reg.reg.remove_current_element(junk_id, junk_mfp);
}
}
}
template <
typename T
>
......@@ -202,6 +228,19 @@ namespace dlib
threads_kernel_shared::thread_pool().register_thread_end_handler(obj,handler);
}
// ----------------------------------------------------------------------------------------
template <
typename T
>
inline void unregister_thread_end_handler (
T& obj,
void (T::*handler)()
)
{
threads_kernel_shared::thread_pool().unregister_thread_end_handler(obj,handler);
}
// ----------------------------------------------------------------------------------------
template <
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment