adium 3936:af2c953c613e: Merged

commits at adium.im commits at adium.im
Fri Jun 17 23:40:44 UTC 2011


details:	http://hg.adium.im/adium/rev/af2c953c613e
revision:	3936:af2c953c613e
branch:		(none)
author:		Thijs Alkemade <thijsalkemade at gmail.com>
date:		Sat Jun 18 01:35:01 2011 +0200

Merged

diffs (498 lines):

diff -r cebc5ee744ee -r af2c953c613e Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj	Thu Jun 16 00:40:14 2011 +0200
+++ b/Adium.xcodeproj/project.pbxproj	Sat Jun 18 01:35:01 2011 +0200
@@ -3046,7 +3046,7 @@
 		346C9C200E70E1F8002314EE /* hu */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = hu; path = "Plugins/WebKit Message View/hu.lproj/WebKitPreferencesView.nib"; sourceTree = "<group>"; };
 		346CFDC4087B7836009711C8 /* AdiumIdleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AdiumIdleManager.h; path = Source/AdiumIdleManager.h; sourceTree = "<group>"; };
 		346CFDC5087B7836009711C8 /* AdiumIdleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AdiumIdleManager.m; path = Source/AdiumIdleManager.m; sourceTree = "<group>"; };
-		346F5CB308A418FB0055C610 /* CurrentTunes.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = CurrentTunes.scpt; path = Resources/CurrentTunes.scpt; sourceTree = "<group>"; };
+		346F5CB308A418FB0055C610 /* CurrentTunes.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = file; name = CurrentTunes.scpt; path = Resources/CurrentTunes.scpt; sourceTree = "<group>"; };
 		347065E406015DC5004F0D20 /* WebKit Defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; name = "WebKit Defaults.plist"; path = "Plugins/WebKit Message View/WebKit Defaults.plist"; sourceTree = "<group>"; };
 		347374BC0AA9206B00AD18E3 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = Resources/en.lproj/ShortcutRecorder.strings; sourceTree = "<group>"; };
 		347374F00AA920F300AD18E3 /* ca */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = ca; path = Resources/ca.lproj/ShortcutRecorder.strings; sourceTree = "<group>"; };
