load ~/.Xdefaults less often, make it shared and free its resources.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 29 Apr 2010 15:32:47 +0000 (15:32 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 29 Apr 2010 15:32:47 +0000 (15:32 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@48420 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/engines/gl_x11/evas_engine.c
src/modules/engines/software_16_x11/evas_engine.c
src/modules/engines/software_x11/evas_engine.c
src/modules/engines/xrender_x11/evas_engine.c

index 0645181..ba64937 100644 (file)
@@ -114,6 +114,51 @@ int _evas_engine_GL_X11_log_dom = -1;
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
+struct xrdb_user
+{
+   time_t last_stat;
+   time_t last_mtime;
+   XrmDatabase db;
+};
+static struct xrdb_user xrdb_user = {0, 0, NULL};
+
+static Eina_Bool
+xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
+{
+   time_t last = xrdb_user.last_stat, now = time(NULL);
+
+   xrdb_user.last_stat = now;
+   if (last != now) /* don't stat() more than once every second */
+     {
+       struct stat st;
+       const char *home = getenv("HOME");
+       char tmp[PATH_MAX];
+
+       if (!home) goto failed;
+       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
+       if (stat(tmp, &st) != 0) goto failed;
+       if (xrdb_user.last_mtime != st.st_mtime)
+         {
+            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
+            xrdb_user.db = XrmGetFileDatabase(tmp);
+            if (!xrdb_user.db) goto failed;
+            xrdb_user.last_mtime = st.st_mtime;
+         }
+     }
+
+   if (!xrdb_user.db) return EINA_FALSE;
+   return XrmGetResource(xrdb_user.db, name, cls, type, val);
+
+ failed:
+   if (xrdb_user.db)
+     {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.db = NULL;
+     }
+   xrdb_user.last_mtime = 0;
+   return EINA_FALSE;
+}
+
 typedef struct _Render_Engine Render_Engine;
 
 struct _Render_Engine
@@ -123,9 +168,7 @@ struct _Render_Engine
    Evas                    *evas;
    int                      end;
    
-   // TODO: maybe use these as shared global resources, acquired only once?
-   XrmDatabase   xrdb_dpy; // xres - dpi
-   XrmDatabase   xrdb_user;
+   XrmDatabase   xrdb; // xres - dpi
    struct { // xres - dpi
       int        dpi; // xres - dpi
    } xr; // xres - dpi
@@ -195,26 +238,16 @@ eng_setup(Evas *e, void *in)
           {
              int status;
              char *type = NULL;
-            const char *home;
              XrmValue val;
              
              re->xr.dpi = 75000; // dpy * 1000
 
-            if ((home = getenv("HOME")))
-              {
-                 char tmp[PATH_MAX];
-                 snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-                 re->xrdb_user = XrmGetFileDatabase(tmp);
-                 if (re->xrdb_user)
-                   status = XrmGetResource(re->xrdb_user,
-                                           "Xft.dpi", "Xft.Dpi", &type, &val);
-              }
-
+            status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
             if ((!status) || (!type))
               {
-                 re->xrdb_dpy = XrmGetDatabase(info->info.display);
-                 if (re->xrdb_dpy)
-                   status = XrmGetResource(re->xrdb_dpy,
+                 if (!re->xrdb) re->xrdb = XrmGetDatabase(info->info.display);
+                 if (re->xrdb)
+                   status = XrmGetResource(re->xrdb,
                                            "Xft.dpi", "Xft.Dpi", &type, &val);
               }
 
@@ -326,9 +359,10 @@ eng_output_free(void *data)
    Render_Engine *re;
 
    re = (Render_Engine *)data;
-   
-//   if (re->xrdb_user) XrmDestroyDatabase(re->xrdb_user);
-//   if (re->xrdb_dpy) XrmDestroyDatabase(re->xrdb_dpy);
+
+// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
+//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
+
    eng_window_free(re->win);
    free(re);
 
@@ -1905,6 +1939,13 @@ eng_canvas_alpha_get(void *data __UNUSED__, void *info __UNUSED__)
 static int
 module_open(Evas_Module *em)
 {
+   static Eina_Bool xrm_inited = EINA_FALSE;
+   if (!xrm_inited)
+     {
+       xrm_inited = EINA_TRUE;
+       XrmInitialize();
+     }
+
    if (!em) return 0;
    /* get whatever engine module we inherit from */
    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
@@ -2022,6 +2063,13 @@ static void
 module_close(Evas_Module *em)
 {
     eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
+    if (xrdb_user.db)
+      {
+        XrmDestroyDatabase(xrdb_user.db);
+        xrdb_user.last_stat = 0;
+        xrdb_user.last_mtime = 0;
+        xrdb_user.db = NULL;
+      }
 }
 
 static Evas_Module_Api evas_modapi =
index 884e684..32a88ba 100644 (file)
@@ -8,6 +8,51 @@ int _evas_engine_soft16_x11_log_dom = -1;
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
+struct xrdb_user
+{
+   time_t last_stat;
+   time_t last_mtime;
+   XrmDatabase db;
+};
+static struct xrdb_user xrdb_user = {0, 0, NULL};
+
+static Eina_Bool
+xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
+{
+   time_t last = xrdb_user.last_stat, now = time(NULL);
+
+   xrdb_user.last_stat = now;
+   if (last != now) /* don't stat() more than once every second */
+     {
+       struct stat st;
+       const char *home = getenv("HOME");
+       char tmp[PATH_MAX];
+
+       if (!home) goto failed;
+       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
+       if (stat(tmp, &st) != 0) goto failed;
+       if (xrdb_user.last_mtime != st.st_mtime)
+         {
+            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
+            xrdb_user.db = XrmGetFileDatabase(tmp);
+            if (!xrdb_user.db) goto failed;
+            xrdb_user.last_mtime = st.st_mtime;
+         }
+     }
+
+   if (!xrdb_user.db) return EINA_FALSE;
+   return XrmGetResource(xrdb_user.db, name, cls, type, val);
+
+ failed:
+   if (xrdb_user.db)
+     {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.db = NULL;
+     }
+   xrdb_user.last_mtime = 0;
+   return EINA_FALSE;
+}
+
 /* engine struct data */
 typedef struct _Render_Engine Render_Engine;
 
@@ -21,9 +66,7 @@ struct _Render_Engine
    Tilebuf_Rect     *rects;
    Tilebuf_Rect     *cur_rect;
    
-   // TODO: maybe use these as shared global resources, acquired only once?
-   XrmDatabase   xrdb_dpy; // xres - dpi
-   XrmDatabase   xrdb_user;
+   XrmDatabase   xrdb; // xres - dpi
    struct { // xres - dpi
       int        dpi; // xres - dpi
    } xr; // xres - dpi
@@ -188,26 +231,16 @@ eng_setup(Evas *e, void *in)
      {   
         int status;
         char *type = NULL;
-       const char *home;
         XrmValue val;
         
         re->xr.dpi = 75000; // dpy * 1000
 
-       if ((home = getenv("HOME")))
-         {
-            char tmp[PATH_MAX];
-            snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-            re->xrdb_user = XrmGetFileDatabase(tmp);
-            if (re->xrdb_user)
-              status = XrmGetResource(re->xrdb_user,
-                                      "Xft.dpi", "Xft.Dpi", &type, &val);
-         }
-
+       status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
        if ((!status) || (!type))
          {
-            re->xrdb_dpy = XrmGetDatabase(re->disp);
-            if (re->xrdb_dpy)
-              status = XrmGetResource(re->xrdb_dpy,
+            if (!re->xrdb) re->xrdb = XrmGetDatabase(re->disp);
+            if (re->xrdb)
+              status = XrmGetResource(re->xrdb,
                                       "Xft.dpi", "Xft.Dpi", &type, &val);
          }
 
@@ -266,8 +299,8 @@ eng_output_free(void *data)
 
    re = (Render_Engine *)data;
    
-//   if (re->xrdb_user) XrmDestroyDatabase(re->xrdb_user);
-//   if (re->xrdb_dpy) XrmDestroyDatabase(re->xrdb_dpy);
+// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
+//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
    
    if (re->shbuf) evas_software_x11_x_output_buffer_free(re->shbuf, 0);
    if (re->clip_rects) XDestroyRegion(re->clip_rects);
@@ -630,6 +663,13 @@ eng_canvas_alpha_get(void *data __UNUSED__, void *context __UNUSED__)
 static int
 module_open(Evas_Module *em)
 {
+   static Eina_Bool xrm_inited = EINA_FALSE;
+   if (!xrm_inited)
+     {
+       xrm_inited = EINA_TRUE;
+       XrmInitialize();
+     }
+
    if (!em) return 0;
    /* get whatever engine module we inherit from */
    if (!_evas_module_engine_inherit(&pfunc, "software_16")) return 0;
@@ -667,6 +707,13 @@ static void
 module_close(Evas_Module *em)
 {
   eina_log_domain_unregister(_evas_engine_soft16_x11_log_dom);
+  if (xrdb_user.db)
+    {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.last_stat = 0;
+       xrdb_user.last_mtime = 0;
+       xrdb_user.db = NULL;
+    }
 }
 
 static Evas_Module_Api evas_modapi =
index 7be2b69..2788fc6 100644 (file)
@@ -20,6 +20,53 @@ int test ;
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+struct xrdb_user
+{
+   time_t last_stat;
+   time_t last_mtime;
+   XrmDatabase db;
+};
+static struct xrdb_user xrdb_user = {0, 0, NULL};
+
+static Eina_Bool
+xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
+{
+   time_t last = xrdb_user.last_stat, now = time(NULL);
+
+   xrdb_user.last_stat = now;
+   if (last != now) /* don't stat() more than once every second */
+     {
+       struct stat st;
+       const char *home = getenv("HOME");
+       char tmp[PATH_MAX];
+
+       if (!home) goto failed;
+       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
+       if (stat(tmp, &st) != 0) goto failed;
+       if (xrdb_user.last_mtime != st.st_mtime)
+         {
+            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
+            xrdb_user.db = XrmGetFileDatabase(tmp);
+            if (!xrdb_user.db) goto failed;
+            xrdb_user.last_mtime = st.st_mtime;
+         }
+     }
+
+   if (!xrdb_user.db) return EINA_FALSE;
+   return XrmGetResource(xrdb_user.db, name, cls, type, val);
+
+ failed:
+   if (xrdb_user.db)
+     {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.db = NULL;
+     }
+   xrdb_user.last_mtime = 0;
+   return EINA_FALSE;
+}
+#endif
+
 /* engine struct data */
 typedef struct _Render_Engine Render_Engine;
 
@@ -32,9 +79,7 @@ struct _Render_Engine
    int           end : 1;
    
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
-   // TODO: maybe use these as shared global resources, acquired only once?
-   XrmDatabase   xrdb_dpy; // xres - dpi
-   XrmDatabase   xrdb_user;
+   XrmDatabase   xrdb; // xres - dpi
    struct { // xres - dpi
       int        dpi; // xres - dpi
    } xr; // xres - dpi
@@ -101,28 +146,18 @@ _output_xlib_setup(int      w,
    evas_software_xlib_outbuf_init();
 
      {
-        int status = 0;
+        int status;
         char *type = NULL;
-       const char *home;
         XrmValue val;
         
         re->xr.dpi = 75000; // dpy * 1000
 
-       if ((home = getenv("HOME")))
-         {
-            char tmp[PATH_MAX];
-            snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-            re->xrdb_user = XrmGetFileDatabase(tmp);
-            if (re->xrdb_user)
-              status = XrmGetResource(re->xrdb_user,
-                                      "Xft.dpi", "Xft.Dpi", &type, &val);
-         }
-
+       status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
        if ((!status) || (!type))
          {
-            re->xrdb_dpy = XrmGetDatabase(disp);
-            if (re->xrdb_dpy)
-              status = XrmGetResource(re->xrdb_dpy,
+            if (!re->xrdb) re->xrdb = XrmGetDatabase(disp);
+            if (re->xrdb)
+              status = XrmGetResource(re->xrdb,
                                       "Xft.dpi", "Xft.Dpi", &type, &val);
          }
 
@@ -235,7 +270,7 @@ _output_xcb_setup(int               w,
    evas_software_xcb_x_color_init();
    evas_software_xcb_outbuf_init();
 
-   // FIXME: re->xrdb_user, re->xrdb_dpy
+   // FIXME: re->xrdb
    
    re->ob = evas_software_xcb_outbuf_setup_x(w,
                                              h,
@@ -574,12 +609,12 @@ eng_output_free(void *data)
    if (!data) return;
 
    re = (Render_Engine *)data;
-   
+
 #ifdef BUILD_ENGINE_SOFTWARE_XLIB
-//   if (re->xrdb_user) XrmDestroyDatabase(re->xrdb_user);
-//   if (re->xrdb_dpy) XrmDestroyDatabase(re->xrdb_dpy);
-#endif   
-   
+// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
+//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
+#endif
+
    re->outbuf_free(re->ob);
    evas_common_tilebuf_free(re->tb);
    if (re->rects) evas_common_tilebuf_free_render_rects(re->rects);
@@ -720,7 +755,17 @@ eng_canvas_alpha_get(void *data, void *context __UNUSED__)
 static int
 module_open(Evas_Module *em)
 {
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   static Eina_Bool xrm_inited = EINA_FALSE;
+   if (!xrm_inited)
+     {
+       xrm_inited = EINA_TRUE;
+       XrmInitialize();
+     }
+#endif
+
    if (!em) return 0;
+
    /* get whatever engine module we inherit from */
    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
    _evas_engine_soft_x11_log_dom = eina_log_domain_register("EvasSoftX11", EVAS_DEFAULT_LOG_COLOR);
@@ -756,6 +801,15 @@ static void
 module_close(Evas_Module *em __UNUSED__)
 {
   eina_log_domain_unregister(_evas_engine_soft_x11_log_dom);
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+  if (xrdb_user.db)
+    {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.last_stat = 0;
+       xrdb_user.last_mtime = 0;
+       xrdb_user.db = NULL;
+    }
+#endif
 }
 
 static Evas_Module_Api evas_modapi =
index 064d923..174287d 100644 (file)
@@ -8,6 +8,53 @@ int _evas_xrender_xcb_log_dom = -1;
 /* function tables - filled in later (func and parent func) */
 static Evas_Func func, pfunc;
 
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+struct xrdb_user
+{
+   time_t last_stat;
+   time_t last_mtime;
+   XrmDatabase db;
+};
+static struct xrdb_user xrdb_user = {0, 0, NULL};
+
+static Eina_Bool
+xrdb_user_query(const char *name, const char *cls, char **type, XrmValue *val)
+{
+   time_t last = xrdb_user.last_stat, now = time(NULL);
+
+   xrdb_user.last_stat = now;
+   if (last != now) /* don't stat() more than once every second */
+     {
+       struct stat st;
+       const char *home = getenv("HOME");
+       char tmp[PATH_MAX];
+
+       if (!home) goto failed;
+       snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
+       if (stat(tmp, &st) != 0) goto failed;
+       if (xrdb_user.last_mtime != st.st_mtime)
+         {
+            if (xrdb_user.db) XrmDestroyDatabase(xrdb_user.db);
+            xrdb_user.db = XrmGetFileDatabase(tmp);
+            if (!xrdb_user.db) goto failed;
+            xrdb_user.last_mtime = st.st_mtime;
+         }
+     }
+
+   if (!xrdb_user.db) return EINA_FALSE;
+   return XrmGetResource(xrdb_user.db, name, cls, type, val);
+
+ failed:
+   if (xrdb_user.db)
+     {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.db = NULL;
+     }
+   xrdb_user.last_mtime = 0;
+   return EINA_FALSE;
+}
+#endif
+
 /* engine struct data */
 typedef struct _Render_Engine        Render_Engine;
 typedef struct _Render_Engine_Update Render_Engine_Update;
@@ -31,9 +78,7 @@ struct _Render_Engine
    unsigned char    destination_alpha : 1;
 
 #ifdef BUILD_ENGINE_XRENDER_X11
-   // TODO: maybe use these as shared global resources, acquired only once?
-   XrmDatabase   xrdb_dpy; // xres - dpi
-   XrmDatabase   xrdb_user;
+   XrmDatabase   xrdb; // xres - dpi
    struct { // xres - dpi
       int        dpi; // xres - dpi
    } xr; // xres - dpi
@@ -229,26 +274,17 @@ _output_xlib_setup(int           width,
      {   
         int status;
         char *type = NULL;
-       const char *home;
         XrmValue val;
         
         re->xr.dpi = 75000; // dpy * 1000
 
-       if ((home = getenv("HOME")))
-         {
-            char tmp[PATH_MAX];
-            snprintf(tmp, sizeof(tmp), "%s/.Xdefaults", home);
-            re->xrdb_user = XrmGetFileDatabase(tmp);
-            if (re->xrdb_user)
-              status = XrmGetResource(re->xrdb_user,
-                                      "Xft.dpi", "Xft.Dpi", &type, &val);
-         }
-
+       status = xrdb_user_query("Xft.dpi", "Xft.Dpi", &type, &val);
        if ((!status) || (!type))
          {
-            re->xrdb_dpy = XrmGetDatabase((Display *)re->x11.connection);
-            if (re->xrdb_dpy)
-              status = XrmGetResource(re->xrdb_dpy,
+            if (!re->xrdb)
+              re->xrdb = XrmGetDatabase((Display *)re->x11.connection);
+            if (re->xrdb)
+              status = XrmGetResource(re->xrdb,
                                       "Xft.dpi", "Xft.Dpi", &type, &val);
          }
 
@@ -521,8 +557,8 @@ eng_output_free(void *data)
    re = (Render_Engine *)data;
    
 #ifdef BUILD_ENGINE_XRENDER_X11
-//   if (re->xrdb_user) XrmDestroyDatabase(re->xrdb_user);
-//   if (re->xrdb_dpy) XrmDestroyDatabase(re->xrdb_dpy);
+// NOTE: XrmGetDatabase() result is shared per connection, do not free it.
+//   if (re->xrdb) XrmDestroyDatabase(re->xrdb);
 #endif
    
    evas_common_font_shutdown();
@@ -1490,6 +1526,15 @@ eng_canvas_alpha_get(void *data, void *context)
 static int
 module_open(Evas_Module *em)
 {
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+   static Eina_Bool xrm_inited = EINA_FALSE;
+   if (!xrm_inited)
+     {
+       xrm_inited = EINA_TRUE;
+       XrmInitialize();
+     }
+#endif
+
    if (!em) return 0;
    /* get whatever engine module we inherit from */
    if (!_evas_module_engine_inherit(&pfunc, "software_generic")) return 0;
@@ -1605,6 +1650,15 @@ static void
 module_close(Evas_Module *em)
 {
   eina_log_domain_unregister(_evas_xrender_xcb_log_dom);
+#ifdef BUILD_ENGINE_SOFTWARE_XLIB
+  if (xrdb_user.db)
+    {
+       XrmDestroyDatabase(xrdb_user.db);
+       xrdb_user.last_stat = 0;
+       xrdb_user.last_mtime = 0;
+       xrdb_user.db = NULL;
+    }
+#endif
 }
 
 static Evas_Module_Api evas_modapi =