| 158 | } |
| 159 | |
| 160 | ~KeyTable() { |
| 161 | nkeytable.fetch_sub(1, butil::memory_order_relaxed); |
| 162 | for (int ntry = 0; ntry < PTHREAD_DESTRUCTOR_ITERATIONS; ++ntry) { |
| 163 | for (uint32_t i = 0; i < KEY_1STLEVEL_SIZE; ++i) { |
| 164 | if (_subs[i]) { |
| 165 | _subs[i]->clear(i * KEY_2NDLEVEL_SIZE); |
| 166 | } |
| 167 | } |
| 168 | bool all_cleared = true; |
| 169 | for (uint32_t i = 0; i < KEY_1STLEVEL_SIZE; ++i) { |
| 170 | if (_subs[i] != NULL && !_subs[i]->cleared()) { |
| 171 | all_cleared = false; |
| 172 | break; |
| 173 | } |
| 174 | } |
| 175 | if (all_cleared) { |
| 176 | for (uint32_t i = 0; i < KEY_1STLEVEL_SIZE; ++i) { |
| 177 | delete _subs[i]; |
| 178 | } |
| 179 | return; |
| 180 | } |
| 181 | } |
| 182 | LOG(ERROR) << "Fail to destroy all objects in KeyTable[" << this << ']'; |
| 183 | } |
| 184 | |
| 185 | inline void* get_data(bthread_key_t key) const { |
| 186 | const uint32_t subidx = key.index / KEY_2NDLEVEL_SIZE; |