* tsd_destroy - destroy thread specific data * @keyp: lookup key address * * Destroys the thread specific data on all threads which use this key. * * Caller must prevent racing tsd_set() or tsd_get(), this function is * safe from racing tsd_create(), tsd_destroy(), and tsd_exit(). */
| 585 | * safe from racing tsd_create(), tsd_destroy(), and tsd_exit(). |
| 586 | */ |
| 587 | void |
| 588 | tsd_destroy(uint_t *keyp) |
| 589 | { |
| 590 | HLIST_HEAD(work); |
| 591 | tsd_hash_table_t *table; |
| 592 | tsd_hash_entry_t *dtor_entry, *entry; |
| 593 | tsd_hash_bin_t *dtor_entry_bin, *entry_bin; |
| 594 | ulong_t hash; |
| 595 | |
| 596 | table = tsd_hash_table; |
| 597 | ASSERT3P(table, !=, NULL); |
| 598 | |
| 599 | spin_lock(&table->ht_lock); |
| 600 | dtor_entry = tsd_hash_search(table, *keyp, DTOR_PID); |
| 601 | if (dtor_entry == NULL) { |
| 602 | spin_unlock(&table->ht_lock); |
| 603 | return; |
| 604 | } |
| 605 | |
| 606 | /* |
| 607 | * All threads which use this key must be linked off of the |
| 608 | * DTOR_PID entry. They are removed from the hash table and |
| 609 | * linked in to a private working list to be destroyed. |
| 610 | */ |
| 611 | while (!list_empty(&dtor_entry->he_key_list)) { |
| 612 | entry = list_entry(dtor_entry->he_key_list.next, |
| 613 | tsd_hash_entry_t, he_key_list); |
| 614 | ASSERT3U(dtor_entry->he_key, ==, entry->he_key); |
| 615 | ASSERT3P(dtor_entry->he_dtor, ==, entry->he_dtor); |
| 616 | |
| 617 | hash = hash_long((ulong_t)entry->he_key * |
| 618 | (ulong_t)entry->he_pid, table->ht_bits); |
| 619 | entry_bin = &table->ht_bins[hash]; |
| 620 | |
| 621 | spin_lock(&entry_bin->hb_lock); |
| 622 | tsd_hash_del(table, entry); |
| 623 | hlist_add_head(&entry->he_list, &work); |
| 624 | spin_unlock(&entry_bin->hb_lock); |
| 625 | } |
| 626 | |
| 627 | hash = hash_long((ulong_t)dtor_entry->he_key * |
| 628 | (ulong_t)dtor_entry->he_pid, table->ht_bits); |
| 629 | dtor_entry_bin = &table->ht_bins[hash]; |
| 630 | |
| 631 | spin_lock(&dtor_entry_bin->hb_lock); |
| 632 | tsd_hash_del(table, dtor_entry); |
| 633 | hlist_add_head(&dtor_entry->he_list, &work); |
| 634 | spin_unlock(&dtor_entry_bin->hb_lock); |
| 635 | spin_unlock(&table->ht_lock); |
| 636 | |
| 637 | tsd_hash_dtor(&work); |
| 638 | *keyp = 0; |
| 639 | } |
| 640 | EXPORT_SYMBOL(tsd_destroy); |
| 641 | |
| 642 | /* |
no test coverage detected