예제 #1
0
파일: ipc_space.c 프로젝트: jue-jiang/xnu
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);
}
예제 #2
0
파일: ipc_space.c 프로젝트: ctos/bpi
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);
}