changeset 1580:a51397ea24bf

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 25 Jan 2012 03:17:36 +0000
parents 245e6bf51317
children a80ec948c3eb
files mac/dw.m
diffstat 1 files changed, 88 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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;
 }
 
 /*