int _pthread_setspecific(pthread_key_t key, const void *value) { struct pthread *pthread; int ret = 0; /* Point to the running thread: */ pthread = _get_curthread(); if ((pthread->specific) || (pthread->specific = pthread_key_allocate_data())) { if ((unsigned int)key < PTHREAD_KEYS_MAX) { if (_thread_keytable[key].allocated) { if (pthread->specific[key].data == NULL) { if (value != NULL) pthread->specific_data_count++; } else if (value == NULL) pthread->specific_data_count--; *(const void **)&pthread->specific[key].data = value; pthread->specific[key].seqno = _thread_keytable[key].seqno; ret = 0; } else ret = EINVAL; } else ret = EINVAL; } else ret = ENOMEM; return (ret); }
int pthread_setspecific(pthread_key_t key, const void *value) { pthread_t pthread; int ret = 0; int status; PTHREAD_INIT; /* Block signals: */ _thread_kern_sig_block(&status); /* Point to the running thread: */ pthread = _thread_run; /* * Enter a loop for signal handler threads to find the parent thread * which has the specific data associated with it: */ while (pthread->parent_thread != NULL) { /* Point to the parent thread: */ pthread = pthread->parent_thread; } if ((pthread->specific_data) || (pthread->specific_data = pthread_key_allocate_data())) { if ((key < PTHREAD_KEYS_MAX) && (key_table)) { if (key_table[key].count) { if (pthread->specific_data[key] == NULL) { if (value != NULL) { pthread->specific_data_count++; key_table[key].count++; } } else { if (value == NULL) { pthread->specific_data_count--; key_table[key].count--; } } pthread->specific_data[key] = value; ret = 0; } else { ret = EINVAL; } } else { ret = EINVAL; } } else { ret = ENOMEM; } /* Unblock signals: */ _thread_kern_sig_unblock(status); return (ret); }