Allocate a new lock info struct for the current thread and associate it * with our thread specific key. Contains sanity checks to ensure this * hasn't already been done. */
| 746 | * with our thread specific key. Contains sanity checks to ensure this |
| 747 | * hasn't already been done. */ |
| 748 | static void new_thread_lock_info(bdb_state_type *bdb_state) |
| 749 | { |
| 750 | thread_lock_info_type *lk = pthread_getspecific(lock_key); |
| 751 | int rc = 0; |
| 752 | |
| 753 | if (lk) { |
| 754 | logmsg(LOGMSG_WARN, "%s: redundant thread start!\n", __func__); |
| 755 | lk->callers++; |
| 756 | return; |
| 757 | } |
| 758 | |
| 759 | lk = calloc(1, sizeof(thread_lock_info_type)); |
| 760 | if (!lk) { |
| 761 | logmsg(LOGMSG_FATAL, "%s: out of memory\n", __func__); |
| 762 | exit(1); |
| 763 | } |
| 764 | |
| 765 | lk->threadid = pthread_self(); |
| 766 | lk->callers = 1; |
| 767 | |
| 768 | if (bdb_state->attr && bdb_state->attr->debug_bdb_lock_stack) { |
| 769 | lk->stack = (void **)malloc(sizeof(void *) * BDB_DEBUG_STACK); |
| 770 | if (!lk->stack) { |
| 771 | logmsg(LOGMSG_FATAL, "%s: out of memory\n", __func__); |
| 772 | free(lk); |
| 773 | exit(1); |
| 774 | } |
| 775 | rc = stack_pc_getlist(NULL, lk->stack, BDB_DEBUG_STACK, &lk->nstack); |
| 776 | if (rc) { |
| 777 | #ifndef _LINUX_SOURCE |
| 778 | logmsg(LOGMSG_WARN, "%s: failed to get stack %d\n", __func__, rc); |
| 779 | #endif |
| 780 | free(lk->stack); |
| 781 | lk->stack = NULL; |
| 782 | } |
| 783 | } |
| 784 | |
| 785 | Pthread_setspecific(lock_key, lk); |
| 786 | |
| 787 | Pthread_mutex_lock(&bdb_state->thread_lock_info_list_mutex); |
| 788 | listc_atl(&bdb_state->thread_lock_info_list, lk); |
| 789 | Pthread_mutex_unlock(&bdb_state->thread_lock_info_list_mutex); |
| 790 | } |
| 791 | |
| 792 | /* Free the current thread's lock info struct. */ |
| 793 | static void delete_thread_lock_info(bdb_state_type *bdb_state) |
no test coverage detected