From owner-FreeBSD-users-jp@jp.FreeBSD.org Mon Nov 11 15:44:40 2002
Received: (from daemon@localhost)
	by castle.jp.FreeBSD.org (8.11.6+3.4W/8.11.3) id gAB6iet42869;
	Mon, 11 Nov 2002 15:44:40 +0900 (JST)
	(envelope-from owner-FreeBSD-users-jp@jp.FreeBSD.org)
Received: from kiri.pis (pis.elm.toba-cmt.ac.jp [202.26.248.196])
	by castle.jp.FreeBSD.org (8.11.6+3.4W/8.11.3) with ESMTP/inet id gAB6idm42787
	for <FreeBSD-users-jp@jp.FreeBSD.org>; Mon, 11 Nov 2002 15:44:39 +0900 (JST)
	(envelope-from kiri@pis.elm.toba-cmt.ac.jp)
Received: from kiri.pis (localhost [127.0.0.1])
	by kiri.pis (8.12.6/8.12.6) with ESMTP id gAB6jNDo098294
	for <FreeBSD-users-jp@jp.FreeBSD.org>; Mon, 11 Nov 2002 15:45:30 +0900 (JST)
	(envelope-from kiri@pis.elm.toba-cmt.ac.jp)
Message-Id: <200211110645.gAB6jNDo098294@kiri.pis>
From: KIRIYAMA Kazuhiko <kiri@pis.elm.toba-cmt.ac.jp>
To: FreeBSD-users-jp@jp.FreeBSD.org
In-Reply-To: <20021111085114Z.jiro@maverick.riko.shimane-u.ac.jp>
References: <20021109105141.GA627@MysticWALL.COM>
	<20021110131153M.jiro@maverick.riko.shimane-u.ac.jp>
	<20021110053958.GA77344@MysticWALL.COM>
	<20021111085114Z.jiro@maverick.riko.shimane-u.ac.jp>
User-Agent: Wanderlust/2.4.0 (Rio) SEMI/1.13.7 (Awazu) FLIM/1.13.2 (Kasanui) MULE XEmacs/21.4 (patch 10) (Military Intelligence) (i386--freebsd)
MIME-Version: 1.0 (generated by SEMI 1.13.7 - "Awazu")
Content-Type: multipart/mixed;
 boundary="Multipart_Mon_Nov_11_15:45:23_2002-1"
Reply-To: FreeBSD-users-jp@jp.FreeBSD.org
Precedence: list
Date: Mon, 11 Nov 2002 15:45:23 +0900
X-Sequence: FreeBSD-users-jp 71945
Subject: [FreeBSD-users-jp 71945] Re: 4.7-RELEASE
 =?ISO-2022-JP?B?GyRCJEcbKEI=?= gimp
 =?ISO-2022-JP?B?GyRCJCxGMCQrJEokJBsoQg==?= 
Errors-To: owner-FreeBSD-users-jp@jp.FreeBSD.org
Sender: owner-FreeBSD-users-jp@jp.FreeBSD.org
X-Originator: kiri@pis.elm.toba-cmt.ac.jp
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+021107

--Multipart_Mon_Nov_11_15:45:23_2002-1
Content-Type: text/plain; charset=ISO-2022-JP

$B6M;3$G$9!#(B

At Mon, 11 Nov 2002 08:51:14 +0900,
SAKAMOTO Jiro wrote:
> 
> $BJ,$+$j$^$7$?!#$d$O$j!"$3$A$i$N2?$+8E$$$b$N$,0-$5$r$7$F$$$k$N$G$7$g$&$+(B
> $B$M!#$3$&$$$&$N$O!"$I$&$d$C$FD4$Y$?$iNI$$$N$G$7$g$&$+!#(B

