kern_return_t thread_dup2( thread_t source, thread_t target) { kern_return_t result = KERN_SUCCESS; uint32_t active = 0; if (source == THREAD_NULL || target == THREAD_NULL || target == source) return (KERN_INVALID_ARGUMENT); thread_mtx_lock(source); active = source->active; thread_mtx_unlock(source); if (!active) { return KERN_TERMINATED; } thread_mtx_lock(target); if (target->active || target->inspection) { thread_hold(target); thread_mtx_unlock(target); if (thread_stop(target, TRUE)) { thread_mtx_lock(target); result = machine_thread_dup(source, target); if (source->affinity_set != AFFINITY_SET_NULL) thread_affinity_dup(source, target); thread_unstop(target); } else { thread_mtx_lock(target); result = KERN_ABORTED; } thread_release(target); } else result = KERN_TERMINATED; thread_mtx_unlock(target); return (result); }
kern_return_t thread_dup( register thread_t target) { thread_t self = current_thread(); kern_return_t result = KERN_SUCCESS; if (target == THREAD_NULL || target == self) return (KERN_INVALID_ARGUMENT); thread_mtx_lock(target); if (target->active) { thread_hold(target); thread_mtx_unlock(target); if (thread_stop(target, TRUE)) { thread_mtx_lock(target); result = machine_thread_dup(self, target); if (self->affinity_set != AFFINITY_SET_NULL) thread_affinity_dup(self, target); thread_unstop(target); } else { thread_mtx_lock(target); result = KERN_ABORTED; } thread_release(target); } else result = KERN_TERMINATED; thread_mtx_unlock(target); return (result); }