+ } else {
+ /* reset the importance attribute from our previous life */
+ task_importance_reset(p->task);
+
+ /* reset atm context from task */
+ task_atm_reset(p->task);
+ }
+
+ /*
+ * Apply the spawnattr policy, apptype (which primes the task for importance donation),
+ * and bind any portwatch ports to the new task.
+ * This must be done after the exec so that the child's thread is ready,
+ * and after the in transit state has been released, because priority is
+ * dropped here so we need to be prepared for a potentially long preemption interval
+ *
+ * TODO: Consider splitting this up into separate phases
+ */
+ if (error == 0 && imgp->ip_px_sa != NULL) {
+ struct _posix_spawnattr *psa = (struct _posix_spawnattr *) imgp->ip_px_sa;
+
+ exec_handle_spawnattr_policy(p, psa->psa_apptype, psa->psa_qos_clamp,
+ portwatch_ports, portwatch_count);
+ }
+
+ /* Apply the main thread qos */
+ if (error == 0) {
+ thread_t main_thread = (imgp->ip_new_thread != NULL) ? imgp->ip_new_thread : current_thread();
+
+ task_set_main_thread_qos(p->task, main_thread);
+ }
+
+ /*
+ * Release any ports we kept around for binding to the new task
+ * We need to release the rights even if the posix_spawn has failed.
+ */
+ if (portwatch_ports != NULL) {
+ for (int i = 0; i < portwatch_count; i++) {
+ ipc_port_t port = NULL;
+ if ((port = portwatch_ports[i]) != NULL) {
+ ipc_port_release_send(port);
+ }
+ }
+ FREE(portwatch_ports, M_TEMP);
+ portwatch_ports = NULL;
+ portwatch_count = 0;