|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* ! 26: * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990 ! 27: * Open Software Foundation, Inc. ! 28: * ! 29: * Permission to use, copy, modify, and distribute this software and ! 30: * its documentation for any purpose and without fee is hereby granted, ! 31: * provided that the above copyright notice appears in all copies and ! 32: * that both the copyright notice and this permission notice appear in ! 33: * supporting documentation, and that the name of ("OSF") or Open Software ! 34: * Foundation not be used in advertising or publicity pertaining to ! 35: * distribution of the software without specific, written prior permission. ! 36: * ! 37: * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE ! 38: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ! 39: * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY ! 40: * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! 41: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ! 42: * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING ! 43: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE ! 44: */ ! 45: /* ! 46: * OSF Research Institute MK6.1 (unencumbered) 1/31/1995 ! 47: */ ! 48: /* ! 49: * Mach Operating System ! 50: * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University ! 51: * All Rights Reserved. ! 52: * ! 53: * Permission to use, copy, modify and distribute this software and its ! 54: * documentation is hereby granted, provided that both the copyright ! 55: * notice and this permission notice appear in all copies of the ! 56: * software, derivative works or modified versions, and any portions ! 57: * thereof, and that both notices appear in supporting documentation. ! 58: * ! 59: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 60: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 61: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 62: * ! 63: * Carnegie Mellon requests users of this software to return to ! 64: * ! 65: * Software Distribution Coordinator or [email protected] ! 66: * School of Computer Science ! 67: * Carnegie Mellon University ! 68: * Pittsburgh PA 15213-3890 ! 69: * ! 70: * any improvements or extensions that they make and grant Carnegie Mellon ! 71: * the rights to redistribute these changes. ! 72: */ ! 73: /* ! 74: * File: ipc/ipc_space.c ! 75: * Author: Rich Draves ! 76: * Date: 1989 ! 77: * ! 78: * Functions to manipulate IPC capability spaces. ! 79: */ ! 80: ! 81: #import <mach/features.h> ! 82: ! 83: #include <mach/boolean.h> ! 84: #include <mach/kern_return.h> ! 85: #include <mach/port.h> ! 86: #include <kern/assert.h> ! 87: #include <kern/sched_prim.h> ! 88: #include <kern/zalloc.h> ! 89: #include <ipc/port.h> ! 90: #include <ipc/ipc_entry.h> ! 91: #include <ipc/ipc_splay.h> ! 92: #include <ipc/ipc_object.h> ! 93: #include <ipc/ipc_hash.h> ! 94: #include <ipc/ipc_table.h> ! 95: #include <ipc/ipc_port.h> ! 96: #include <ipc/ipc_space.h> ! 97: #include <ipc/ipc_right.h> ! 98: ! 99: ! 100: ! 101: zone_t ipc_space_zone; ! 102: ipc_space_t ipc_space_kernel; ! 103: ipc_space_t ipc_space_reply; ! 104: ! 105: /* ! 106: * Routine: ipc_space_reference ! 107: * Routine: ipc_space_release ! 108: * Purpose: ! 109: * Function versions of the IPC space macros. ! 110: * The "is_" cover macros can be defined to use the ! 111: * macros or the functions, as desired. ! 112: */ ! 113: ! 114: void ! 115: ipc_space_reference( ! 116: ipc_space_t space) ! 117: { ! 118: ipc_space_reference_macro(space); ! 119: } ! 120: ! 121: void ! 122: ipc_space_release( ! 123: ipc_space_t space) ! 124: { ! 125: ipc_space_release_macro(space); ! 126: } ! 127: ! 128: /* ! 129: * Routine: ipc_space_create ! 130: * Purpose: ! 131: * Creates a new IPC space. ! 132: * ! 133: * The new space has two references, one for the caller ! 134: * and one because it is active. ! 135: * Conditions: ! 136: * Nothing locked. Allocates memory. ! 137: * Returns: ! 138: * KERN_SUCCESS Created a space. ! 139: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 140: */ ! 141: ! 142: kern_return_t ! 143: ipc_space_create( ! 144: ipc_table_size_t initial, ! 145: ipc_space_t *spacep) ! 146: { ! 147: ipc_space_t space; ! 148: ipc_entry_t table; ! 149: ipc_entry_num_t new_size; ! 150: mach_port_index_t index; ! 151: ! 152: space = is_alloc(); ! 153: if (space == IS_NULL) ! 154: return KERN_RESOURCE_SHORTAGE; ! 155: ! 156: table = it_entries_alloc(initial); ! 157: if (table == IE_NULL) { ! 158: is_free(space); ! 159: return KERN_RESOURCE_SHORTAGE; ! 160: } ! 161: ! 162: new_size = initial->its_size; ! 163: bzero((char *) table, new_size * sizeof(struct ipc_entry)); ! 164: ! 165: /* ! 166: * Initialize the free list in the table. ! 167: * Add the entries in reverse order, and ! 168: * set the generation number to -1, so that ! 169: * initial allocations produce "natural" names. ! 170: */ ! 171: ! 172: for (index = 0; index < new_size; index++) { ! 173: ipc_entry_t entry = &table[index]; ! 174: ! 175: entry->ie_bits = IE_BITS_GEN_MASK; ! 176: entry->ie_next = index+1; ! 177: } ! 178: table[new_size-1].ie_next = 0; ! 179: ! 180: is_ref_lock_init(space); ! 181: space->is_references = 2; ! 182: ! 183: is_lock_init(space); ! 184: space->is_active = TRUE; ! 185: space->is_growing = FALSE; ! 186: space->is_table = table; ! 187: space->is_table_size = new_size; ! 188: space->is_table_next = initial+1; ! 189: ! 190: ipc_splay_tree_init(&space->is_tree); ! 191: space->is_tree_total = 0; ! 192: space->is_tree_small = 0; ! 193: space->is_tree_hash = 0; ! 194: ! 195: #if MACH_IPC_COMPAT ! 196: { ! 197: mach_port_t name; ! 198: ipc_port_t port; ! 199: kern_return_t kr; ! 200: ! 201: /* ! 202: * ipc_port_alloc_compat probably won't look at is_notify, ! 203: * but make sure all fields have sane values anyway. ! 204: */ ! 205: ! 206: space->is_notify = IP_NULL; ! 207: ! 208: #if !NeXT ! 209: kr = ipc_port_alloc_compat(space, &name, &port); ! 210: if (kr != KERN_SUCCESS) { ! 211: ipc_space_destroy(space); ! 212: is_release(space); ! 213: return kr; ! 214: } ! 215: ! 216: ip_reference(port); ! 217: port->ip_srights++; ! 218: ip_unlock(port); ! 219: space->is_notify = port; ! 220: #endif ! 221: } ! 222: #endif MACH_IPC_COMPAT ! 223: ! 224: *spacep = space; ! 225: return KERN_SUCCESS; ! 226: } ! 227: ! 228: /* ! 229: * Routine: ipc_space_create_special ! 230: * Purpose: ! 231: * Create a special space. A special space ! 232: * doesn't hold rights in the normal way. ! 233: * Instead it is place-holder for holding ! 234: * disembodied (naked) receive rights. ! 235: * See ipc_port_alloc_special/ipc_port_dealloc_special. ! 236: * Conditions: ! 237: * Nothing locked. ! 238: * Returns: ! 239: * KERN_SUCCESS Created a space. ! 240: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 241: */ ! 242: ! 243: kern_return_t ! 244: ipc_space_create_special( ! 245: ipc_space_t *spacep) ! 246: { ! 247: ipc_space_t space; ! 248: ! 249: space = is_alloc(); ! 250: if (space == IS_NULL) ! 251: return KERN_RESOURCE_SHORTAGE; ! 252: ! 253: is_ref_lock_init(space); ! 254: space->is_references = 1; ! 255: ! 256: is_lock_init(space); ! 257: space->is_active = FALSE; ! 258: ! 259: *spacep = space; ! 260: return KERN_SUCCESS; ! 261: } ! 262: ! 263: /* ! 264: * Routine: ipc_space_destroy ! 265: * Purpose: ! 266: * Marks the space as dead and cleans up the entries. ! 267: * Does nothing if the space is already dead. ! 268: * Conditions: ! 269: * Nothing locked. ! 270: */ ! 271: ! 272: void ! 273: ipc_space_destroy( ! 274: ipc_space_t space) ! 275: { ! 276: ipc_tree_entry_t tentry; ! 277: ipc_entry_t table; ! 278: ipc_entry_num_t size; ! 279: mach_port_index_t index; ! 280: boolean_t active; ! 281: ! 282: assert(space != IS_NULL); ! 283: ! 284: is_write_lock(space); ! 285: active = space->is_active; ! 286: space->is_active = FALSE; ! 287: is_write_unlock(space); ! 288: ! 289: if (!active) ! 290: return; ! 291: ! 292: /* ! 293: * If somebody is trying to grow the table, ! 294: * we must wait until they finish and figure ! 295: * out the space died. ! 296: */ ! 297: ! 298: is_read_lock(space); ! 299: while (space->is_growing) { ! 300: assert_wait((event_t) space, FALSE); ! 301: is_read_unlock(space); ! 302: thread_block_with_continuation((void (*)(void)) 0); ! 303: is_read_lock(space); ! 304: } ! 305: is_read_unlock(space); ! 306: ! 307: /* ! 308: * Now we can futz with it without having it locked. ! 309: */ ! 310: ! 311: table = space->is_table; ! 312: size = space->is_table_size; ! 313: ! 314: for (index = 0; index < size; index++) { ! 315: ipc_entry_t entry = &table[index]; ! 316: mach_port_type_t type = IE_BITS_TYPE(entry->ie_bits); ! 317: ! 318: if (type != MACH_PORT_TYPE_NONE) { ! 319: mach_port_t name = ! 320: MACH_PORT_MAKEB(index, entry->ie_bits); ! 321: ! 322: ipc_right_clean(space, name, entry); ! 323: } ! 324: } ! 325: ! 326: it_entries_free(space->is_table_next-1, table); ! 327: ! 328: for (tentry = ipc_splay_traverse_start(&space->is_tree); ! 329: tentry != ITE_NULL; ! 330: tentry = ipc_splay_traverse_next(&space->is_tree, TRUE)) { ! 331: mach_port_type_t type = IE_BITS_TYPE(tentry->ite_bits); ! 332: mach_port_t name = tentry->ite_name; ! 333: ! 334: assert(type != MACH_PORT_TYPE_NONE); ! 335: ! 336: /* use object before ipc_right_clean releases ref */ ! 337: ! 338: if (type == MACH_PORT_TYPE_SEND) ! 339: ipc_hash_global_delete(space, tentry->ite_object, ! 340: name, tentry); ! 341: ! 342: ipc_right_clean(space, name, &tentry->ite_entry); ! 343: } ! 344: ipc_splay_traverse_finish(&space->is_tree); ! 345: ! 346: #if MACH_IPC_COMPAT ! 347: if (IP_VALID(space->is_notify)) ! 348: ipc_port_release_send(space->is_notify); ! 349: #endif MACH_IPC_COMPAT ! 350: ! 351: /* ! 352: * Because the space is now dead, ! 353: * we must release the "active" reference for it. ! 354: * Our caller still has his reference. ! 355: */ ! 356: ! 357: is_release(space); ! 358: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.