changeset 826:6bb8bff36548

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.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sat, 26 Mar 2011 20:51:40 +0000
parents 8a2e3138e1e4
children dc094750d284
files mac/dw.m
diffstat 1 files changed, 60 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- 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];