Changeset 22436
- Timestamp:
- 01/20/2008 10:04:53 AM (10 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/Plugins/Purple Service/adiumPurpleEventloop.m
r21519 r22436 25 25 26 26 static guint sourceId = 0; //The next source key; continuously incrementing 27 static NSMutableDictionary *sourceInfoDict = nil;28 27 static CFRunLoopRef purpleRunLoop = nil; 29 28 … … 34 33 void *infoVoid); 35 34 /* 36 * The sources, keyed by integer key id (wrapped in an NS Value), holding37 * struct sourceInfo* values (wrapped in an NSValue).35 * The sources, keyed by integer key id (wrapped in an NSNumber), holding 36 * SourceInfo * objects 38 37 */ 39 40 // The structure of values of sourceInfoDict 41 struct SourceInfo { 42 CFSocketRef socket; 43 int fd; 44 CFRunLoopSourceRef run_loop_source; 45 46 guint timer_tag; 47 GSourceFunc timer_function; 48 CFRunLoopTimerRef timer; 49 gpointer timer_user_data; 50 51 guint read_tag; 52 PurpleInputFunction read_ioFunction; 53 gpointer read_user_data; 54 55 guint write_tag; 56 PurpleInputFunction write_ioFunction; 57 gpointer write_user_data; 58 }; 59 60 struct SourceInfo *newSourceInfo(void) 61 { 62 struct SourceInfo *info = (struct SourceInfo*)malloc(sizeof(struct SourceInfo)); 38 static NSMutableDictionary *sourceInfoDict = nil; 39 40 /*! 41 * @class Holder for various source/timer information 42 * 43 * This serves as the context info for source and timer callbacks. We use it just as a 44 * struct (declaring all the class's ivars to be public) but make it an object so we can use 45 * reference counting on it easily. 46 */ 47 @interface SourceInfo : NSObject { 48 49 @public CFSocketRef socket; 50 @public int fd; 51 @public CFRunLoopSourceRef run_loop_source; 52 53 @public guint timer_tag; 54 @public GSourceFunc timer_function; 55 @public CFRunLoopTimerRef timer; 56 @public gpointer timer_user_data; 57 58 @public guint read_tag; 59 @public PurpleInputFunction read_ioFunction; 60 @public gpointer read_user_data; 61 62 @public guint write_tag; 63 @public PurpleInputFunction write_ioFunction; 64 @public gpointer write_user_data; 65 } 66 @end 67 68 @implementation SourceInfo 69 - (NSString *)description 70 { 71 return [NSString stringWithFormat:@"<SourceInfo %p: Socket %p: fd %i; timer_tag %i; read_tag %i; write_tag %i>", 72 self, socket, fd, timer_tag, read_tag, write_tag]; 73 } 74 @end 75 76 static SourceInfo *createSourceInfo(void) 77 { 78 SourceInfo *info = [[SourceInfo alloc] init]; 63 79 64 80 info->socket = NULL; … … 92 108 * This is necessary to prevent the now-unneeded condition from triggerring its callback. 93 109 */ 94 void updateSocketForSourceInfo( structSourceInfo *sourceInfo)110 void updateSocketForSourceInfo(SourceInfo *sourceInfo) 95 111 { 96 112 CFSocketRef socket = sourceInfo->socket; … … 121 137 122 138 gboolean adium_source_remove(guint tag) { 123 struct SourceInfo *sourceInfo = (struct SourceInfo*) 124 [[sourceInfoDict objectForKey:[NSNumber numberWithUnsignedInt:tag]] pointerValue]; 139 SourceInfo *sourceInfo = (SourceInfo *)[sourceInfoDict objectForKey:[NSNumber numberWithUnsignedInt:tag]]; 125 140 126 141 if (sourceInfo) { … … 139 154 140 155 } 141 142 [sourceInfoDict removeObjectForKey:[NSNumber numberWithUnsignedInt:tag]];143 156 144 157 if (sourceInfo->timer_tag == 0 && sourceInfo->read_tag == 0 && sourceInfo->write_tag == 0) { … … 161 174 CFRelease(sourceInfo->run_loop_source); 162 175 } 163 164 free(sourceInfo);165 176 } else { 166 177 if ((sourceInfo->timer_tag == 0) && (sourceInfo->timer)) { … … 177 188 } 178 189 } 190 191 [sourceInfoDict removeObjectForKey:[NSNumber numberWithUnsignedInt:tag]]; 179 192 180 193 return TRUE; … … 193 206 void callTimerFunc(CFRunLoopTimerRef timer, void *info) 194 207 { 195 structSourceInfo *sourceInfo = info;208 SourceInfo *sourceInfo = info; 196 209 197 210 if (!sourceInfo->timer_function || … … 203 216 guint adium_timeout_add(guint interval, GSourceFunc function, gpointer data) 204 217 { 205 struct SourceInfo *info = newSourceInfo();218 SourceInfo *info = createSourceInfo(); 206 219 207 220 NSTimeInterval intervalInSec = (NSTimeInterval)interval/1000; 208 CFRunLoopTimerContext runLoopTimerContext = { 0, info, NULL, NULL, NULL }; 221 222 CFRunLoopTimerContext runLoopTimerContext = { 0, info, CFRetain, CFRelease, /* CFAllocatorCopyDescriptionCallBack */ NULL }; 209 223 CFRunLoopTimerRef runLoopTimer = CFRunLoopTimerCreate( 210 kCFAllocatorDefault, /* default allocator */224 NULL, /* default allocator */ 211 225 (CFAbsoluteTimeGetCurrent() + intervalInSec), /* The time at which the timer should first fire */ 212 226 intervalInSec, /* firing interval */ … … 217 231 ); 218 232 CFRunLoopAddTimer(purpleRunLoop, runLoopTimer, kCFRunLoopCommonModes); 219 233 [info release]; 234 220 235 info->timer_function = function; 221 236 info->timer = runLoopTimer; … … 223 238 info->timer_tag = ++sourceId; 224 239 225 [sourceInfoDict setObject: [NSValue valueWithPointer:info]240 [sourceInfoDict setObject:info 226 241 forKey:[NSNumber numberWithUnsignedInt:info->timer_tag]]; 227 242 … … 237 252 } 238 253 239 struct SourceInfo *info = newSourceInfo();254 SourceInfo *info = createSourceInfo(); 240 255 241 256 // And likewise the entire CFSocket 242 CFSocketContext context = { 0, info, /* CFAllocatorRetainCallBack */ NULL, /* CFAllocatorReleaseCallBack */ NULL, /* CFAllocatorCopyDescriptionCallBack */ NULL };257 CFSocketContext context = { 0, info, CFRetain, CFRelease, /* CFAllocatorCopyDescriptionCallBack */ NULL }; 243 258 244 259 /* … … 250 265 AILog(@"adium_input_add(): Adding input %i on fd %i", condition, fd); 251 266 #endif 252 CFSocketRef socket = CFSocketCreateWithNative( kCFAllocatorDefault,267 CFSocketRef socket = CFSocketCreateWithNative(NULL, 253 268 fd, 254 269 (kCFSocketReadCallBack | kCFSocketWriteCallBack), … … 263 278 CFSocketGetContext(socket, &actualSocketContext); 264 279 if (actualSocketContext.info != info) { 265 free(info);280 [info release]; 266 281 CFRelease(socket); 267 info = actualSocketContext.info;282 info = [(SourceInfo *)(actualSocketContext.info) retain]; 268 283 } 269 284 … … 276 291 info->read_user_data = user_data; 277 292 278 [sourceInfoDict setObject: [NSValue valueWithPointer:info]293 [sourceInfoDict setObject:info 279 294 forKey:[NSNumber numberWithUnsignedInt:info->read_tag]]; 280 295 … … 284 299 info->write_user_data = user_data; 285 300 286 [sourceInfoDict setObject: [NSValue valueWithPointer:info]301 [sourceInfoDict setObject:info 287 302 forKey:[NSNumber numberWithUnsignedInt:info->write_tag]]; 288 303 } … … 292 307 //Add it to our run loop 293 308 if (!(info->run_loop_source)) { 294 info->run_loop_source = CFSocketCreateRunLoopSource( kCFAllocatorDefault, socket, 0);309 info->run_loop_source = CFSocketCreateRunLoopSource(NULL, socket, 0); 295 310 if (info->run_loop_source) { 296 311 CFRunLoopAddSource(purpleRunLoop, info->run_loop_source, kCFRunLoopCommonModes); … … 299 314 } 300 315 } 316 317 [info release]; 301 318 302 319 return sourceId; … … 310 327 void *infoVoid) 311 328 { 312 struct SourceInfo *sourceInfo = (struct SourceInfo*)infoVoid;329 SourceInfo *sourceInfo = (SourceInfo *)infoVoid; 313 330 gpointer user_data; 314 331 PurpleInputCondition c;