@@ -3831,7 +3831,7 @@
 		34F4675B080F46AC007800AB /* ESBonjourAccountView.nib */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; path = ESBonjourAccountView.nib; sourceTree = "<group>"; };
 		34F4675C080F46AC007800AB /* AWBonjourService.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AWBonjourService.m; sourceTree = "<group>"; };
 		34F4675D080F46AC007800AB /* AWBonjourService.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AWBonjourService.h; sourceTree = "<group>"; };
-		34F46778080F49C5007800AB /* Safari.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.scpt; name = Safari.scpt; path = Resources/Safari.scpt; sourceTree = "<group>"; };
+		34F46778080F49C5007800AB /* Safari.scpt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = file; name = Safari.scpt; path = Resources/Safari.scpt; sourceTree = "<group>"; };
 		34F46779080F49C5007800AB /* Safari.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Safari.png; path = Resources/Safari.png; sourceTree = "<group>"; };
 		34F46783080F7FFB007800AB /* ESSafariLinkToolbarItemPlugin.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = ESSafariLinkToolbarItemPlugin.m; path = Source/ESSafariLinkToolbarItemPlugin.m; sourceTree = "<group>"; };
 		34F46784080F7FFB007800AB /* ESSafariLinkToolbarItemPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ESSafariLinkToolbarItemPlugin.h; path = Source/ESSafariLinkToolbarItemPlugin.h; sourceTree = "<group>"; };
@@ -4491,12 +4491,12 @@
 		6360B2590BF2EB93004CD99B /* AIWebKitDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIWebKitDelegate.m; path = "Plugins/WebKit Message View/AIWebKitDelegate.m"; sourceTree = "<group>"; };
 		636C6E5D0ED56D0100E0E528 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = /usr/lib/libcrypto.dylib; sourceTree = "<absolute>"; };
 		636D8C970E4E95A500E5F558 /* AIAddressBookController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIAddressBookController.m; path = "Frameworks/Adium Framework/Source/AIAddressBookController.m"; sourceTree = "<group>"; };
-		636D93660E4E9FD300E5F558 /* AdiumAddressBookAction_Yahoo.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_Yahoo.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_Yahoo.scpt"; sourceTree = "<group>"; };
-		636D93670E4E9FD300E5F558 /* AdiumAddressBookAction_SMS.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_SMS.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_SMS.scpt"; sourceTree = "<group>"; };
-		636D93680E4E9FD300E5F558 /* AdiumAddressBookAction_MSN.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_MSN.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_MSN.scpt"; sourceTree = "<group>"; };
-		636D93690E4E9FD300E5F558 /* AdiumAddressBookAction_Jabber.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_Jabber.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_Jabber.scpt"; sourceTree = "<group>"; };
-		636D936A0E4E9FD300E5F558 /* AdiumAddressBookAction_ICQ.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_ICQ.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_ICQ.scpt"; sourceTree = "<group>"; };
-		636D936B0E4E9FD300E5F558 /* AdiumAddressBookAction_AIM.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.scpt; name = AdiumAddressBookAction_AIM.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_AIM.scpt"; sourceTree = "<group>"; };
+		636D93660E4E9FD300E5F558 /* AdiumAddressBookAction_Yahoo.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_Yahoo.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_Yahoo.scpt"; sourceTree = "<group>"; };
+		636D93670E4E9FD300E5F558 /* AdiumAddressBookAction_SMS.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_SMS.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_SMS.scpt"; sourceTree = "<group>"; };
+		636D93680E4E9FD300E5F558 /* AdiumAddressBookAction_MSN.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_MSN.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_MSN.scpt"; sourceTree = "<group>"; };
+		636D93690E4E9FD300E5F558 /* AdiumAddressBookAction_Jabber.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_Jabber.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_Jabber.scpt"; sourceTree = "<group>"; };
+		636D936A0E4E9FD300E5F558 /* AdiumAddressBookAction_ICQ.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_ICQ.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_ICQ.scpt"; sourceTree = "<group>"; };
+		636D936B0E4E9FD300E5F558 /* AdiumAddressBookAction_AIM.scpt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file; name = AdiumAddressBookAction_AIM.scpt; path = "Frameworks/Adium Framework/Resources/AdiumAddressBookAction_AIM.scpt"; sourceTree = "<group>"; };
 		638392F609D4D67A0067B9B7 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Sparkle.framework; path = Frameworks/Sparkle.framework; sourceTree = "<group>"; };
 		638BC1FA0FC932E000CE7600 /* AIObjectDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIObjectDebug.h; path = Source/AIObjectDebug.h; sourceTree = "<group>"; };
 		638BC1FB0FC932E000CE7600 /* AIObjectDebug.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AIObjectDebug.m; path = Source/AIObjectDebug.m; sourceTree = "<group>"; };
@@ -9457,6 +9457,7 @@
 			};
 			buildConfigurationList = DADE8E3A085507450062B664 /* Build configuration list for PBXProject "Adium" */;
 			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				en,
diff -r cebc5ee744ee -r af2c953c613e Plugins/Purple Service/adiumPurpleEventloop.m
--- a/Plugins/Purple Service/adiumPurpleEventloop.m	Thu Jun 16 00:40:14 2011 +0200
+++ b/Plugins/Purple Service/adiumPurpleEventloop.m	Sat Jun 18 01:35:01 2011 +0200
@@ -21,244 +21,74 @@
 #import <sys/socket.h>
 #import <sys/select.h>
 
+#include <dispatch/dispatch.h>
+
 //#define PURPLE_SOCKET_DEBUG
 
 static guint				sourceId = 0;		//The next source key; continuously incrementing
-static CFRunLoopRef			purpleRunLoop = nil;
 
-static void socketCallback(CFSocketRef s,
-                           CFSocketCallBackType callbackType,
-                           CFDataRef address,
-                           const void *data,
-                           void *infoVoid);
 /*
  * The sources, keyed by integer key id (wrapped in an NSNumber), holding
- * SourceInfo * objects
+ * NSVaue*'s with pointers to dispatch_source_ts. (The tags are guints (32 bits),
+ * so too small to hold an NSValue* or dispatch_source_t on x86.
  */
 static NSMutableDictionary	*sourceInfoDict = nil;
 
