From: Fredrik Kuivinen Date: Tue, 23 Mar 2010 17:31:30 GMT Subject: [PATCH 2/2] Make sha1_to_hex thread-safe Message-ID: <20100323173130.GC4218@fredrik-laptop> In-Reply-To: <20100323161713.3183.57927.stgit@fredrik-laptop> Signed-off-by: Fredrik Kuivinen --- 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 +#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