xserver: Branch 'xorg-server-1.4-apple'

George Peter Staplin gstaplin at kemper.freedesktop.org
Tue Sep 23 11:48:20 PDT 2008


 hw/xquartz/pbproxy/main.m        |    5 -
 hw/xquartz/pbproxy/x-input.m     |    9 +
 hw/xquartz/pbproxy/x-selection.h |    4 
 hw/xquartz/pbproxy/x-selection.m |  183 ++++++++++++++++++---------------------
 4 files changed, 97 insertions(+), 104 deletions(-)

New commits:
commit b245d84a72ee3929546cd11a6eba3c60fb4a4d95
Author: George Peter Staplin <gps at Georges-Workstation.local>
Date:   Tue Sep 23 12:39:32 2008 -0600

    XQuartz: pbproxy: Fix NSObject memory leaks by properly using the
    NSAutoreleasePool.   Now the usage is consistent.  In x_input_run()
    we create a pool, and release it after processing the XEvents.
    
    Add some getpid() output to main for debugging.  It needs a bit more
    testing before the next release.
    
    Don't retain the NSPasteboard as the old code did.  That may have
    contributed to the leak, and it made it so that we needed the
    NSAutoreleasePool created in main().
    
    Remove the _known_types, and _pasteboard instance variables from
    the x_selection class.  They aren't needed anymore.
    
    The leaks program now indicates 0 leaks after some usage.  I want
    to test further, but this seems much better, and my memory usage
    graph indicates it's not growing.

diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m
index 6d49070..9bf19f0 100644
--- a/hw/xquartz/pbproxy/main.m
+++ b/hw/xquartz/pbproxy/main.m
@@ -7,6 +7,7 @@
 #import "x-selection.h"
 
 #include <pthread.h>
+#include <unistd.h> /*for getpid*/
 
 #include <X11/extensions/applewm.h>
 #include <HIServices/CoreDockServices.h>
