2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
29 isMySessionKey(CFStringRef sessionKey
, CFStringRef key
)
32 CFStringRef cacheSessionKey
;
34 dict
= CFDictionaryGetValue(cacheData
, key
);
36 /* if key no longer exists */
40 cacheSessionKey
= CFDictionaryGetValue(dict
, kSCDSession
);
41 if (!cacheSessionKey
) {
42 /* if this is not a session key */
46 if (!CFEqual(sessionKey
, cacheSessionKey
)) {
47 /* if this is not "my" session key */
56 _SCDClose(SCDSessionRef
*session
)
58 SCDSessionPrivateRef sessionPrivate
= (SCDSessionPrivateRef
)*session
;
60 CFStringRef sessionKey
;
63 serverSessionRef mySession
;
65 SCDLog(LOG_DEBUG
, CFSTR("_SCDClose:"));
67 if ((*session
== NULL
) || (sessionPrivate
->server
== MACH_PORT_NULL
)) {
71 /* Remove notification keys */
72 if ((keyCnt
= CFSetGetCount(sessionPrivate
->keys
)) > 0) {
74 CFArrayRef keysToRemove
;
77 watchedKeys
= CFAllocatorAllocate(NULL
, keyCnt
* sizeof(CFStringRef
), 0);
78 CFSetGetValues(sessionPrivate
->keys
, watchedKeys
);
79 keysToRemove
= CFArrayCreate(NULL
, watchedKeys
, keyCnt
, &kCFTypeArrayCallBacks
);
80 CFAllocatorDeallocate(NULL
, watchedKeys
);
81 for (i
=0; i
<keyCnt
; i
++) {
82 (void) _SCDNotifierRemove(*session
,
83 CFArrayGetValueAtIndex(keysToRemove
, i
),
86 CFRelease(keysToRemove
);
89 /* Remove regex notification keys */
90 if ((keyCnt
= CFSetGetCount(sessionPrivate
->reKeys
)) > 0) {
92 CFArrayRef keysToRemove
;
95 watchedKeys
= CFAllocatorAllocate(NULL
, keyCnt
* sizeof(CFStringRef
), 0);
96 CFSetGetValues(sessionPrivate
->reKeys
, watchedKeys
);
97 keysToRemove
= CFArrayCreate(NULL
, watchedKeys
, keyCnt
, &kCFTypeArrayCallBacks
);
98 CFAllocatorDeallocate(NULL
, watchedKeys
);
99 for (i
=0; i
<keyCnt
; i
++) {
100 (void) _SCDNotifierRemove(*session
,
101 CFArrayGetValueAtIndex(keysToRemove
, i
),
104 CFRelease(keysToRemove
);
107 /* Remove/cancel any outstanding notification requests. */
108 (void) _SCDNotifierCancel(*session
);
110 /* Remove any session keys */
111 sessionKey
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), sessionPrivate
->server
);
112 dict
= CFDictionaryGetValue(sessionData
, sessionKey
);
113 keys
= CFDictionaryGetValue(dict
, kSCDSessionKeys
);
114 if (keys
&& ((keyCnt
= CFArrayGetCount(keys
)) > 0)) {
119 * if necessary, claim a lock to ensure that we inform
120 * any processes that a session key was removed.
122 wasLocked
= SCDOptionGet(NULL
, kSCDOptionIsLocked
);
124 (void) _SCDLock(*session
);
127 /* remove keys from "locked" cache" */
128 for (i
=0; i
<keyCnt
; i
++) {
129 if (isMySessionKey(sessionKey
, CFArrayGetValueAtIndex(keys
, i
)))
130 (void) _SCDRemove(*session
, CFArrayGetValueAtIndex(keys
, i
));
134 /* remove keys from "unlocked" cache" */
135 _swapLockedCacheData();
136 for (i
=0; i
<keyCnt
; i
++) {
137 if (isMySessionKey(sessionKey
, CFArrayGetValueAtIndex(keys
, i
)))
138 (void) _SCDRemove(*session
, CFArrayGetValueAtIndex(keys
, i
));
140 _swapLockedCacheData();
144 * Note: everyone who calls _SCDClose() ends up
145 * removing this sessions dictionary. As
146 * such, we don't need to worry about
150 CFRelease(sessionKey
);
152 /* release the lock */
153 if (SCDOptionGet(*session
, kSCDOptionIsLocked
)) {
154 (void) _SCDUnlock(*session
);
158 * Invalidate the server port (for this client) which will result
159 * in the removal of any associated run loop sources.
161 mySession
= getSession(sessionPrivate
->server
);
162 if (mySession
->serverRunLoopSource
) {
163 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
164 mySession
->serverRunLoopSource
,
165 kCFRunLoopDefaultMode
);
166 CFRelease(mySession
->serverRunLoopSource
);
168 CFMachPortInvalidate(mySession
->serverPort
);
169 CFRelease(mySession
->serverPort
);
171 CFRelease(sessionPrivate
->keys
);
172 CFRelease(sessionPrivate
->reKeys
);
173 CFAllocatorDeallocate(NULL
, sessionPrivate
);
181 _configclose(mach_port_t server
, int *scd_status
)
183 serverSessionRef mySession
= getSession(server
);
185 SCDLog(LOG_DEBUG
, CFSTR("Close session."));
186 SCDLog(LOG_DEBUG
, CFSTR(" server = %d"), server
);
191 *scd_status
= _SCDClose(&mySession
->session
);
192 if (*scd_status
!= SCD_OK
) {
193 SCDLog(LOG_DEBUG
, CFSTR(" _SCDClose(): %s"), SCDError(*scd_status
));
198 * Remove the session entry.
200 removeSession(server
);