summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Peter Staplin <gps@Georges-Workstation.local>2008-09-23 12:39:32 -0600
committerJeremy Huddleston <jeremyhu@freedesktop.org>2008-09-26 12:31:06 -0700
commit586fbc91df731150ff5e39170efe33f3cfac28a2 (patch)
tree1f7ba0c2d55eb536296aac32cbb07245cfb8cf21
parent238999cfc99dbf306184f0e846465a8707bcc9d2 (diff)
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. (cherry picked from commit b245d84a72ee3929546cd11a6eba3c60fb4a4d95)
-rw-r--r--hw/xquartz/pbproxy/main.m5
-rw-r--r--hw/xquartz/pbproxy/x-input.m9
-rw-r--r--hw/xquartz/pbproxy/x-selection.h4
-rw-r--r--hw/xquartz/pbproxy/x-selection.m183
4 files changed, 97 insertions, 104 deletions
diff --git a/hw/xquartz/pbproxy/main.m b/hw/xquartz/pbproxy/main.m
index 6d4907056..9bf19f0a2 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 5261212e0..fd59881bb 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 06910b49b..1bb1f10f0 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 5e4061338..7e4bd7c70 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);