void ipc_space_terminate( ipc_space_t space) { ipc_entry_t table; ipc_entry_num_t size; mach_port_index_t index; assert(space != IS_NULL); is_write_lock(space); if (!is_active(space)) { is_write_unlock(space); return; } is_mark_inactive(space); /* * If somebody is trying to grow the table, * we must wait until they finish and figure * out the space died. */ while (is_growing(space)) is_write_sleep(space); is_write_unlock(space); /* * Now we can futz with it unlocked. */ table = space->is_table; size = space->is_table_size; for (index = 0; index < size; index++) { ipc_entry_t entry = &table[index]; mach_port_type_t type; type = IE_BITS_TYPE(entry->ie_bits); if (type != MACH_PORT_TYPE_NONE) { mach_port_name_t name; name = MACH_PORT_MAKE(index, IE_BITS_GEN(entry->ie_bits)); ipc_right_terminate(space, name, entry); } } it_entries_free(space->is_table_next-1, table); space->is_table_size = 0; /* * Because the space is now dead, * we must release the "active" reference for it. * Our caller still has his reference. */ is_release(space); }
void ipc_space_destroy( ipc_space_t space) { ipc_tree_entry_t tentry; ipc_entry_t table; ipc_entry_num_t size; mach_port_index_t index; boolean_t active; assert(space != IS_NULL); is_write_lock(space); active = space->is_active; space->is_active = FALSE; is_write_unlock(space); if (!active) return; /* * If somebody is trying to grow the table, * we must wait until they finish and figure * out the space died. */ is_read_lock(space); while (space->is_growing) { assert_wait((event_t) space, FALSE); is_read_unlock(space); thread_block((void (*)(void)) 0); is_read_lock(space); } is_read_unlock(space); /* * Now we can futz with it without having it locked. */ table = space->is_table; size = space->is_table_size; for (index = 0; index < size; index++) { ipc_entry_t entry = &table[index]; mach_port_type_t type = IE_BITS_TYPE(entry->ie_bits); if (type != MACH_PORT_TYPE_NONE) { mach_port_t name = MACH_PORT_MAKEB(index, entry->ie_bits); ipc_right_clean(space, name, entry); } } it_entries_free(space->is_table_next-1, table); for (tentry = ipc_splay_traverse_start(&space->is_tree); tentry != ITE_NULL; tentry = ipc_splay_traverse_next(&space->is_tree, TRUE)) { mach_port_type_t type = IE_BITS_TYPE(tentry->ite_bits); mach_port_t name = tentry->ite_name; assert(type != MACH_PORT_TYPE_NONE); /* use object before ipc_right_clean releases ref */ if (type == MACH_PORT_TYPE_SEND) ipc_hash_global_delete(space, tentry->ite_object, name, tentry); ipc_right_clean(space, name, &tentry->ite_entry); } ipc_splay_traverse_finish(&space->is_tree); /* * Because the space is now dead, * we must release the "active" reference for it. * Our caller still has his reference. */ is_release(space); }