# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1327461456 0 # Node ID a51397ea24bfa73427159d76dfe1e55dce9839aa # Parent 245e6bf51317586c3ae491da9bf3dc3c3503b92d Added local auto-release macros on Mac to allow us to prevent leaks on secondary threads without calling _dw_pool_drain(). Macros should be added to any funtions that allocate temporary objects. diff -r 245e6bf51317 -r a51397ea24bf mac/dw.m --- a/mac/dw.m Tue Jan 24 00:00:36 2012 +0000 +++ b/mac/dw.m Wed Jan 25 03:17:36 2012 +0000 @@ -41,6 +41,12 @@ dw_mutex_unlock(DWThreadMutex); \ _locked_by_me = FALSE; } } +/* Macros to handle local auto-release pools */ +#define DW_LOCAL_POOL_IN NSAutoreleasePool *localpool = nil; \ + if(DWThread != (DWTID)-1 && pthread_self() != DWThread) \ + localpool = [[NSAutoreleasePool alloc] init]; +#define DW_LOCAL_POOL_OUT if(localpool) [localpool drain]; + unsigned long _colors[] = { 0x00000000, /* 0 black */ @@ -3161,6 +3167,7 @@ { char temp[PATH_MAX+1]; char *file = NULL, *path = NULL; + DW_LOCAL_POOL_IN; /* Figure out path information... * These functions are only support in Snow Leopard and later... @@ -3250,7 +3257,11 @@ NSArray *files = [openDlg URLs]; NSString *fileName = [[files objectAtIndex:0] path]; if(fileName) - return strdup([ fileName UTF8String ]); + { + char *ret = strdup([ fileName UTF8String ]); + DW_LOCAL_POOL_OUT; + return ret; + } } } else @@ -3283,10 +3294,14 @@ */ NSString* fileName = [[saveDlg URL] path]; if(fileName) - return strdup([ fileName UTF8String ]); - } - } - + { + char *ret = strdup([ fileName UTF8String ]); + DW_LOCAL_POOL_OUT; + return ret; + } + } + } + DW_LOCAL_POOL_OUT; return NULL; } @@ -5163,6 +5178,7 @@ { NSColor *oldcolor = pthread_getspecific(_dw_fg_color_key); NSColor *newcolor; + DW_LOCAL_POOL_IN; _foreground = _get_color(value); @@ -5171,6 +5187,7 @@ DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] retain]; pthread_setspecific(_dw_fg_color_key, newcolor); [oldcolor release]; + DW_LOCAL_POOL_OUT; } /* Sets the current background drawing color. @@ -5183,6 +5200,7 @@ { NSColor *oldcolor = pthread_getspecific(_dw_bg_color_key); NSColor *newcolor; + DW_LOCAL_POOL_IN; if(value == DW_CLR_DEFAULT) { @@ -5198,6 +5216,7 @@ pthread_setspecific(_dw_bg_color_key, newcolor); } [oldcolor release]; + DW_LOCAL_POOL_OUT; } /* Allows the user to choose a color using the system's color chooser dialog. @@ -5257,6 +5276,7 @@ void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; if(pixmap) @@ -5271,6 +5291,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } _DWLastDrawable = handle; @@ -5291,6 +5312,7 @@ [image unlockFocus]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* Draw a line on a window (preferably a render window). @@ -5305,6 +5327,7 @@ void API dw_draw_line(HWND handle, HPIXMAP pixmap, int x1, int y1, int x2, int y2) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; if(pixmap) @@ -5319,6 +5342,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } _DWLastDrawable = handle; @@ -5340,6 +5364,7 @@ [image unlockFocus]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* Draw text on a window (preferably a render window). @@ -5353,6 +5378,7 @@ void API dw_draw_text(HWND handle, HPIXMAP pixmap, int x, int y, char *text) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; NSString *nstr = [ NSString stringWithUTF8String:text ]; @@ -5365,6 +5391,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } NSColor *fgcolor = pthread_getspecific(_dw_fg_color_key); @@ -5412,6 +5439,7 @@ [dict release]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* Query the width and height of a text string. @@ -5425,8 +5453,12 @@ void API dw_font_text_extents_get(HWND handle, HPIXMAP pixmap, char *text, int *width, int *height) { id object = handle; - NSString *nstr = [NSString stringWithUTF8String:text]; + NSString *nstr; NSFont *font = nil; + DW_LOCAL_POOL_IN; + + nstr = [NSString stringWithUTF8String:text]; + /* Check the pixmap for associated object or font */ if(pixmap) { @@ -5456,6 +5488,7 @@ { *height = size.height; } + DW_LOCAL_POOL_OUT; } /* Internal function to create an image graphics context... @@ -5483,6 +5516,7 @@ void API dw_draw_polygon( HWND handle, HPIXMAP pixmap, int flags, int npoints, int *x, int *y ) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; int z; @@ -5498,6 +5532,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; @@ -5527,6 +5562,7 @@ [image unlockFocus]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* Draw a rectangle on a window (preferably a render window). @@ -5542,6 +5578,7 @@ void API dw_draw_rect(HWND handle, HPIXMAP pixmap, int flags, int x, int y, int width, int height) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; if(pixmap) @@ -5556,6 +5593,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; @@ -5577,6 +5615,7 @@ [image unlockFocus]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* Draw an arc on a window (preferably a render window). @@ -5595,6 +5634,7 @@ void API dw_draw_arc(HWND handle, HPIXMAP pixmap, int flags, int xorigin, int yorigin, int x1, int y1, int x2, int y2) { int _locked_by_me = FALSE; + DW_LOCAL_POOL_IN; DW_MUTEX_LOCK; id image = handle; double r, a1, a2, a; @@ -5611,6 +5651,7 @@ if([image lockFocusIfCanDraw] == NO) { DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; return; } [[NSGraphicsContext currentContext] setShouldAntialias:(flags & DW_DRAW_NOAA ? NO : YES)]; @@ -5656,6 +5697,7 @@ [image unlockFocus]; } DW_MUTEX_UNLOCK; + DW_LOCAL_POOL_OUT; } /* @@ -6882,10 +6924,14 @@ HPIXMAP API dw_pixmap_new_from_file(HWND handle, char *filename) { HPIXMAP pixmap; + DW_LOCAL_POOL_IN; char *ext = _dw_get_image_extension( filename ); if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + { + DW_LOCAL_POOL_OUT; return NULL; + } NSString *nstr = [ NSString stringWithUTF8String:filename ]; NSImage *tmpimage = [[[NSImage alloc] initWithContentsOfFile:nstr] autorelease]; if(!tmpimage && ext) @@ -6894,7 +6940,10 @@ tmpimage = [[[NSImage alloc] initWithContentsOfFile:nstr] autorelease]; } if(!tmpimage) + { + DW_LOCAL_POOL_OUT; return NULL; + } NSSize size = [tmpimage size]; NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL @@ -6912,6 +6961,7 @@ pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; + DW_LOCAL_POOL_OUT; return pixmap; } @@ -6928,13 +6978,20 @@ HPIXMAP API dw_pixmap_new_from_data(HWND handle, char *data, int len) { HPIXMAP pixmap; + DW_LOCAL_POOL_IN; if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + { + DW_LOCAL_POOL_OUT; return NULL; + } NSData *thisdata = [NSData dataWithBytes:data length:len]; NSImage *tmpimage = [[[NSImage alloc] initWithData:thisdata] autorelease]; if(!tmpimage) + { + DW_LOCAL_POOL_OUT; return NULL; + } NSSize size = [tmpimage size]; NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL @@ -6952,6 +7009,7 @@ pixmap->height = size.height; pixmap->image = image; pixmap->handle = handle; + DW_LOCAL_POOL_OUT; return pixmap; } @@ -6980,9 +7038,13 @@ HPIXMAP API dw_pixmap_grab(HWND handle, ULONG resid) { HPIXMAP pixmap; + DW_LOCAL_POOL_IN; if(!(pixmap = calloc(1,sizeof(struct _hpixmap)))) + { + DW_LOCAL_POOL_OUT; return NULL; + } NSBundle *bundle = [NSBundle mainBundle]; NSString *respath = [bundle resourcePath]; @@ -7012,6 +7074,7 @@ return pixmap; } free(pixmap); + DW_LOCAL_POOL_OUT; return NULL; } @@ -7103,12 +7166,18 @@ int API dw_pixmap_stretch_bitblt(HWND dest, HPIXMAP destp, int xdest, int ydest, int width, int height, HWND src, HPIXMAP srcp, int xsrc, int ysrc, int srcwidth, int srcheight) { DWBitBlt *bltinfo = calloc(1, sizeof(DWBitBlt)); - NSValue* bi = [NSValue valueWithPointer:bltinfo]; + NSValue* bi; + DW_LOCAL_POOL_IN; + + bi = [NSValue valueWithPointer:bltinfo]; /* Sanity checks */ if((!dest && !destp) || (!src && !srcp) || ((srcwidth == -1 || srcheight == -1) && srcwidth != srcheight)) + { + DW_LOCAL_POOL_OUT; return DW_ERROR_GENERAL; + } /* Fill in the information */ bltinfo->dest = dest; @@ -7131,7 +7200,11 @@ id object = bltinfo->src = (id)srcp->image; [object retain]; } - [DWObj performSelectorOnMainThread:@selector(doBitBlt:) withObject:bi waitUntilDone:YES]; + if(DWThread == (DWTID)-1) + [DWObj doBitBlt:bi]; + else + [DWObj performSelectorOnMainThread:@selector(doBitBlt:) withObject:bi waitUntilDone:YES]; + DW_LOCAL_POOL_OUT; return DW_ERROR_NONE; } @@ -7748,11 +7821,14 @@ void API dw_window_function(HWND handle, void *function, void *data) { void **params = calloc(2, sizeof(void *)); - NSValue *v = [NSValue valueWithPointer:params]; + NSValue *v; + DW_LOCAL_POOL_IN; + v = [NSValue valueWithPointer:params]; params[0] = function; params[1] = data; [DWObj performSelectorOnMainThread:@selector(doWindowFunc:) withObject:v waitUntilDone:YES]; free(params); + DW_LOCAL_POOL_OUT; } @@ -8574,6 +8650,8 @@ void API dw_window_set_bitmap(HWND handle, unsigned long resid, char *filename) { NSObject *object = handle; + DW_LOCAL_POOL_IN; + if([ object isKindOfClass:[ NSImageView class ] ]) { NSImageView *iv = handle; @@ -8595,6 +8673,7 @@ _dw_redraw([iv window], TRUE); } } + DW_LOCAL_POOL_OUT; } /*