A race condition could occur between the pthread_key_delete() and the __nptl_deallocate_tsd().
For instance, __nptl_deallocate_tsd() could call a destructor for the key, immediately before the pthread_key_delete() invalidates it (from an another thread), and will continue destructor execution after the completion of pthread_key_delete().
From a user code this looks as if the corresponding destructor executes after the key has been removed by pthread_key_delete(), and there is no way to know whether was destructor called/executed or not.
Suggest add pthread_rwlock_rdlock() for __nptl_deallocate_tsd() and pthread_rwlock_wrlock() for pthread_key_delete().
Related to bugs 18136, 21032.