about summary refs log tree commit diff
path: root/libidn/idn-stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'libidn/idn-stub.c')
-rw-r--r--libidn/idn-stub.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/libidn/idn-stub.c b/libidn/idn-stub.c
index f2a11611ef..1e5cc1f6f9 100644
--- a/libidn/idn-stub.c
+++ b/libidn/idn-stub.c
@@ -23,6 +23,8 @@
 #include <stdio.h>
 #include <string.h>
 #include <dlfcn.h>
+#include <gnu/lib-names.h>
+#include <bits/libc-lock.h>
 
 /* Get specification for idna_to_ascii_lz. */
 #include "idna.h"
@@ -53,20 +55,30 @@ __idna_to_ascii_lz (const char *input, char **output, int flags)
 
   if (h == NULL)
     {
-      h = __libc_dlopen ("libcidn.so");
+      __libc_lock_define_initialized (static, lock);
 
+      __libc_lock_lock (lock);
+
+      /* Retest in case some other thread arrived here at the same time.  */
       if (h == NULL)
-	h = (void *) 1l;
-      else
 	{
-	  /* Get the function we are interested in.  */
-	  to_ascii_lz = __libc_dlsym (h, "idna_to_ascii_lz");
-	  if (to_ascii_lz == NULL)
+	  h = __libc_dlopen (LIBCIDN_SO);
+
+	  if (h == NULL)
+	    h = (void *) 1l;
+	  else
 	    {
-	      __libc_dlclose (h);
-	      h = (void *) 1l;
+	      /* Get the function we are interested in.  */
+	      to_ascii_lz = __libc_dlsym (h, "idna_to_ascii_lz");
+	      if (to_ascii_lz == NULL)
+		{
+		  __libc_dlclose (h);
+		  h = (void *) 1l;
+		}
 	    }
 	}
+
+      __libc_lock_unlock (lock);
     }
 
   if (h == (void *) 1l)