1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** dgccallt.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** DG protocol service routines. Handle client call table (CCALLT). 90** 91** 92*/ 93 94#include <dg.h> 95#include <dgcall.h> 96#include <dgccall.h> 97#include <dgccallt.h> 98 99/* 100 * R P C _ _ D G _ C C A L L T _ I N S E R T 101 * 102 * Add a client call handle to the CCALLT. Increment the call handle's reference 103 * count. 104 */ 105 106PRIVATE void rpc__dg_ccallt_insert 107( 108 rpc_dg_ccall_p_t ccall 109) 110{ 111 unsigned16 probe = ccall->c.actid_hash % RPC_DG_CCALLT_SIZE; 112 113 RPC_LOCK_ASSERT(0); 114 115 ccall->c.next = (rpc_dg_call_p_t) rpc_g_dg_ccallt[probe]; 116 rpc_g_dg_ccallt[probe] = ccall; 117 RPC_DG_CALL_REFERENCE(&ccall->c); 118} 119 120/* 121 * R P C _ _ D G _ C C A L L T _ R E M O V E 122 * 123 * Remove a client call handle from the CCALLT. Decrement the call 124 * handle's reference count. This routine can be called only if there 125 * are references to the CCALL other than the one from the CCALLT. 126 */ 127 128PRIVATE void rpc__dg_ccallt_remove 129( 130 rpc_dg_ccall_p_t ccall 131) 132{ 133 unsigned16 probe = ccall->c.actid_hash % RPC_DG_CCALLT_SIZE; 134 rpc_dg_ccall_p_t scan_ccall, prev_scan_ccall; 135 136 RPC_LOCK_ASSERT(0); 137 RPC_DG_CALL_LOCK_ASSERT(&ccall->c); 138 assert(ccall->c.refcnt > 1); 139 140 /* 141 * Scan down the hash chain. 142 */ 143 144 scan_ccall = rpc_g_dg_ccallt[probe]; 145 prev_scan_ccall = NULL; 146 147 while (scan_ccall != NULL) { 148 if (scan_ccall == ccall) { 149 if (prev_scan_ccall == NULL) 150 rpc_g_dg_ccallt[probe] = (rpc_dg_ccall_p_t) scan_ccall->c.next; 151 else 152 prev_scan_ccall->c.next = scan_ccall->c.next; 153 RPC_DG_CCALL_RELEASE_NO_UNLOCK(&scan_ccall); 154 return; 155 } 156 else { 157 prev_scan_ccall = scan_ccall; 158 scan_ccall = (rpc_dg_ccall_p_t) scan_ccall->c.next; 159 } 160 } 161 162 assert(false); /* Shouldn't ever fail to find the ccall */ 163} 164 165/* 166 * R P C _ _ D G _ C C A L L T _ L O O K U P 167 * 168 * Find a client call handle in the CCALLT based on an activity ID and 169 * probe hint (ahint). Return the ccall or NULL if no matching entry 170 * is found. Note that a probe_hint of RPC_C_DG_NO_HINT can be used if 171 * the caller doesn't have a hint. If we're returning a ccall, it will 172 * be locked and have it's reference count incremented already. 173 */ 174 175PRIVATE rpc_dg_ccall_p_t rpc__dg_ccallt_lookup 176( 177 uuid_p_t actid, 178 unsigned32 probe_hint 179) 180{ 181 rpc_dg_ccall_p_t ccall; 182 unsigned16 probe; 183 unsigned32 st; 184 boolean once = false; 185 186 RPC_LOCK_ASSERT(0); 187 188 /* 189 * Determine the hash chain to use 190 */ 191 192 if (probe_hint == RPC_C_DG_NO_HINT || probe_hint >= RPC_DG_CCALLT_SIZE) 193 probe = rpc__dg_uuid_hash(actid) % RPC_DG_CCALLT_SIZE; 194 else 195 probe = probe_hint; 196 197 /* 198 * Scan down the probe chain, reserve and return a matching SCTE. 199 */ 200 201RETRY: 202 ccall = rpc_g_dg_ccallt[probe]; 203 204 while (ccall != NULL) 205 { 206 if (UUID_EQ(*actid, ccall->c.call_actid, &st)) 207 { 208 RPC_DG_CALL_LOCK(&ccall->c); 209 RPC_DG_CALL_REFERENCE(&ccall->c); 210 return(ccall); 211 } 212 else 213 ccall = (rpc_dg_ccall_p_t) ccall->c.next; 214 } 215 216 /* 217 * No matching entry found. If we used the provided hint, try 218 * recomputing the probe and if this yields a new probe, give it 219 * one more try. 220 */ 221 222 if (probe == probe_hint && !once) 223 { 224 once = true; 225 probe = rpc__dg_uuid_hash(actid) % RPC_DG_CCALLT_SIZE; 226 if (probe != probe_hint) 227 goto RETRY; 228 } 229 230 return(NULL); 231} 232 233/* 234 * R P C _ _ D G _ C C A L L T _ F O R K _ H A N D L E R 235 * 236 * Handle fork related processing for this module. 237 */ 238PRIVATE void rpc__dg_ccallt_fork_handler 239( 240 rpc_fork_stage_id_t stage 241) 242{ 243 unsigned32 i; 244 245 switch ((int)stage) 246 { 247 case RPC_C_PREFORK: 248 break; 249 case RPC_C_POSTFORK_PARENT: 250 break; 251 case RPC_C_POSTFORK_CHILD: 252 /* 253 * Clear out the Client Call Handle Table 254 */ 255 256 for (i = 0; i < RPC_DG_CCALLT_SIZE; i++) 257 rpc_g_dg_ccallt[i] = NULL; 258 break; 259 } 260} 261