| 106 | } |
| 107 | |
| 108 | int thread_key_delete(ThreadKey& thread_key) { |
| 109 | if (BAIDU_UNLIKELY(!thread_key.Valid())) { |
| 110 | return EINVAL; |
| 111 | } |
| 112 | |
| 113 | BAIDU_SCOPED_LOCK(g_thread_key_mutex); |
| 114 | size_t id = thread_key._id; |
| 115 | size_t seq = thread_key._seq; |
| 116 | if (id >= g_thread_keys->size() || |
| 117 | seq != (*g_thread_keys)[id].seq || |
| 118 | KEY_UNUSED((*g_thread_keys)[id].seq)) { |
| 119 | thread_key.Reset(); |
| 120 | return EINVAL; |
| 121 | } |
| 122 | |
| 123 | ++((*g_thread_keys)[id].seq); |
| 124 | // Collect the usable key id for reuse. |
| 125 | if (KEY_USABLE((*g_thread_keys)[id].seq)) { |
| 126 | g_free_ids->push_back(id); |
| 127 | } |
| 128 | thread_key.Reset(); |
| 129 | |
| 130 | return 0; |
| 131 | } |
| 132 | |
| 133 | int thread_setspecific(ThreadKey& thread_key, void* data) { |
| 134 | if (BAIDU_UNLIKELY(!thread_key.Valid())) { |