-/*!
- * @class SourceInfo
- * @brief Holder for various source/timer information
- *
- * This serves as the context info for source and timer callbacks.  We use it just as a
- * struct (declaring all the class's ivars to be public) but make it an object so we can use
- * reference counting on it easily.
- */
- at interface SourceInfo : NSObject {
+gboolean adium_source_remove(guint tag) {
+	
+	NSValue *srcPointer = [sourceInfoDict objectForKey:[NSNumber numberWithInt:tag]];
+	
+    if (!srcPointer) {
+		NSLog(@"Source info for %i not found in %@", tag, sourceInfoDict);
+		return FALSE;
+	}
+	
+	dispatch_source_t src = (dispatch_source_t)[srcPointer pointerValue];
+    dispatch_source_cancel(src);
+    dispatch_release(src);
+	
+    [sourceInfoDict removeObjectForKey:[NSNumber numberWithInt:tag]];
 
- at public	CFSocketRef socket;
- at public	gint fd;
- at public	CFRunLoopSourceRef run_loop_source;
-	
- at public	guint timer_tag;
- at public	GSourceFunc timer_function;
- at public	CFRunLoopTimerRef timer;
- at public	gpointer timer_user_data;
-	
- at public	guint read_tag;
- at public	PurpleInputFunction read_ioFunction;
- at public	gpointer read_user_data;
-	
- at public	guint write_tag;
- at public	PurpleInputFunction write_ioFunction;
- at public	gpointer write_user_data;	
-}
- at end
-
- at implementation SourceInfo
-- (NSString *)description
-{
-	return [NSString stringWithFormat:@"<SourceInfo %p: Socket %p: fd %i; timer_tag %i; read_tag %i; write_tag %i>",
-			self, socket, fd, timer_tag, read_tag, write_tag];
-}
- at end
-
-static SourceInfo *createSourceInfo(void)
-{
-	SourceInfo *info = [[SourceInfo alloc] init];
-
-	info->socket = NULL;
-	info->fd = 0;
-	info->run_loop_source = NULL;
-
-	info->timer_tag = 0;
-	info->timer_function = NULL;
-	info->timer = NULL;
-	info->timer_user_data = NULL;
-
-	info->write_tag = 0;
-	info->write_ioFunction = NULL;
-	info->write_user_data = NULL;
-
-	info->read_tag = 0;
-	info->read_ioFunction = NULL;
-	info->read_user_data = NULL;	
-	
-	return info;
-}
-
-#pragma mark Remove
-
-/*!
- * @brief Given a SourceInfo struct for a socket which was for reading *and* writing, recreate its socket to be for just one
- *
- * If the sourceInfo still has a read_tag, the resulting CFSocket will be just for reading.
- * If the sourceInfo still has a write_tag, the resulting CFSocket will be just for writing.
- *
- * This is necessary to prevent the now-unneeded condition from triggerring its callback.
- */
-void updateSocketForSourceInfo(SourceInfo *sourceInfo)
-{
-	CFSocketRef sourceSocket = sourceInfo->socket;
-	
-	if (!sourceSocket) return;
-
-	//Reading
-#ifdef PURPLE_SOCKET_DEBUG
-	AILogWithSignature(@"%@", sourceInfo);
-#endif
-	if (sourceInfo->read_tag)
-		CFSocketEnableCallBacks(sourceSocket, kCFSocketReadCallBack);
-	else
-		CFSocketDisableCallBacks(sourceSocket, kCFSocketReadCallBack);
-
-	//Writing
-	if (sourceInfo->write_tag)
-		CFSocketEnableCallBacks(sourceSocket, kCFSocketWriteCallBack);
-	else
-		CFSocketDisableCallBacks(sourceSocket, kCFSocketWriteCallBack);
-	
-	//Re-enable callbacks automatically and, by starting with 0, _don't_ close the socket on invalidate
-	CFOptionFlags flags = 0;
-	
-	if (sourceInfo->read_tag) flags |= kCFSocketAutomaticallyReenableReadCallBack;
-	if (sourceInfo->write_tag) flags |= kCFSocketAutomaticallyReenableWriteCallBack;
-	
-	CFSocketSetSocketFlags(sourceSocket, flags);
-}
-
-gboolean adium_source_remove(guint tag) {
-	NSNumber *tagNumber = [[NSNumber alloc] initWithUnsignedInteger:tag];
-    SourceInfo *sourceInfo = (SourceInfo *)[sourceInfoDict objectForKey:tagNumber];
-	BOOL didRemove;
-
-    if (sourceInfo) {
-#ifdef PURPLE_SOCKET_DEBUG
-		AILog(@"adium_source_remove(): Removing for fd %i [sourceInfo %x]: tag is %i (timer %i, read %i, write %i)",sourceInfo->fd,
-			  sourceInfo, tag, sourceInfo->timer_tag, sourceInfo->read_tag, sourceInfo->write_tag);
-#endif
-		if (sourceInfo->timer_tag == tag) {
-			sourceInfo->timer_tag = 0;
-
-		} else if (sourceInfo->read_tag == tag) {
-			sourceInfo->read_tag = 0;
-
-		} else if (sourceInfo->write_tag == tag) {
-			sourceInfo->write_tag = 0;
-
-		}
-		
-		if (sourceInfo->timer_tag == 0 && sourceInfo->read_tag == 0 && sourceInfo->write_tag == 0) {
-			//It's done
-			if (sourceInfo->timer) { 
-				CFRunLoopTimerInvalidate(sourceInfo->timer);
-				CFRelease(sourceInfo->timer);
-				sourceInfo->timer = NULL;
-			}
-			
-			if (sourceInfo->socket) {
-#ifdef PURPLE_SOCKET_DEBUG
-				AILog(@"adium_source_remove(): Done with a socket %x, so invalidating it",sourceInfo->socket);
-#endif
-				CFSocketInvalidate(sourceInfo->socket);
-				CFRelease(sourceInfo->socket);
-				sourceInfo->socket = NULL;
-			}
-
-			if (sourceInfo->run_loop_source) {
-				CFRelease(sourceInfo->run_loop_source);
-				sourceInfo->run_loop_source = NULL;
-			}
-		} else {
-			if ((sourceInfo->timer_tag == 0) && (sourceInfo->timer)) {
-				CFRunLoopTimerInvalidate(sourceInfo->timer);
-				CFRelease(sourceInfo->timer);
-				sourceInfo->timer = NULL;
-			}
-			
-			if (sourceInfo->socket && (sourceInfo->read_tag || sourceInfo->write_tag)) {
-#ifdef PURPLE_SOCKET_DEBUG
-				AILog(@"adium_source_remove(): Calling updateSocketForSourceInfo(%x)",sourceInfo);
-#endif				
-				updateSocketForSourceInfo(sourceInfo);
-			}
-		}
-		
-		[sourceInfoDict removeObjectForKey:tagNumber];
-
-		didRemove = TRUE;
-
-	} else {
-		didRemove = FALSE;
-	}
-
-	[tagNumber release];
-
-	return didRemove;
+	return (dispatch_source_testcancel(src) != 0);
 }
 
 //Like g_source_remove, return TRUE if successful, FALSE if not
 gboolean adium_timeout_remove(guint tag) {
-    return (adium_source_remove(tag));
+    return adium_source_remove(tag);
 }
 
-#pragma mark Add
+guint addTimer(uint64_t interval, uint64_t leeway, GSourceFunc function, gpointer data)
+{
+	dispatch_source_t src;
+	guint tag;
+	
+    tag = ++sourceId;
+    
+    src = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
+	
+    dispatch_source_set_timer(src, dispatch_time(DISPATCH_TIME_NOW, interval), interval, leeway);
+	
+    dispatch_source_set_event_handler(src, ^{
+        if (!function || !function(data))
+			adium_timeout_remove(tag);
+    });
+	
+    [sourceInfoDict setObject:[NSValue valueWithPointer:src]
+                       forKey:[NSNumber numberWithUnsignedInt:tag]];
+	
+    dispatch_resume(src);
 
-void callTimerFunc(CFRunLoopTimerRef timer, void *info)
-{
-	SourceInfo *sourceInfo = info;
-
-	if (![sourceInfoDict objectForKey:[NSNumber numberWithUnsignedInteger:sourceInfo->timer_tag]])
-		NSLog(@"**** WARNING: %@ has already been removed, but we're calling its timer function!", info);
-
-	if (!sourceInfo->timer_function ||
-		!sourceInfo->timer_function(sourceInfo->timer_user_data)) {
-        adium_source_remove(sourceInfo->timer_tag);
-	}
+    return tag;
 }
 
 guint adium_timeout_add(guint interval, GSourceFunc function, gpointer data)
 {
-    SourceInfo *info = createSourceInfo();
-	
-	NSTimeInterval intervalInSec = (NSTimeInterval)interval/1000;
-	
-	CFRunLoopTimerContext runLoopTimerContext = { 0, info, CFRetain, CFRelease, /* CFAllocatorCopyDescriptionCallBack */ NULL };
-	CFRunLoopTimerRef runLoopTimer = CFRunLoopTimerCreate(
-														  NULL, /* default allocator */
-														  (CFAbsoluteTimeGetCurrent() + intervalInSec), /* The time at which the timer should first fire */
-														  intervalInSec, /* firing interval */
-														  0, /* flags, currently ignored */
-														  0, /* order, currently ignored */
-														  callTimerFunc, /* CFRunLoopTimerCallBack callout */
-														  &runLoopTimerContext /* context */
-														  );
-	guint timer_tag = ++sourceId;
-	info->timer_function = function;
-	info->timer = runLoopTimer;
-	info->timer_user_data = data;	
-	info->timer_tag = timer_tag;
+	return addTimer(((uint64_t)interval) * (NSEC_PER_SEC / 1000), NSEC_PER_USEC, function, data);
+}
 
-	NSNumber *tagNumber = [[NSNumber alloc] initWithUnsignedInteger:timer_tag];
-	[sourceInfoDict setObject:info
-					   forKey:tagNumber];
-	[tagNumber release];
-
-	CFRunLoopAddTimer(purpleRunLoop, runLoopTimer, kCFRunLoopCommonModes);
-	[info release];
-
-	return timer_tag;
+guint adium_timeout_add_seconds(guint interval, GSourceFunc function, gpointer data)
+{
+	return addTimer(((uint64_t)interval) * NSEC_PER_SEC, NSEC_PER_SEC, function, data);
 }
 
 guint adium_input_add(gint fd, PurpleInputCondition condition,
@@ -269,118 +99,30 @@
 		return ++sourceId;
 	}
 
-    SourceInfo *info = createSourceInfo();
+	dispatch_source_t src;
+	guint tag;
+	dispatch_source_type_t type;
 	
-    // And likewise the entire CFSocket
-    CFSocketContext context = { 0, info, CFRetain, CFRelease, /* CFAllocatorCopyDescriptionCallBack */ NULL };
-
-	/*
-	 * From CFSocketCreateWithNative:
-	 * If a socket already exists on this fd, CFSocketCreateWithNative() will return that existing socket, and the other parameters
-	 * will be ignored.
-	 */
-#ifdef PURPLE_SOCKET_DEBUG
-	AILog(@"adium_input_add(): Adding input %i on fd %i", condition, fd);
-#endif
-	CFSocketRef newSocket = CFSocketCreateWithNative(NULL,
-												  fd,
-												  (kCFSocketReadCallBack | kCFSocketWriteCallBack),
-												  socketCallback,
-												  &context);
-
-	/* If we did not create a *new* socket, it is because there is already one for this fd in the run loop.
-	 * See the CFSocketCreateWithNative() documentation), add it to the run loop.
-	 * In that case, the socket's info was not updated.
-	 */
-	CFSocketContext actualSocketContext = { 0, NULL, NULL, NULL, NULL };
-	CFSocketGetContext(newSocket, &actualSocketContext);
-	if (actualSocketContext.info != info) {
-		[info release];
-		CFRelease(newSocket);
-		info = [(SourceInfo *)(actualSocketContext.info) retain];
-	}
-
-	info->fd = fd;
-	info->socket = newSocket;
-
-    if ((condition & PURPLE_INPUT_READ)) {
-		info->read_tag = ++sourceId;
-		info->read_ioFunction = func;
-		info->read_user_data = user_data;
-		
-		NSNumber *tagNumber = [[NSNumber alloc] initWithUnsignedInteger:info->read_tag];
-		[sourceInfoDict setObject:info
-						   forKey:tagNumber];
-		[tagNumber release];
-		
+    tag = ++sourceId;
+	
+	if (condition == PURPLE_INPUT_READ) {
+		type = DISPATCH_SOURCE_TYPE_READ;
 	} else {
-		info->write_tag = ++sourceId;
-		info->write_ioFunction = func;
-		info->write_user_data = user_data;
-		
-		NSNumber *tagNumber = [[NSNumber alloc] initWithUnsignedInteger:info->write_tag];
-		[sourceInfoDict setObject:info
-						   forKey:tagNumber];
-		[tagNumber release];
+		type = DISPATCH_SOURCE_TYPE_WRITE;
 	}
 	
-	updateSocketForSourceInfo(info);
+    src = dispatch_source_create(type, fd, 0, dispatch_get_main_queue());
 	
-	//Add it to our run loop
-	if (!(info->run_loop_source)) {
-		info->run_loop_source = CFSocketCreateRunLoopSource(NULL, newSocket, 0);
-		if (info->run_loop_source) {
-			CFRunLoopAddSource(purpleRunLoop, info->run_loop_source, kCFRunLoopCommonModes);
-		} else {
-			AILog(@"*** Unable to create run loop source for %p",newSocket);
-		}		
-	}
+    dispatch_source_set_event_handler(src, ^{
+        if (func) func(user_data, fd, condition);
+    });
+		
+    [sourceInfoDict setObject:[NSValue valueWithPointer:src]
+                       forKey:[NSNumber numberWithUnsignedInt:tag]];
 
-	[info release];
-
-    return sourceId;
-}
-
-#pragma mark Socket Callback
-static void socketCallback(CFSocketRef s,
-						   CFSocketCallBackType callbackType,
-						   CFDataRef address,
-						   const void *data,
-						   void *infoVoid)
-{
-    SourceInfo *sourceInfo = (SourceInfo *)infoVoid;
-	gpointer user_data;
-    PurpleInputCondition c;
-	PurpleInputFunction ioFunction = NULL;
-	gint	 fd = sourceInfo->fd;
-
-    if ((callbackType & kCFSocketReadCallBack)) {
-		if (sourceInfo->read_tag) {
-			user_data = sourceInfo->read_user_data;
-			c = PURPLE_INPUT_READ;
-			ioFunction = sourceInfo->read_ioFunction;
-		} else {
-			AILog(@"Called read with no read_tag %@", sourceInfo);
-		}
-
-	} else /* if ((callbackType & kCFSocketWriteCallBack)) */ {
-		if (sourceInfo->write_tag) {
-			user_data = sourceInfo->write_user_data;
-			c = PURPLE_INPUT_WRITE;	
-			ioFunction = sourceInfo->write_ioFunction;
-		} else {
-			AILog(@"Called write with no write_tag %@", sourceInfo);
-		}
-	}
-
-	if (ioFunction) {
-#ifdef PURPLE_SOCKET_DEBUG
-		AILog(@"socketCallback(): Calling the ioFunction for %x, callback type %i (%s: tag is %i)",s,callbackType,
-			  ((callbackType & kCFSocketReadCallBack) ? "reading" : "writing"),
-			  ((callbackType & kCFSocketReadCallBack) ? sourceInfo->read_tag : sourceInfo->write_tag));
-#endif
-		ioFunction(user_data, fd, c);
-	}
+	dispatch_resume(src);
+	
+    return tag;
 }
 
 int adium_input_get_error(int fd, int *error)
@@ -436,7 +178,7 @@
     adium_input_add,
     adium_source_remove,
 	adium_input_get_error,
-	/* timeout_add_seconds */ NULL,
+	adium_timeout_add_seconds,
 	/* _purple_reserved2 */ NULL,
 	/* _purple_reserved3 */ NULL,
 	/* _purple_reserved4 */ NULL
@@ -446,9 +188,5 @@
 {
 	if (!sourceInfoDict) sourceInfoDict = [[NSMutableDictionary alloc] init];
 
-	//Determine our run loop
-	purpleRunLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
-	CFRetain(purpleRunLoop);
-
 	return &adiumEventLoopUiOps;
 }




More information about the commits mailing list