2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
27 * Modification History
29 * June 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - public API conversion
32 * June 2, 2000 Allan Nathanson <ajn@apple.com>
40 __private_extern__ CFMutableDictionaryRef sessionData
= NULL
;
42 __private_extern__ CFMutableDictionaryRef storeData
= NULL
;
43 __private_extern__ CFMutableDictionaryRef storeData_s
= NULL
;
45 __private_extern__ CFMutableDictionaryRef patternData
= NULL
;
46 __private_extern__ CFMutableDictionaryRef patternData_s
= NULL
;
48 __private_extern__ CFMutableSetRef changedKeys
= NULL
;
49 __private_extern__ CFMutableSetRef changedKeys_s
= NULL
;
51 __private_extern__ CFMutableSetRef deferredRemovals
= NULL
;
52 __private_extern__ CFMutableSetRef deferredRemovals_s
= NULL
;
54 __private_extern__ CFMutableSetRef removedSessionKeys
= NULL
;
55 __private_extern__ CFMutableSetRef removedSessionKeys_s
= NULL
;
57 __private_extern__ CFMutableSetRef needsNotification
= NULL
;
59 __private_extern__
int storeLocked
= 0; /* > 0 if dynamic store locked */
64 _swapLockedStoreData()
69 storeData
= storeData_s
;
73 patternData
= patternData_s
;
77 changedKeys
= changedKeys_s
;
80 temp
= deferredRemovals
;
81 deferredRemovals
= deferredRemovals_s
;
82 deferredRemovals_s
= temp
;
84 temp
= removedSessionKeys
;
85 removedSessionKeys
= removedSessionKeys_s
;
86 removedSessionKeys_s
= temp
;
94 _addWatcher(CFNumberRef sessionNum
, CFStringRef watchedKey
)
97 CFMutableDictionaryRef newDict
;
99 CFMutableArrayRef newWatchers
;
100 CFArrayRef watcherRefs
;
101 CFMutableArrayRef newWatcherRefs
;
107 * Get the dictionary associated with this key out of the store
109 dict
= CFDictionaryGetValue(storeData
, watchedKey
);
111 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
113 newDict
= CFDictionaryCreateMutable(NULL
,
115 &kCFTypeDictionaryKeyCallBacks
,
116 &kCFTypeDictionaryValueCallBacks
);
120 * Get the set of watchers out of the keys dictionary
122 watchers
= CFDictionaryGetValue(newDict
, kSCDWatchers
);
123 watcherRefs
= CFDictionaryGetValue(newDict
, kSCDWatcherRefs
);
125 newWatchers
= CFArrayCreateMutableCopy(NULL
, 0, watchers
);
126 newWatcherRefs
= CFArrayCreateMutableCopy(NULL
, 0, watcherRefs
);
128 newWatchers
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
129 newWatcherRefs
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
133 * Add my session to the set of watchers
135 i
= CFArrayGetFirstIndexOfValue(newWatchers
,
136 CFRangeMake(0, CFArrayGetCount(newWatchers
)),
139 /* if this is the first instance of this session watching this key */
140 CFArrayAppendValue(newWatchers
, sessionNum
);
142 refNum
= CFNumberCreate(NULL
, kCFNumberIntType
, &refCnt
);
143 CFArrayAppendValue(newWatcherRefs
, refNum
);
146 /* if this is another instance of this session watching this key */
147 refNum
= CFArrayGetValueAtIndex(newWatcherRefs
, i
);
148 CFNumberGetValue(refNum
, kCFNumberIntType
, &refCnt
);
150 refNum
= CFNumberCreate(NULL
, kCFNumberIntType
, &refCnt
);
151 CFArraySetValueAtIndex(newWatcherRefs
, i
, refNum
);
156 * Update the keys dictionary
158 CFDictionarySetValue(newDict
, kSCDWatchers
, newWatchers
);
159 CFRelease(newWatchers
);
160 CFDictionarySetValue(newDict
, kSCDWatcherRefs
, newWatcherRefs
);
161 CFRelease(newWatcherRefs
);
164 * Update the store for this key
166 CFDictionarySetValue(storeData
, watchedKey
, newDict
);
169 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" _addWatcher: %@, %@"), sessionNum
, watchedKey
);
177 _removeWatcher(CFNumberRef sessionNum
, CFStringRef watchedKey
)
179 CFDictionaryRef dict
;
180 CFMutableDictionaryRef newDict
;
182 CFMutableArrayRef newWatchers
;
183 CFArrayRef watcherRefs
;
184 CFMutableArrayRef newWatcherRefs
;
190 * Get the dictionary associated with this key out of the store
192 dict
= CFDictionaryGetValue(storeData
, watchedKey
);
193 if ((dict
== NULL
) || (CFDictionaryContainsKey(dict
, kSCDWatchers
) == FALSE
)) {
194 /* key doesn't exist (isn't this really fatal?) */
195 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" _removeWatcher: %@, %@, key not watched"), sessionNum
, watchedKey
);
198 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
201 * Get the set of watchers out of the keys dictionary and
202 * remove this session from the list.
204 watchers
= CFDictionaryGetValue(newDict
, kSCDWatchers
);
205 newWatchers
= CFArrayCreateMutableCopy(NULL
, 0, watchers
);
207 watcherRefs
= CFDictionaryGetValue(newDict
, kSCDWatcherRefs
);
208 newWatcherRefs
= CFArrayCreateMutableCopy(NULL
, 0, watcherRefs
);
210 /* locate the session reference */
211 i
= CFArrayGetFirstIndexOfValue(newWatchers
,
212 CFRangeMake(0, CFArrayGetCount(newWatchers
)),
215 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" _removeWatcher: %@, %@, session not watching"), sessionNum
, watchedKey
);
217 CFRelease(newWatchers
);
218 CFRelease(newWatcherRefs
);
222 /* remove one session reference */
223 refNum
= CFArrayGetValueAtIndex(newWatcherRefs
, i
);
224 CFNumberGetValue(refNum
, kCFNumberIntType
, &refCnt
);
226 refNum
= CFNumberCreate(NULL
, kCFNumberIntType
, &refCnt
);
227 CFArraySetValueAtIndex(newWatcherRefs
, i
, refNum
);
230 /* if this was the last reference */
231 CFArrayRemoveValueAtIndex(newWatchers
, i
);
232 CFArrayRemoveValueAtIndex(newWatcherRefs
, i
);
235 if (CFArrayGetCount(newWatchers
) > 0) {
236 /* if this key is still being "watched" */
237 CFDictionarySetValue(newDict
, kSCDWatchers
, newWatchers
);
238 CFDictionarySetValue(newDict
, kSCDWatcherRefs
, newWatcherRefs
);
240 /* no watchers left, remove the empty set */
241 CFDictionaryRemoveValue(newDict
, kSCDWatchers
);
242 CFDictionaryRemoveValue(newDict
, kSCDWatcherRefs
);
244 CFRelease(newWatchers
);
245 CFRelease(newWatcherRefs
);
247 if (CFDictionaryGetCount(newDict
) > 0) {
248 /* if this key is still active */
249 CFDictionarySetValue(storeData
, watchedKey
, newDict
);
251 /* no information left, remove the empty dictionary */
252 CFDictionaryRemoveValue(storeData
, watchedKey
);
256 SCLog(_configd_verbose
, LOG_DEBUG
, CFSTR(" _removeWatcher: %@, %@"), sessionNum
, watchedKey
);