/* * ipc_space_clean - remove all port references from an ipc space. * * In order to follow the traditional semantic, ipc_space_destroy * will not destroy the entire port table of a shared space. Instead * it will simply clear its own sub-space. */ void ipc_space_clean( ipc_space_t space) { ipc_entry_t table; ipc_entry_num_t size; mach_port_index_t index; /* * If somebody is trying to grow the table, * we must wait until they finish and figure * out the space died. */ retry: is_write_lock(space); while (is_growing(space)) is_write_sleep(space); if (!is_active(space)) { is_write_unlock(space); return; } /* * Now we can futz with it since we have the write lock. */ 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 = MACH_PORT_MAKE(index, IE_BITS_GEN(entry->ie_bits)); ipc_right_destroy(space, name, entry, FALSE, 0); /* unlocks space */ goto retry; } } /* * JMM - Now the table is cleaned out. We don't bother shrinking the * size of the table at this point, but we probably should if it is * really large. */ is_write_unlock(space); }
kern_return_t mach_port_destroy( ipc_space_t space, mach_port_name_t name) { ipc_entry_t entry; kern_return_t kr; if (space == IS_NULL) return KERN_INVALID_TASK; if (!MACH_PORT_VALID(name)) return KERN_SUCCESS; kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) return kr; /* space is write-locked and active */ kr = ipc_right_destroy(space, name, entry); is_write_unlock(space); return kr; }