summaryrefslogtreecommitdiff
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);
}