@@ -130,9 +131,7 @@ static void signal_handler (int sig) {
 }
 
 int main (int argc, const char *argv[]) {
-    NSAutoreleasePool *pool;
-
-    pool = [[NSAutoreleasePool alloc] init];
+    printf("pid: %u\n", getpid());
     
     x_init ();
     
diff --git a/hw/xquartz/pbproxy/x-input.m b/hw/xquartz/pbproxy/x-input.m
index 5261212..fd59881 100644
--- a/hw/xquartz/pbproxy/x-input.m
+++ b/hw/xquartz/pbproxy/x-input.m
@@ -49,6 +49,13 @@ static void x_event_apple_wm_notify(XAppleWMNotifyEvent *e) {
 }
 
 void x_input_run (void) {
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    
+    if (nil == pool) 
+    {
+	fprintf(stderr, "unable to allocate/init auto release pool!\n");
+	return;
+    }
 
     while (XPending (x_dpy) != 0) {
         XEvent e;       
@@ -82,6 +89,8 @@ void x_input_run (void) {
 
 	XFlush(x_dpy);
     }
+
+    [pool release];
 }
 
 static int add_input_socket (int sock, CFOptionFlags callback_types,
diff --git a/hw/xquartz/pbproxy/x-selection.h b/hw/xquartz/pbproxy/x-selection.h
index 06910b4..1bb1f10 100644
--- a/hw/xquartz/pbproxy/x-selection.h
+++ b/hw/xquartz/pbproxy/x-selection.h
@@ -54,10 +54,6 @@ struct atom_list {
     /* The unmapped window we use for fetching selections. */
     Window _selection_window;
 
-    /* Cached general pasteboard and array of types we can handle. */
-    NSPasteboard *_pasteboard;
-    NSArray *_known_types;
-
     /* Last time we declared anything on the pasteboard. */
     int _my_last_change;
 
diff --git a/hw/xquartz/pbproxy/x-selection.m b/hw/xquartz/pbproxy/x-selection.m
index 5e40613..7e4bd7c 100644
--- a/hw/xquartz/pbproxy/x-selection.m
+++ b/hw/xquartz/pbproxy/x-selection.m
@@ -302,10 +302,18 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 {
     static NSInteger changeCount;
     NSInteger countNow;
+    NSPasteboard *pb;
 
     TRACE ();
 
-    countNow = [_pasteboard changeCount];
+    pb = [NSPasteboard generalPasteboard];
+
+    if (nil == pb)
+    {
+	return;
+    }
+
+    countNow = [pb changeCount];
 
     if (countNow != changeCount)
     {
@@ -317,8 +325,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
 
 #if 0
-    if ([_pasteboard changeCount] != _my_last_change)
-    {
 	/*gstaplin: we should perhaps investigate something like this branch above...*/
 	if ([_pasteboard availableTypeFromArray: _known_types] != nil)
 	{
@@ -330,7 +336,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    XSetSelectionOwner (x_dpy, XA_PRIMARY,
 				_selection_window, timestamp);
 	}
-    }
 #endif
 }
 
@@ -379,7 +384,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 /*
- *
+ * Set pbproxy as owner of the SELECTION_MANAGER selection.
+ * This prevents tools like xclipboard from causing havoc.
  */
 - (void) set_clipboard_manager
 {
@@ -508,19 +514,19 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
  * (in Latin-1 encoding).  The requestor can then make the choice based on
  * the list.
  */
-- (void) send_targets:(XSelectionRequestEvent *)e
+- (void) send_targets:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
     if (pbtypes)
     {
 	long list[6];
         long count = 0;
-	
+ 	
 	if ([pbtypes containsObject:NSStringPboardType])
 	{
 	    /* We have a string type that we can convert to UTF8, or Latin-1... */
@@ -561,7 +567,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 
-- (void) send_string:(XSelectionRequestEvent *)e utf8:(BOOL)utf8
+- (void) send_string:(XSelectionRequestEvent *)e utf8:(BOOL)utf8 pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -573,7 +579,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
  
     if (![pbtypes containsObject:NSStringPboardType])
     {
@@ -583,7 +589,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     DB ("pbtypes retainCount after containsObject: %u\n", [pbtypes retainCount]);
 
-    data = [_pasteboard stringForType:NSStringPboardType];
+    data = [pb stringForType:NSStringPboardType];
 
     if (nil == data)
     {
@@ -591,7 +597,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	return;
     }
 
-
     if (utf8) 
     {
 	bytes = [data UTF8String];
@@ -620,12 +625,10 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     
     reply.xselection.property = e->property;
 
-    DB ("data retainCount before release %u\n", [data retainCount]);
-    [data release];
     [self send_reply:&reply];
 }
 
-- (void) send_compound_text:(XSelectionRequestEvent *)e
+- (void) send_compound_text:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -634,11 +637,11 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     
     [self init_reply:&reply request:e];
      
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
 
     if ([pbtypes containsObject: NSStringPboardType])
     {
-	NSString *data = [_pasteboard stringForType:NSStringPboardType];
+	NSString *data = [pb stringForType:NSStringPboardType];
 	if (nil != data)
 	{
 	    /*
@@ -671,7 +674,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    if (textprop.value)
  		XFree (textprop.value);
 
-	    [data release];
 	}
     }
     
@@ -696,7 +698,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 }
 
 
-- (void) send_image:(XSelectionRequestEvent *)e
+- (void) send_image:(XSelectionRequestEvent *)e pasteboard:(NSPasteboard *)pb
 {
     XEvent reply;
     NSArray *pbtypes;
@@ -708,7 +710,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     [self init_reply:&reply request:e];
 
-    pbtypes = [_pasteboard types];
+    pbtypes = [pb types];
 
     if (pbtypes) 
     {
@@ -734,7 +736,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	return;
     }
 
-    data = [_pasteboard dataForType:type];
+    data = [pb dataForType:type];
 
     if (nil == data)
     {
@@ -751,7 +753,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 	if (nil == bmimage)
 	{
-	    [data release];
 	    [self send_reply:&reply];
 	    return;
 	}
@@ -775,20 +776,15 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 	    
 	    DB ("changed property for %s\n", XGetAtomName (x_dpy, e->target));
 	    DB ("encdata retainCount %u\n", [encdata retainCount]);
-	    [encdata release];
-	    [bmimage release];
 	}
 	DB ("dict retainCount before release %u\n", [dict retainCount]);
-	
-	[dict release];
+	[dict autorelease];
 
-	
 	DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
-	/*FIXME Why on earth is retainCount 3? */
-	[bmimage release];
-	[bmimage release];
+	
+	[bmimage autorelease];
     }
-    [data release];
+
     [self send_reply:&reply];
 }
 
@@ -806,6 +802,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 /* Another client requested the data or targets of data available from the clipboard. */
 - (void)request_event:(XSelectionRequestEvent *)e
 {
+    NSPasteboard *pb;
+
     TRACE ();
 
     /* TODO We should also keep track of the time of the selection, and 
@@ -820,29 +818,39 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     /*TODO we need a COMPOUND_TEXT test app*/
     /*TODO we need a MULTIPLE test app*/
+
+    pb = [NSPasteboard generalPasteboard];
+    if (nil == pb) 
+    {
+	[self send_none:e];
+	return;
+    }
+    
+
     if (None != e->target)
 	DB ("e->target %s\n", XGetAtomName (x_dpy, e->target));
 
     if (e->target == atoms->targets) 
     {
 	/* The paste requestor wants to know what TARGETS we support. */
-	[self send_targets:e];
+	[self send_targets:e pasteboard:pb];
     }
     else if (e->target == atoms->multiple)
     {
+	/* This isn't finished, and may never be, unless I can find a good app. */
 	[self send_multiple:e];
     } 
     else if (e->target == atoms->utf8_string)
     {
-	[self send_string:e utf8:YES];
+	[self send_string:e utf8:YES pasteboard:pb];
     } 
     else if (e->target == atoms->string)
     {
-	[self send_string:e utf8:NO];
+	[self send_string:e utf8:NO pasteboard:pb];
     }
     else if (e->target == atoms->compound_text)
     {
-	[self send_compound_text:e];
+	[self send_compound_text:e pasteboard:pb];
     }
     else if (e->target == atoms->multiple)
     {
@@ -850,9 +858,9 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     }
     else if (e->target == atoms->image_png || e->target == atoms->image_jpeg)
     {
-	[self send_image:e];
+	[self send_image:e pasteboard:pb];
     }
-    else 
+    else
     {
 	[self send_none:e];
     }
@@ -983,7 +991,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 /* This handles the image type of selection (typically in CLIPBOARD). */
 /* We convert to a TIFF, so that other applications can paste more easily. */
-- (void) handle_image: (struct propdata *)pdata
+- (void) handle_image: (struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSArray *pbtypes;
     NSUInteger length;
@@ -1008,7 +1016,7 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil == bmimage)
     {
-	[data release];
+	[data autorelease];
 	DB ("unable to create NSBitmapImageRep!\n");
 	return;
     }
@@ -1024,10 +1032,8 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     @catch (NSException *e) 
     {
 	DB ("NSTIFFException!\n");
-	[data release];
-	[bmimage release];
-	/*WHY 2?*/
-	[bmimage release];
+	[data autorelease];
+	[bmimage autorelease];
 	return;
     }
     
@@ -1037,40 +1043,29 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil == pbtypes)
     {
-	[tiff release];
-	[data release];
-	[bmimage release];
-	/* WHY is the object with a retainCount of 2 after initWithData? */
-	[bmimage release];
+	[data autorelease];
+	[bmimage autorelease];
 	return;
     }
 
- 
-    [_pasteboard declareTypes:pbtypes owner:self];
-    if (YES != [_pasteboard setData:tiff forType:NSTIFFPboardType])
+    [pb declareTypes:pbtypes owner:nil];
+    if (YES != [pb setData:tiff forType:NSTIFFPboardType])
     {
 	DB ("writing pasteboard data failed!\n");
     }
 
-    [pbtypes release];
-    [data release];
-
-    DB ("tiff retainCount before release %u\n", [tiff retainCount]);
-    [tiff release];
+    [data autorelease];
 
     DB ("bmimage retainCount before release %u\n", [bmimage retainCount]);
-    /*WHY 3?*/
-    [bmimage release];
-    [bmimage release];
-    [bmimage release];
+    [bmimage autorelease];
 }
 
 /* This handles the UTF8_STRING type of selection. */
-- (void) handle_utf8_string: (struct propdata *)pdata
+- (void) handle_utf8_string:(struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSString *string;
     NSArray *pbtypes;
-
+ 
     TRACE ();
 
     string = [[NSString alloc] initWithBytes:pdata->data length:pdata->length encoding:NSUTF8StringEncoding];
@@ -1078,26 +1073,25 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     if (nil == string)
 	return;
 
-    DB ("string retainCount is %u\n", [string retainCount]);
-
     pbtypes = [NSArray arrayWithObjects:NSStringPboardType, nil];
 
-    if (nil != pbtypes)
+    if (nil == pbtypes)
     {
-	[_pasteboard declareTypes:pbtypes owner:self];
-
-	if (YES != [_pasteboard setString:string forType:NSStringPboardType]) {
-	    DB ("_pasteboard setString:forType: failed!\n");
-	}
-	[pbtypes release];
+	[string autorelease];
+	return;	
     }
-    [string release];
 
+    [pb declareTypes:pbtypes owner:nil];
+    
+    if (YES != [pb setString:string forType:NSStringPboardType]) {
+	DB ("_pasteboard setString:forType: failed!\n");
+    }
+    [string autorelease];
     DB ("done handling utf8 string\n");
 }
 
 /* This handles the STRING type, which should be in Latin-1. */
-- (void) handle_string: (struct propdata *)pdata
+- (void) handle_string: (struct propdata *)pdata pasteboard:(NSPasteboard *)pb
 {
     NSString *string; 
     NSArray *pbtypes;
@@ -1113,47 +1107,55 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
     if (nil != pbtypes)
     {
-	[_pasteboard declareTypes:pbtypes owner:self];
-	[_pasteboard setString:string forType:NSStringPboardType];
-
-	DB ("pbtypes retainCount %u\n", [pbtypes retainCount]);
-	[pbtypes release];
+	[pb declareTypes:pbtypes owner:nil];
+	[pb setString:string forType:NSStringPboardType];
     }
-    [string release];
+    [string autorelease];
 }
 
 /* This is called when the selection is completely retrieved from another client. */
 /* Warning: this frees the propdata. */
 - (void) handle_selection:(Atom)selection type:(Atom)type propdata:(struct propdata *)pdata
 {
+    NSPasteboard *pb;
+
     TRACE ();
 
+    pb = [NSPasteboard generalPasteboard];
+
+    if (nil == pb) 
+    {
+	[self copy_completed:selection];
+	return;
+    }
+ 
     if (request_atom == atoms->targets && type == atoms->atom)
     {
 	[self handle_targets:selection propdata:pdata];
     } 
     else if (type == atoms->image_png)
     {
-	[self handle_image:pdata];
+	[self handle_image:pdata pasteboard:pb];
     } 
     else if (type == atoms->image_jpeg)
     {
-	[self handle_image:pdata];
+	[self handle_image:pdata pasteboard:pb];
     }
     else if (type == atoms->utf8_string) 
     {
-	[self handle_utf8_string:pdata];
+	[self handle_utf8_string:pdata pasteboard:pb];
     } 
     else if (type == atoms->string)
     {
-	[self handle_string:pdata];
+	[self handle_string:pdata pasteboard:pb];
     } 
  
     free_propdata(pdata);
-    
+
     [self copy_completed:selection];
 }
 
+
 - (void) copy_completed:(Atom)selection
 {
     TRACE ();
@@ -1243,11 +1245,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
     atoms->compound_text = XInternAtom (x_dpy, "COMPOUND_TEXT", False);
     atoms->atom_pair = XInternAtom (x_dpy, "ATOM_PAIR", False);
 
-    _pasteboard = [[NSPasteboard generalPasteboard] retain];
-
-    //_known_types = [[NSArray arrayWithObject:NSStringPboardType] retain];
-    _known_types = nil;
-
     pixel = BlackPixel (x_dpy, DefaultScreen (x_dpy));
     _selection_window = XCreateSimpleWindow (x_dpy, DefaultRootWindow (x_dpy),
 					     0, 0, 1, 1, 0, pixel, pixel);
@@ -1269,14 +1266,6 @@ get_property(Window win, Atom property, struct propdata *pdata, Bool delete, Ato
 
 - (void) dealloc
 {
-
-    [_pasteboard releaseGlobally];
-    [_pasteboard release];
-    _pasteboard = nil;
-
-    //[_known_types release];
-    _known_types = nil;
-
     if (None != _selection_window)
     {
 	XDestroyWindow (x_dpy, _selection_window);


More information about the xorg-commit mailing list