From c8b09927b5ae87b19e8880614ac2b23e3c0df6e6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Mon, 4 Nov 2013 18:57:17 +0100 Subject: [PATCH] Fix memory leaks in NS version. * src/macfont.m (CG_SET_FILL_COLOR_WITH_GC_FOREGROUND) (CG_SET_FILL_COLOR_WITH_GC_BACKGROUND) (CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND): Fix memory leak. * src/nsfns.m (Fx_create_frame): Fix memory leak. * src/nsterm.h (EmacsApp): Add shouldKeepRunning and isFirst for OSX >= 10.9. * src/nsterm.m (init, run, stop:): New methods in EmacsApp for OSX >= 10.9 to prevent memory leak of GCD dispatch source. --- src/ChangeLog | 14 ++++++++++++++ src/macfont.m | 29 ++++++++++++++++++----------- src/nsfns.m | 1 + src/nsterm.h | 4 ++++ src/nsterm.m | 40 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 11 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index e27f83962af..5f919b8516d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2013-11-04 Jan Djärv + + * nsterm.m (init, run, stop:): New methods in EmacsApp for + OSX >= 10.9 to prevent memory leak of GCD dispatch source. + + * nsterm.h (EmacsApp): Add shouldKeepRunning and isFirst for + OSX >= 10.9. + + * nsfns.m (Fx_create_frame): Fix memory leak. + + * macfont.m (CG_SET_FILL_COLOR_WITH_GC_FOREGROUND) + (CG_SET_FILL_COLOR_WITH_GC_BACKGROUND) + (CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND): Fix memory leak. + 2013-11-04 Eli Zaretskii * xdisp.c (message3_nolog, message_with_string): Encode the string diff --git a/src/macfont.m b/src/macfont.m index 150aca07651..4b8be551786 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -624,19 +624,26 @@ get_cgcolor(unsigned long idx, struct frame *f) } #define CG_SET_FILL_COLOR_WITH_GC_FOREGROUND(context, s) \ - CGContextSetFillColorWithColor (context, \ - get_cgcolor (NS_FACE_FOREGROUND (s->face), \ - s->f)) - + do { \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (s->face), \ + s->f); \ + CGContextSetFillColorWithColor (context, refcol_) ; \ + CGColorRelease (refcol_); \ + } while (0) #define CG_SET_FILL_COLOR_WITH_GC_BACKGROUND(context, s) \ - CGContextSetFillColorWithColor (context, \ - get_cgcolor (NS_FACE_BACKGROUND (s->face), \ - s->f)) - + do { \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_BACKGROUND (s->face),\ + s->f); \ + CGContextSetFillColorWithColor (context, refcol_); \ + CGColorRelease (refcol_); \ + } while (0) #define CG_SET_STROKE_COLOR_WITH_GC_FOREGROUND(context, s) \ - CGContextSetStrokeColorWithColor (context, \ - get_cgcolor (NS_FACE_FOREGROUND (s->face),\ - s->f)) + do { \ + CGColorRef refcol_ = get_cgcolor (NS_FACE_FOREGROUND (s->face),\ + s->f); \ + CGContextSetStrokeColorWithColor (context, refcol_); \ + CGColorRelease (refcol_); \ + } while (0) /* Mac font driver. */ diff --git a/src/nsfns.m b/src/nsfns.m index 011edf38cef..c6730f41aa7 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -1194,6 +1194,7 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qfont, build_string (fontname), "font", "Font", RES_TYPE_STRING); + xfree (fontname); } unblock_input (); diff --git a/src/nsterm.h b/src/nsterm.h index 71faa075f32..22a8aec9436 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -85,6 +85,10 @@ typedef float EmacsCGFloat; /* We override sendEvent: as a means to stop/start the event loop */ @interface EmacsApp : NSApplication { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 + BOOL shouldKeepRunning; + BOOL isFirst; +#endif #ifdef NS_IMPL_GNUSTEP @public int nextappdefined; diff --git a/src/nsterm.m b/src/nsterm.m index 5ca3ab7eed2..12f182968b3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -4367,6 +4367,46 @@ ns_term_shutdown (int sig) @implementation EmacsApp +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 +- (id)init +{ + if (self = [super init]) + self->isFirst = YES; + + return self; +} + +- (void)run +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + if (isFirst) [self finishLaunching]; + isFirst = NO; + + shouldKeepRunning = YES; + do + { + [pool release]; + pool = [[NSAutoreleasePool alloc] init]; + + NSEvent *event = + [self nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + [self sendEvent:event]; + [self updateWindows]; + } while (shouldKeepRunning); + + [pool release]; +} + +- (void)stop: (id)sender +{ + shouldKeepRunning = NO; +} +#endif + - (void)logNotification: (NSNotification *)notification { const char *name = [[notification name] UTF8String]; -- 2.39.2