- mutex = mutex_addr(task->lock);
- excp = &task->exc_actions[exception];
-
- /*
- * Save work if we are terminating.
- * Just go back to our AST handler.
- */
- if (!self->active) {
- return(KERN_FAILURE);
- }
-
- /*
- * Snapshot the exception action data under lock for consistency.
- * Hold a reference to the port over the exception_raise_* calls
- * so it can't be destroyed. This seems like overkill, but keeps
- * the port from disappearing between now and when
- * ipc_object_copyin_from_kernel is finally called.
- */
- mutex_lock(mutex);
- exc_port = excp->port;
- if (!IP_VALID(exc_port)) {
- mutex_unlock(mutex);
- return(KERN_FAILURE);
- }
- ip_lock(exc_port);
- if (!ip_active(exc_port)) {
- ip_unlock(exc_port);
- mutex_unlock(mutex);
- return(KERN_FAILURE);
- }
- ip_reference(exc_port);
- exc_port->ip_srights++;
- ip_unlock(exc_port);
-
- flavor = excp->flavor;
- behavior = excp->behavior;
- mutex_unlock(mutex);
-
- switch (behavior) {
- case EXCEPTION_STATE: {
- mach_msg_type_number_t state_cnt;
- thread_state_data_t state;
-
- c_thr_exc_raise_state++;
- state_cnt = _MachineStateCount[flavor];
- kr = thread_getstatus(self, flavor,
- (thread_state_t)state,
- &state_cnt);
- if (kr == KERN_SUCCESS) {
- kr = exception_raise_state(exc_port, exception,
- code, codeCnt,
- &flavor,
- state, state_cnt,
- state, &state_cnt);
- if (kr == MACH_MSG_SUCCESS)
- kr = thread_setstatus(self, flavor,
- (thread_state_t)state,
- state_cnt);
- }