[PATCH 2/2] Make sha1_to_hex thread-safe
From: Fredrik Kuivinen <hidden>
Date: 2016-06-15 22:48:29
Subsystem:
the rest · Maintainer:
Linus Torvalds
Signed-off-by: Fredrik Kuivinen <redacted> --- hex.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/hex.c b/hex.c
index bb402fb..fe1d302 100644
--- a/hex.c
+++ b/hex.c@@ -1,5 +1,9 @@ #include "cache.h" +#ifndef NO_PTHREADS +#include <pthread.h> +#endif + const signed char hexval_table[256] = { -1, -1, -1, -1, -1, -1, -1, -1, /* 00-07 */ -1, -1, -1, -1, -1, -1, -1, -1, /* 08-0f */
@@ -48,6 +52,7 @@ int get_sha1_hex(const char *hex, unsigned char *sha1) return 0; } +#ifdef NO_PTHREADS char *sha1_to_hex(const unsigned char *sha1) { static int bufno;
@@ -65,3 +70,51 @@ char *sha1_to_hex(const unsigned char *sha1) return buffer; } +#else +static pthread_once_t sha1_to_hex_once = PTHREAD_ONCE_INIT; +static pthread_key_t sha1_to_hex_key; + +static void sha1_to_hex_init(void) +{ + int err = pthread_key_create(&sha1_to_hex_key, free); + if (err) + die("pthread_key_create failed: %s", strerror(err)); +} + +struct sha1_to_hex_buf +{ + int no; + char hex[4][50]; +}; + +char *sha1_to_hex(const unsigned char *sha1) +{ + static const char hex[] = "0123456789abcdef"; + struct sha1_to_hex_buf *hexbuf; + int i; + char *buffer, *buf; + + pthread_once(&sha1_to_hex_once, sha1_to_hex_init); + + hexbuf = pthread_getspecific(sha1_to_hex_key); + if (!hexbuf) { + int err; + hexbuf = xmalloc(sizeof(struct sha1_to_hex_buf)); + hexbuf->no = 0; + err = pthread_setspecific(sha1_to_hex_key, hexbuf); + if (err) + die("pthread_getspecific failed: %s", strerror(err)); + } + + buffer = hexbuf->hex[3 & ++hexbuf->no], buf = buffer; + + for (i = 0; i < 20; i++) { + unsigned int val = *sha1++; + *buf++ = hex[val >> 4]; + *buf++ = hex[val & 0xf]; + } + *buf = '\0'; + + return buffer; +} +#endif