summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2017-09-10 08:08:22 (GMT)
committerJunio C Hamano <gitster@pobox.com>2017-09-10 08:08:22 (GMT)
commita48ce378585054f2ae3b2f0e18346ab005290524 (patch)
treebfb2fab6ffc87128bd4cbc03ff40a83ce07f8001
parent3ec7d702a89c647ddf42a59bc3539361367de9d5 (diff)
parent6cdf8a7929688ea5702ab53f450d038e973e64e1 (diff)
downloadgit-a48ce378585054f2ae3b2f0e18346ab005290524.zip
git-a48ce378585054f2ae3b2f0e18346ab005290524.tar.gz
git-a48ce378585054f2ae3b2f0e18346ab005290524.tar.bz2
Merge branch 'ma/ts-cleanups'
Assorted bugfixes and clean-ups. * ma/ts-cleanups: ThreadSanitizer: add suppressions strbuf_setlen: don't write to strbuf_slopbuf pack-objects: take lock before accessing `remaining` convert: always initialize attr_action in convert_attrs
-rw-r--r--.tsan-suppressions10
-rw-r--r--builtin/pack-objects.c6
-rw-r--r--color.c7
-rw-r--r--convert.c5
-rw-r--r--strbuf.h5
-rw-r--r--transport-helper.c7
6 files changed, 37 insertions, 3 deletions
diff --git a/.tsan-suppressions b/.tsan-suppressions
new file mode 100644
index 0000000..8c85014
--- /dev/null
+++ b/.tsan-suppressions
@@ -0,0 +1,10 @@
+# Suppressions for ThreadSanitizer (tsan).
+#
+# This file is used by setting the environment variable TSAN_OPTIONS to, e.g.,
+# "suppressions=$(pwd)/.tsan-suppressions". Observe that relative paths such as
+# ".tsan-suppressions" might not work.
+
+# A static variable is written to racily, but we always write the same value, so
+# in practice it (hopefully!) doesn't matter.
+race:^want_color$
+race:^transfer_debug$
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 82ad6e0..a57b4f0 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -2171,7 +2171,10 @@ static void *threaded_find_deltas(void *arg)
{
struct thread_params *me = arg;
+ progress_lock();
while (me->remaining) {
+ progress_unlock();
+
find_deltas(me->list, &me->remaining,
me->window, me->depth, me->processed);
@@ -2193,7 +2196,10 @@ static void *threaded_find_deltas(void *arg)
pthread_cond_wait(&me->cond, &me->mutex);
me->data_ready = 0;
pthread_mutex_unlock(&me->mutex);
+
+ progress_lock();
}
+ progress_unlock();
/* leave ->working 1 so that this doesn't get more work assigned */
return NULL;
}
diff --git a/color.c b/color.c
index 7aa8b07..9ccd954 100644
--- a/color.c
+++ b/color.c
@@ -338,6 +338,13 @@ static int check_auto_color(void)
int want_color(int var)
{
+ /*
+ * NEEDSWORK: This function is sometimes used from multiple threads, and
+ * we end up using want_auto racily. That "should not matter" since
+ * we always write the same value, but it's still wrong. This function
+ * is listed in .tsan-suppressions for the time being.
+ */
+
static int want_auto = -1;
if (var < 0)
diff --git a/convert.c b/convert.c
index c5f0b21..0296226 100644
--- a/convert.c
+++ b/convert.c
@@ -1040,7 +1040,6 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
ca->crlf_action = git_path_check_crlf(ccheck + 4);
if (ca->crlf_action == CRLF_UNDEFINED)
ca->crlf_action = git_path_check_crlf(ccheck + 0);
- ca->attr_action = ca->crlf_action;
ca->ident = git_path_check_ident(ccheck + 1);
ca->drv = git_path_check_convert(ccheck + 2);
if (ca->crlf_action != CRLF_BINARY) {
@@ -1054,12 +1053,14 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
else if (eol_attr == EOL_CRLF)
ca->crlf_action = CRLF_TEXT_CRLF;
}
- ca->attr_action = ca->crlf_action;
} else {
ca->drv = NULL;
ca->crlf_action = CRLF_UNDEFINED;
ca->ident = 0;
}
+
+ /* Save attr and make a decision for action */
+ ca->attr_action = ca->crlf_action;
if (ca->crlf_action == CRLF_TEXT)
ca->crlf_action = text_eol_is_crlf() ? CRLF_TEXT_CRLF : CRLF_TEXT_INPUT;
if (ca->crlf_action == CRLF_UNDEFINED && auto_crlf == AUTO_CRLF_FALSE)
diff --git a/strbuf.h b/strbuf.h
index e705b94..7496cb8 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -147,7 +147,10 @@ static inline void strbuf_setlen(struct strbuf *sb, size_t len)
if (len > (sb->alloc ? sb->alloc - 1 : 0))
die("BUG: strbuf_setlen() beyond buffer");
sb->len = len;
- sb->buf[len] = '\0';
+ if (sb->buf != strbuf_slopbuf)
+ sb->buf[len] = '\0';
+ else
+ assert(!strbuf_slopbuf[0]);
}
/**
diff --git a/transport-helper.c b/transport-helper.c
index 8f68d69..f50b34d 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1117,6 +1117,13 @@ int transport_helper_init(struct transport *transport, const char *name)
__attribute__((format (printf, 1, 2)))
static void transfer_debug(const char *fmt, ...)
{
+ /*
+ * NEEDSWORK: This function is sometimes used from multiple threads, and
+ * we end up using debug_enabled racily. That "should not matter" since
+ * we always write the same value, but it's still wrong. This function
+ * is listed in .tsan-suppressions for the time being.
+ */
+
va_list args;
char msgbuf[PBUFFERSIZE];
static int debug_enabled = -1;