# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1301172700 0 # Node ID 6bb8bff365486da790410adf4dae13b055230e55 # Parent 8a2e3138e1e4483d5e393c6812b7005e56c4ef38 Implemented thread specific colors. Allows threads to have their own colors... also reducing color object recreation. Still leaking a little in Control Center... but it is significantly reduced. diff -r 8a2e3138e1e4 -r 6bb8bff36548 mac/dw.m --- a/mac/dw.m Sat Mar 26 14:36:51 2011 +0000 +++ b/mac/dw.m Sat Mar 26 20:51:40 2011 +0000 @@ -74,6 +74,23 @@ return 0; } +/* Thread specific storage */ +#if !defined(GARBAGE_COLLECT) +pthread_key_t _dw_pool_key; +#endif +pthread_key_t _dw_fg_color_key; +pthread_key_t _dw_bg_color_key; + +/* Create a default colors for a thread */ +void _init_colors(void) +{ + NSColor *fgcolor = [[NSColor grayColor] retain]; + NSColor *bgcolor = [[NSColor blackColor] retain]; + + pthread_setspecific(_dw_fg_color_key, fgcolor); + pthread_setspecific(_dw_bg_color_key, bgcolor); +} + typedef struct _sighandler { struct _sighandler *next; @@ -3939,8 +3956,16 @@ */ void API dw_color_foreground_set(unsigned long value) { - /* This may need to be thread specific */ + NSColor *oldcolor = pthread_getspecific(_dw_fg_color_key); + NSColor *newcolor; + _foreground = _get_color(value); + + newcolor = [[NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: + DW_GREEN_VALUE(_foreground)/255.0 blue: + DW_BLUE_VALUE(_foreground)/255.0 alpha: 1] retain]; + pthread_setspecific(_dw_fg_color_key, newcolor); + [oldcolor release]; } /* Sets the current background drawing color. @@ -3951,8 +3976,16 @@ */ void API dw_color_background_set(unsigned long value) { - /* This may need to be thread specific */ + NSColor *oldcolor = pthread_getspecific(_dw_bg_color_key); + NSColor *newcolor; + _background = _get_color(value); + + newcolor = [[NSColor colorWithDeviceRed: DW_RED_VALUE(_background)/255.0 green: + DW_GREEN_VALUE(_background)/255.0 blue: + DW_BLUE_VALUE(_background)/255.0 alpha: 1] retain]; + pthread_setspecific(_dw_bg_color_key, newcolor); + [oldcolor release]; } /* Allows the user to choose a color using the system's color chooser dialog. @@ -4029,7 +4062,7 @@ } NSBezierPath* aPath = [NSBezierPath bezierPath]; [aPath setLineWidth: 0.5]; - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); [color set]; [aPath moveToPoint:NSMakePoint(x, y)]; @@ -4068,7 +4101,7 @@ } NSBezierPath* aPath = [NSBezierPath bezierPath]; [aPath setLineWidth: 0.5]; - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); [color set]; [aPath moveToPoint:NSMakePoint(x1, y1)]; @@ -4104,7 +4137,7 @@ DW_MUTEX_UNLOCK; return; } - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:color, NSForegroundColorAttributeName, nil]; if(font) { @@ -4125,7 +4158,7 @@ } image = (id)pixmap->image; [image lockFocus]; - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithObjectsAndKeys:color, NSForegroundColorAttributeName, nil]; if(font) { @@ -4209,7 +4242,7 @@ } NSBezierPath* aPath = [NSBezierPath bezierPath]; [aPath setLineWidth: 0.5]; - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); [color set]; [aPath moveToPoint:NSMakePoint(*x, *y)]; @@ -4258,7 +4291,7 @@ } NSBezierPath* aPath = [NSBezierPath bezierPath]; [aPath setLineWidth: 0.5]; - NSColor *color = [NSColor colorWithDeviceRed: DW_RED_VALUE(_foreground)/255.0 green: DW_GREEN_VALUE(_foreground)/255.0 blue: DW_BLUE_VALUE(_foreground)/255.0 alpha: 1]; + NSColor *color = pthread_getspecific(_dw_fg_color_key); [color set]; [aPath moveToPoint:NSMakePoint(x, y)]; @@ -7876,10 +7909,6 @@ return 0; } -#if !defined(GARBAGE_COLLECT) -pthread_key_t _dw_pool_key; -#endif - /* Mac specific function to cause garbage collection */ void _dw_pool_drain(void) { @@ -7896,23 +7925,32 @@ */ void _dwthreadstart(void *data) { - void (*threadfunc)(void *) = NULL; - void **tmp = (void **)data; + void (*threadfunc)(void *) = NULL; + void **tmp = (void **)data; + NSColor *color; + /* If we aren't using garbage collection we need autorelease pools */ #if !defined(GARBAGE_COLLECT) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; pthread_setspecific(_dw_pool_key, pool); #endif - - threadfunc = (void (*)(void *))tmp[0]; - - threadfunc(tmp[1]); + _init_colors(); + + threadfunc = (void (*)(void *))tmp[0]; + + /* Start our thread function */ + threadfunc(tmp[1]); + /* Release the pool when we are done so we don't leak */ + color = pthread_getspecific(_dw_fg_color_key); + [color release]; + color = pthread_getspecific(_dw_bg_color_key); + [color release]; #if !defined(GARBAGE_COLLECT) pool = pthread_getspecific(_dw_pool_key); [pool drain]; #endif - free(tmp); + free(tmp); } void _dw_default_font(char *fontname) @@ -7947,6 +7985,9 @@ pool = [[NSAutoreleasePool alloc] init]; pthread_setspecific(_dw_pool_key, pool); #endif + pthread_key_create(&_dw_fg_color_key, NULL); + pthread_key_create(&_dw_bg_color_key, NULL); + _init_colors(); /* Create a default main menu, with just the application menu */ DWMainMenu = _generate_main_menu(); [DWMainMenu retain];