about summary refs log tree commit diff
path: root/inet/inet_ntoa.c
diff options
context:
space:
mode:
Diffstat (limited to 'inet/inet_ntoa.c')
-rw-r--r--inet/inet_ntoa.c74
1 files changed, 34 insertions, 40 deletions
diff --git a/inet/inet_ntoa.c b/inet/inet_ntoa.c
index 9e4b2af5b9..5dfec626a0 100644
--- a/inet/inet_ntoa.c
+++ b/inet/inet_ntoa.c
@@ -26,60 +26,45 @@
 /* The interface of this function is completely stupid, it requires a
    static buffer.  We relax this a bit in that we allow at least one
    buffer for each thread.  */
-__libc_lock_define_initialized (static, lock);
 
 /* This is the key for the thread specific memory.  */
 static __libc_key_t key;
 
+/* If nonzero the key allocation failed and we should better use a
+   static buffer than fail.  */
+static char local_buf[18];
+static char *static_buf;
+
 /* Destructor for the thread-specific data.  */
+static void init (void);
 static void free_key_mem (void *mem);
 
 
 char *
 inet_ntoa (struct in_addr in)
 {
-  static char static_buf[18];
-  static int initialized = 0;
-  char *buffer = NULL;
+  __libc_once_define (once);
+  char *buffer;
   unsigned char *bytes;
 
   /* If we have not yet initialized the buffer do it now.  */
-  if (!initialized)
-    {
-      /* Make sure there is only one process doing the initialization.  */
-      __libc_lock_lock (lock);
-
-      if (!initialized)
-	{
-	  if (__libc_key_create (&key, free_key_mem))
-	    /* Creating the key failed.  This either means we run
-	       have only a single-threaded application or something
-	       really went wrong.  In any case use a static buffer
-	       which is better than nothing.  */
-	    buffer = static_buf;
-	  else
-	    /* We have a key.  */
-	    initialized = 1;
-	}
-
-      __libc_lock_unlock (lock);
-    }
+  __libc_once (once, init);
 
+  if (static_buf != NULL)
+    return static_buf;
+
+  /* We don't use the static buffer and so we have a key.  Use it to
+     get the thread-specific buffer.  */
+  buffer = __libc_getspecific (key);
   if (buffer == NULL)
     {
-      /* We don't use the static buffer and so we have a key.  Use it
-	 to get the thread-specific buffer.  */
-      buffer = __libc_getspecific (key);
+      /* No buffer allocated so far.  */
+      buffer = malloc (18);
       if (buffer == NULL)
-	{
-	  /* No buffer allocated so far.  */
-	  buffer = malloc (18);
-	  if (buffer == NULL)
-	    /* No more memory available.  We use the static buffer.  */
-	    buffer = static_buf;
-	  else
-	    __libc_setspecific (key, buffer);
-	}
+	/* No more memory available.  We use the static buffer.  */
+	buffer = local_buf;
+      else
+	__libc_setspecific (key, buffer);
     }
 
   bytes = (unsigned char *) ∈
@@ -89,12 +74,21 @@ inet_ntoa (struct in_addr in)
 }
 
 
+/* Initialize buffer.  */
+static void
+init (void)
+{
+  if (__libc_key_create (&key, free_key_mem))
+    /* Creating the key failed.  This means something really went
+       wrong.  In any case use a static buffer which is better than
+       nothing.  */
+    static_buf = local_buf;
+}
+
+
+/* free the thread specific data, this is done if a thread terminates.  */
 static void
 free_key_mem (void *mem)
 {
   free (mem);
-
-  /* And we must set the data to NULL so that the destructor is not
-     called again.  */
-  __libc_setspecific (key, NULL);
 }