Commit 1a42dd17eb2c35fa572418f5958595cbe297d229

Russell Belfer 2013-05-31T14:13:11

Mutex init can fail It is obviously quite a serious problem if this happens, but mutex initialization can fail and we should detect it. It's a bit like a memory allocation failure, in that you're probably pretty screwed if this occurs, but at least we'll catch it.

diff --git a/src/cache.c b/src/cache.c
index 6205ef8..afc7c5b 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -68,7 +68,10 @@ int git_cache_init(git_cache *cache)
 {
 	memset(cache, 0, sizeof(*cache));
 	cache->map = git_oidmap_alloc();
-	git_mutex_init(&cache->lock);
+	if (git_mutex_init(&cache->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize cache mutex");
+		return -1;
+	}
 	return 0;
 }
 
diff --git a/src/global.c b/src/global.c
index a0571d1..2d40ca2 100644
--- a/src/global.c
+++ b/src/global.c
@@ -61,7 +61,8 @@ int git_threads_init(void)
 		return 0;
 
 	_tls_index = TlsAlloc();
-	git_mutex_init(&git__mwindow_mutex);
+	if (git_mutex_init(&git__mwindow_mutex))
+		return -1;
 
 	/* Initialize any other subsystems that have global state */
 	if ((error = git_hash_global_init()) >= 0)
@@ -121,7 +122,8 @@ int git_threads_init(void)
 	if (_tls_init)
 		return 0;
 
-	git_mutex_init(&git__mwindow_mutex);
+	if (git_mutex_init(&git__mwindow_mutex))
+		return -1;
 	pthread_key_create(&_tls_key, &cb__free_status);
 
 	/* Initialize any other subsystems that have global state */
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 3d38202..500104c 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -132,7 +132,10 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
 	if (git_mutex_init(&pb->cache_mutex) ||
 		git_mutex_init(&pb->progress_mutex) ||
 		git_cond_init(&pb->progress_cond))
+	{
+		giterr_set(GITERR_OS, "Failed to initialize packbuilder mutex");
 		goto on_error;
+	}
 
 #endif
 
diff --git a/src/pack.c b/src/pack.c
index a9b835f..7ce7099 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -97,7 +97,15 @@ static int cache_init(git_pack_cache *cache)
 	GITERR_CHECK_ALLOC(cache->entries);
 
 	cache->memory_limit = GIT_PACK_CACHE_MEMORY_LIMIT;
-	git_mutex_init(&cache->lock);
+
+	if (git_mutex_init(&cache->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize pack cache mutex");
+
+		git__free(cache->entries);
+		cache->entries = NULL;
+
+		return -1;
+	}
 
 	return 0;
 }
@@ -948,7 +956,11 @@ int git_packfile_alloc(struct git_pack_file **pack_out, const char *path)
 	p->mtime = (git_time_t)st.st_mtime;
 	p->index_version = -1;
 
-	git_mutex_init(&p->lock);
+	if (git_mutex_init(&p->lock)) {
+		giterr_set(GITERR_OS, "Failed to initialize packfile mutex");
+		git__free(p);
+		return -1;
+	}
 
 	/* see if we can parse the sha1 oid in the packfile name */
 	if (path_len < 40 ||
diff --git a/src/thread-utils.h b/src/thread-utils.h
index 49b5f3b..d4ed7e7 100644
--- a/src/thread-utils.h
+++ b/src/thread-utils.h
@@ -140,7 +140,7 @@ GIT_INLINE(int64_t) git_atomic64_add(git_atomic64 *a, int64_t addend)
 
 /* Pthreads Mutex */
 #define git_mutex unsigned int
-#define git_mutex_init(a) (void)0
+#define git_mutex_init(a) 0
 #define git_mutex_lock(a) 0
 #define git_mutex_unlock(a) (void)0
 #define git_mutex_free(a) (void)0