$B$(!<$H!"(BXFree86-3.3.6 $B"*(B XFree86-4.2.x $B$O4pK\E*$K$O(B

http://home.jp.FreeBSD.ORG/cgi-bin/showmail/FreeBSD-users-jp/70003

$B$G2DG=$G$9!#$,!"(Bxc/lib/X11/XlcDL.c $B$N%P%0$G(B

http://xfree86.org/pipermail/xpert/2002-January/015218.html

$B$rEv$F$kI,MW$,$"$j$^$9!#$3$N7o$K$D$$$F$O(B port $B%a%s%F%J$N(B
anholt@freebsd.org $B$5$s$KEj$2$F$*$$$?$N$G$9$,$I$&$bL$$K%Q%C(B
$B%A$,$"$?$C$F$J$$$h$&$G$9!#E:IU$N%Q%C%A$r(B
x11/XFree86-4-libraries.patched/files $B$KF~$l$F%$%s%9%H!<%k$7(B
$BD>$9$H(B OK $B$+$H;W$$$^$9!#(B

$B!t(B $B$b$&0lEY3NG'$7$F(B OK $B$@$C$?$i;d$,(B commit $B$7$^$9$N$G3'MM$N(B
$B!t(B $B8f6(NO$r$*4j$$$7$^$9!#(B

--Multipart_Mon_Nov_11_15:45:23_2002-1
Content-Type: text/plain; charset=US-ASCII

--- lib/X11/XlcDL.c~	Mon Sep  9 21:03:32 2002
+++ lib/X11/XlcDL.c	Mon Sep  9 21:30:10 2002
@@ -83,6 +83,7 @@
   char *im_register;
   char *im_unregister;
   int dl_release;
+  unsigned int refcount;
 #if defined(hpux)
   shl_t dl_module;
 #else
@@ -214,6 +215,7 @@
 	  xi18n_objects_list[lc_count].open = strdup(args[2]);
 	  xi18n_objects_list[lc_count].dl_release = XI18N_DLREL;
 	  xi18n_objects_list[lc_count].locale_name = strdup(lc_name);
+	  xi18n_objects_list[lc_count].refcount = 0;
 	  xi18n_objects_list[lc_count].dl_module = (void*)NULL;
 	  if (n == 5) {
 	    xi18n_objects_list[lc_count].im_register = strdup(args[3]);
@@ -290,6 +292,85 @@
     return path;
 }
 
+/* We reference count dlopen() and dlclose() of modules; unfortunately,
+ * since XCloseIM, XCloseOM, XlcClose aren't wrapped, but directly
+ * call the close method of the object, we leak a reference count every
+ * time we open then close a module. Fixing this would require
+ * either creating proxy objects or hooks for close_im/close_om
+ * in XLCd
+ */
+static Bool
+open_object (object, lc_dir)
+     XI18NObjectsList object;
+     char *lc_dir;
+{
+  char *path;
+
+  if (object->refcount == 0) {
+      path = __lc_path(object->dl_name, lc_dir);
+#if defined(hpux)
+      object->dl_module = shl_load(path, BIND_DEFERRED, 0L);
+#else
+      object->dl_module = dlopen(path, RTLD_LAZY);
+#endif
+      Xfree(path);
+
+      if (!object->dl_module)
+         return False;
+    }
+
+  object->refcount++;
+  return True;
+}
+
+static void *
+fetch_symbol (object, symbol)
+     XI18NObjectsList object;
+     char *symbol;
+{
+    void *result = NULL;
+#if defined(hpux)
+    int getsyms_cnt, i;
+    struct shl_symbol *symbols;
+#endif
+
+#if defined(hpux)
+    getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE,
+                                EXPORT_SYMBOLS, malloc, &symbols);
+
+    for(i=0; i<getsyms_cnt; i++) {
+        if(!strcmp(symbols[i].name, symbol)) {
+           result = symbols[i].value;
+           break;
+         }
+    }
+
+    if(getsyms_cnt > 0) {
+        free(symbols);
+    }
+#else
+    result = (XLCd(*)())try_both_dlsym(object->dl_module, symbol);
+#endif
+
+    return result;
+}
+
+static void
+close_object (object)
+     XI18NObjectsList object;
+{
+  object->refcount--;
+  if (object->refcount == 0)
+    {
+#if defined(hpux)
+        shl_unload(object->dl_module);
+#else
+        dlclose(object->dl_module);
+#endif
+        object->dl_module = NULL;
+    }
+}
+
 XLCd
 #if NeedFunctionPrototypes
 _XlcDynamicLoad(const char *lc_name)
@@ -300,14 +381,9 @@
 {
     XLCd lcd = (XLCd)NULL;
     XLCd (*lc_loader)() = (XLCd(*)())NULL;
-    char *path;
     int count;
     XI18NObjectsList objects_list;
     char lc_dir[BUFSIZE];
-#if defined(hpux)
-    int getsyms_cnt, i;
-    struct shl_symbol *symbols;
-#endif
 
     if (lc_name == NULL) return (XLCd)NULL;
 
@@ -321,47 +397,17 @@
     for (; count-- > 0; objects_list++) {
         if (objects_list->type != XLC_OBJECT ||
 	    strcmp(objects_list->locale_name, lc_name)) continue;
-	if (!objects_list->dl_module) {
-	  path = __lc_path(objects_list->dl_name, lc_dir);
-	  if (!path)
-	      continue;
-#if defined(hpux)
-	  objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
-#else
-	  objects_list->dl_module = dlopen(path, RTLD_LAZY);
-#endif
-	  Xfree(path);
-	  if (!objects_list->dl_module) continue;
-	}
-#if defined(hpux)
-	getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
-		EXPORT_SYMBOLS, malloc, &symbols);
-
-	for(i=0; i<getsyms_cnt; i++) {
-	    if(!strcmp(symbols[i].name, objects_list->open)) {
-		lc_loader = symbols[i].value;
-		break;
-	    }
-	}
+	if (!open_object (objects_list, lc_dir))
+	  continue;
 
-	if(getsyms_cnt > 0) {
-	    free(symbols);
-	}
-#else
-	lc_loader = (XLCd(*)())try_both_dlsym(objects_list->dl_module,
-					      objects_list->open);
-#endif
+	lc_loader = (XLCd(*)())fetch_symbol (objects_list, objects_list->open);
 	if (!lc_loader) continue;
 	lcd = (*lc_loader)(lc_name);
 	if (lcd != (XLCd)NULL) {
 	    break;
 	}
-#if defined(hpux)
-	shl_unload(objects_list->dl_module);
-#else
-	dlclose(objects_list->dl_module);
-#endif
-	objects_list->dl_module = NULL;
+       
+	close_object (objects_list);
     }
     return (XLCd)lcd;
 }
@@ -379,16 +425,11 @@
 #endif
 {
   XIM im = (XIM)NULL;
-  char *path;
   char lc_dir[BUFSIZE];
   char *lc_name;
   XIM (*im_openIM)() = (XIM(*)())NULL;
   int count;
   XI18NObjectsList objects_list = xi18n_objects_list;
-#if defined(hpux)
-  int getsyms_cnt, i;
-  struct shl_symbol *symbols;
-#endif
 
   lc_name = lcd->core->name;
 
@@ -398,48 +439,18 @@
   for (; count-- > 0; objects_list++) {
     if (objects_list->type != XIM_OBJECT ||
 	strcmp(objects_list->locale_name, lc_name)) continue;
-    if (!objects_list->dl_module) {
-      path = __lc_path(objects_list->dl_name, lc_dir);
-      if (!path)
-	  continue;
-#if defined(hpux)
-      objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
-#else
-      objects_list->dl_module = dlopen(path, RTLD_LAZY);
-#endif
-      Xfree(path);
-      if (!objects_list->dl_module) continue;
-    }
-#if defined(hpux)
-    getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
-	EXPORT_SYMBOLS, malloc, &symbols);
 
-    for(i=0; i<getsyms_cnt; i++) {
-	if(!strcmp(symbols[i].name, objects_list->open)) {
-	    im_openIM = symbols[i].value;
-	    break;
-	}
-     }
+    if (!open_object (objects_list, lc_dir))
+      continue;
 
-    if(getsyms_cnt > 0) {
-	free(symbols);
-    }
-#else
-    im_openIM = (XIM(*)())try_both_dlsym(objects_list->dl_module,
-					 objects_list->open);
+    im_openIM = (XIM(*)())fetch_symbol(objects_list, objects_list->open);
     if (!im_openIM) continue;
-#endif
     im = (*im_openIM)(lcd, display, rdb, res_name, res_class);
     if (im != (XIM)NULL) {
       break;
     }
-    im_openIM = 0;
-#if defined(hpux)
-    shl_unload(objects_list->dl_module);
-#else
-    dlclose(objects_list->dl_module);
-#endif
-    objects_list->dl_module = NULL;
+
+    close_object (objects_list);
   }
   return (XIM)im;
 }
@@ -455,7 +466,6 @@
 XIMProc	 callback;
 XPointer	*client_data;
 {
-  char *path;
   char lc_dir[BUFSIZE];
   char *lc_name;
   Bool (*im_registerIM)() = (Bool(*)())NULL;
@@ -475,49 +485,18 @@
   for (; count-- > 0; objects_list++) {
     if (objects_list->type != XIM_OBJECT ||
 	strcmp(objects_list->locale_name, lc_name)) continue;
-    if (!objects_list->dl_module) {
-      path = __lc_path(objects_list->dl_name, lc_dir);
-      if (!path)
-	  continue;
-#if defined(hpux)
-      objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
-#else
-      objects_list->dl_module = dlopen(path, RTLD_LAZY);
-#endif
-      Xfree(path);
-      if (!objects_list->dl_module) continue;
-    }
-#if defined(hpux)
-    getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
-	EXPORT_SYMBOLS, malloc, &symbols);
-
-    for(i=0; i<getsyms_cnt; i++) {
-	if(!strcmp(symbols[i].name, objects_list->open)) {
-	    im_registerIM = symbols[i].value;
-	    break;
-	}
-     }
 
-    if(getsyms_cnt > 0) {
-	free(symbols);
-    }
-#else
-    im_registerIM = (Bool(*)())try_both_dlsym(objects_list->dl_module,
-					      objects_list->im_register);
+    if (!open_object (objects_list, lc_dir))
+      continue;
+    im_registerIM = (Bool(*)())fetch_symbol(objects_list,
+					    objects_list->im_register);
     if (!im_registerIM) continue;
-#endif
     ret_flag = (*im_registerIM)(lcd, display, rdb,
 				res_name, res_class,
 				callback, client_data);
     if (ret_flag) break;
 
-    im_registerIM = 0;
-#if defined(hpux)
-    shl_unload(objects_list->dl_module);
-#else
-    dlclose(objects_list->dl_module);
-#endif
-    objects_list->dl_module = NULL;
+    close_object (objects_list);
   }
   return (Bool)ret_flag;
 }
@@ -533,7 +512,6 @@
 XIMProc	 callback;
 XPointer	*client_data;
 {
-  char *path;
   char lc_dir[BUFSIZE];
   char *lc_name;
   Bool (*im_unregisterIM)() = (Bool(*)())NULL;
@@ -552,50 +530,21 @@
   for (; count-- > 0; objects_list++) {
     if (objects_list->type != XIM_OBJECT ||
 	strcmp(objects_list->locale_name, lc_name)) continue;
-    if (!objects_list->dl_module) {
-      path = __lc_path(objects_list->dl_name, lc_dir);
-      if (!path)
-	  continue;
-#if defined(hpux)
-      objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
-#else
-      objects_list->dl_module = dlopen(path, RTLD_LAZY);
-#endif
-      Xfree(path);
-      if (!objects_list->dl_module) continue;
-    }
-#if defined(hpux)
-    getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
-	EXPORT_SYMBOLS, malloc, &symbols);
 
-    for(i=0; i<getsyms_cnt; i++) {
-	if(!strcmp(symbols[i].name, objects_list->open)) {
-	    im_unregisterIM = symbols[i].value;
-	    break;
-	}
-     }
+    if (!objects_list->refcount) /* Must already be opened */
+      continue;
 
-    if(getsyms_cnt > 0) {
-	free(symbols);
-    }
-#else
-    im_unregisterIM = (Bool(*)())try_both_dlsym(objects_list->dl_module,
-						objects_list->im_unregister);
+    im_unregisterIM = (Bool(*)())fetch_symbol(objects_list,
+					      objects_list->im_unregister);
 
     if (!im_unregisterIM) continue;
-#endif
     ret_flag = (*im_unregisterIM)(lcd, display, rdb,
 				  res_name, res_class,
 				  callback, client_data);
-    if (ret_flag) break;
-
-    im_unregisterIM = 0;
-#if defined(hpux)
-    shl_unload(objects_list->dl_module);
-#else
-    dlclose(objects_list->dl_module);
-#endif
-    objects_list->dl_module = NULL;
+    if (ret_flag) {
+      close_object (objects_list); /* opened in RegisterIMInstantiateCallback */
+      break;
+    }
   }
   return (Bool)ret_flag;
 }
@@ -631,7 +580,6 @@
 {
   XOM om = (XOM)NULL;
   int count;
-  char *path;
   char lc_dir[BUFSIZE];
   char *lc_name;
   XOM (*om_openOM)() = (XOM(*)())NULL;
@@ -649,48 +597,16 @@
   for (; count-- > 0; objects_list++) {
     if (objects_list->type != XOM_OBJECT ||
 	strcmp(objects_list->locale_name, lc_name)) continue;
-    if (!objects_list->dl_module) {
-      path = __lc_path(objects_list->dl_name, lc_dir);
-      if (!path)
-	  continue;
-#if defined(hpux)
-      objects_list->dl_module = shl_load(path, BIND_DEFERRED, 0L);
-#else
-      objects_list->dl_module = dlopen(path, RTLD_LAZY);
-#endif
-      Xfree(path);
-      if (!objects_list->dl_module) continue;
-    }
-#if defined(hpux)
-    getsyms_cnt = shl_getsymbols(objects_list->dl_module, TYPE_PROCEDURE,
-	EXPORT_SYMBOLS, malloc, &symbols);
-
-    for(i=0; i<getsyms_cnt; i++) {
-	if(!strcmp(symbols[i].name, objects_list->open)) {
-	    om_openOM = symbols[i].value;
-	    break;
-	}
-     }
-
-    if(getsyms_cnt > 0) {
-	free(symbols);
-    }
-#else
-    om_openOM = (XOM(*)())try_both_dlsym(objects_list->dl_module,
-					 objects_list->open);
+    if (!open_object (objects_list, lc_dir))
+      continue;
+    
+    om_openOM = (XOM(*)())fetch_symbol(objects_list, objects_list->open);
     if (!om_openOM) continue;
-#endif
     om = (*om_openOM)(lcd, display, rdb, res_name, res_class);
     if (om != (XOM)NULL) {
       break;
     }
-    om_openOM = 0;
-#if defined(hpux)
-    shl_unload(objects_list->dl_module);
-#else
-    dlclose(objects_list->dl_module);
-#endif
-    objects_list->dl_module = NULL;
+    close_object(objects_list);
   }
   return (XOM)om;
 }



--Multipart_Mon_Nov_11_15:45:23_2002-1--
