this repo has no description
at fixPythonPipStalling 241 lines 6.3 kB view raw
1/* 2 * Copyright (c) 2019 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24/* 25 * serviceID_number.c 26 * - assigns numbers to serviceID strings 27 */ 28 29#include <stdio.h> 30#include <stdlib.h> 31#include <unistd.h> 32 33#include "serviceIDNumber.h" 34#include <CoreFoundation/CFDictionary.h> 35 36#if TEST_SERVICEID_NUMBER 37#include <SystemConfiguration/SCPrivate.h> 38#endif /* TEST_SERVICEID_NUMBER */ 39 40 41/* dictionary to hold serviceIDNumber: key is the serviceID */ 42static CFMutableDictionaryRef S_serviceID_to_number_dict; 43 44/* dictionary to hold serviceID: key is the serviceIDNumber */ 45static CFMutableDictionaryRef S_number_to_serviceID_dict; 46 47static Boolean 48serviceIDNumberEqual(const void * ptr1, const void * ptr2) 49{ 50 return (((serviceIDNumber)ptr1) == ((serviceIDNumber)ptr2)); 51} 52 53static CFStringRef 54serviceIDNumberCopyDescription(const void * ptr) 55{ 56 return CFStringCreateWithFormat(NULL, NULL, CFSTR("%ld"), 57 (serviceIDNumber)ptr); 58} 59 60static CFHashCode 61serviceIDNumberHash(const void * ptr) { 62 return (CFHashCode)((serviceIDNumber)ptr); 63} 64 65static const CFDictionaryValueCallBacks kserviceIDNumberValueCallBacks = { 66 0, NULL, NULL, serviceIDNumberCopyDescription, serviceIDNumberEqual 67}; 68 69static const CFDictionaryKeyCallBacks kserviceIDNumberKeyCallBacks = { 70 0, NULL, NULL, serviceIDNumberCopyDescription, serviceIDNumberEqual, 71 serviceIDNumberHash 72}; 73 74/** 75 ** S_serviceID_numbers 76 **/ 77 78__private_extern__ Boolean 79serviceIDNumberGetIfPresent(CFStringRef serviceID, serviceIDNumber *sidn) 80{ 81 Boolean has_number; 82 const void * val; 83 84 has_number = CFDictionaryGetValueIfPresent(S_serviceID_to_number_dict, 85 serviceID, &val); 86 if (has_number) { 87 *sidn = (serviceIDNumber)val; 88 } 89 return (has_number); 90} 91 92/* 93 * Function: serviceIDNumberGet 94 * Purpose: 95 * Return the currently assigned serviceIDNumber for the given serviceID. 96 * If one is already assigned, return that. If one isn't assigned, check 97 * the next integer value after 'current_sidn', but skip zero. 98 * If that number is assigned, pick the next one. 99 */ 100static serviceIDNumber S_current_sidn; 101 102__private_extern__ serviceIDNumber 103serviceIDNumberGet(CFStringRef serviceID) 104{ 105 serviceIDNumber sidn; 106 107 if (serviceIDNumberGetIfPresent(serviceID, &sidn)) { 108 return (sidn); 109 } 110 while (1) { 111 /* assign a number to the serviceID */ 112 S_current_sidn++; 113 if (S_current_sidn == kserviceIDNumberZero) { 114 /* skip zero */ 115 S_current_sidn++; 116 } 117 /* if it's in use, skip to the next value */ 118 if (CFDictionaryContainsKey(S_number_to_serviceID_dict, 119 (const void *)S_current_sidn)) { 120 continue; 121 } 122 /* it's not in use, use it */ 123 sidn = S_current_sidn; 124 CFDictionarySetValue(S_serviceID_to_number_dict, 125 serviceID, (const void *)sidn); 126 CFDictionarySetValue(S_number_to_serviceID_dict, 127 (const void *)sidn, serviceID); 128 break; 129 } 130 return (sidn); 131} 132 133 134__private_extern__ void 135serviceIDNumberRemove(CFStringRef serviceID) 136{ 137 const void * val; 138 139 if (CFDictionaryGetValueIfPresent(S_serviceID_to_number_dict, serviceID, 140 &val)) { 141#if TEST_SERVICEID_NUMBER 142 SCPrint(TRUE, stdout, CFSTR("Removing %@ %ld\n"), 143 serviceID, (serviceIDNumber)val); 144#endif 145 CFDictionaryRemoveValue(S_serviceID_to_number_dict, serviceID); 146 CFDictionaryRemoveValue(S_number_to_serviceID_dict, val); 147 } 148} 149 150__private_extern__ void 151serviceIDNumberInit(void) 152{ 153 S_serviceID_to_number_dict 154 = CFDictionaryCreateMutable(NULL, 0, 155 &kCFTypeDictionaryKeyCallBacks, 156 &kserviceIDNumberValueCallBacks); 157 S_number_to_serviceID_dict 158 = CFDictionaryCreateMutable(NULL, 0, 159 &kserviceIDNumberKeyCallBacks, 160 &kCFTypeDictionaryValueCallBacks); 161} 162 163#if TEST_SERVICEID_NUMBER 164 165static CFStringRef 166my_CFUUIDStringCreate(CFAllocatorRef alloc) 167{ 168 CFUUIDRef uuid; 169 CFStringRef uuid_str; 170 171 uuid = CFUUIDCreate(alloc); 172 uuid_str = CFUUIDCreateString(alloc, uuid); 173 CFRelease(uuid); 174 return (uuid_str); 175} 176 177int 178main() 179{ 180#define N_LIST 10 181 CFStringRef serviceID_list[N_LIST]; 182 183 serviceIDNumberInit(); 184 for (int i = 0; i < N_LIST; i++) { 185 CFStringRef serviceID = my_CFUUIDStringCreate(NULL); 186 serviceIDNumber sidn; 187 188 /* force a collision */ 189 S_current_sidn = -1; 190 191 sidn = serviceIDNumberGet(serviceID); 192 SCPrint(TRUE, stdout, CFSTR("%d: %@ %ld\n"), 193 i, serviceID, sidn); 194 serviceID_list[i] = serviceID; 195 196 } 197 for (int i = 0; i < N_LIST; i++) { 198 CFStringRef serviceID = serviceID_list[i]; 199 serviceIDNumber sidn; 200 201 if (!serviceIDNumberGetIfPresent(serviceID, &sidn)) { 202 SCPrint(TRUE, stderr, CFSTR("Failed to find %@\n"), 203 serviceID); 204 exit(1); 205 } 206 SCPrint(TRUE, stdout, CFSTR("%@ => %ld\n"), serviceID, sidn); 207 } 208 { 209 serviceIDNumber sidn; 210 211 if (serviceIDNumberGetIfPresent(CFSTR("blah"), &sidn)) { 212 fprintf(stderr, 213 "Shouldn't have been able to look that up\n"); 214 exit(1); 215 } 216 } 217 218 for (int i = 0; i < N_LIST / 2; i++) { 219 CFStringRef serviceID = serviceID_list[i]; 220 serviceIDNumber sidn; 221 222 serviceIDNumberRemove(serviceID); 223 if (serviceIDNumberGetIfPresent(serviceID, &sidn)) { 224 SCPrint(TRUE, stderr, 225 CFSTR("Found %@, but shouldn't have\n"), 226 serviceID); 227 exit(1); 228 } 229 } 230 231 for (int i = 0; i < N_LIST; i++) { 232 CFStringRef serviceID = serviceID_list[i]; 233 serviceIDNumber sidn; 234 235 sidn = serviceIDNumberGet(serviceID); 236 SCPrint(TRUE, stdout, CFSTR("%d: %@ %ld\n"), 237 i, serviceID, sidn); 238 } 239 exit(0); 240} 241#endif /* TEST_SERVICEID_NUMBER */