Explain the usage of is_valid in pthread mutexes

Document the usage inside the library, and relate it with how it's
additionally used in the test code.

Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
diff --git a/include/mbedtls/threading.h b/include/mbedtls/threading.h
index a5d0a34..f1d53bd 100644
--- a/include/mbedtls/threading.h
+++ b/include/mbedtls/threading.h
@@ -70,6 +70,9 @@
 typedef struct
 {
     pthread_mutex_t mutex;
+    /* is_valid is 0 after a failed init or a free, and nonzero after a
+     * successful init. This field is not considered part of the public
+     * API of Mbed TLS and may change without notice. */
     char is_valid;
 } mbedtls_threading_mutex_t;
 #endif
diff --git a/library/threading.c b/library/threading.c
index 838cd74..df16fe7 100644
--- a/library/threading.c
+++ b/library/threading.c
@@ -60,6 +60,12 @@
     if( mutex == NULL )
         return;
 
+    /* A nonzero value of is_valid indicates a successfully initialized
+     * mutex. This is a workaround for not being able to return an error
+     * code for this function. The lock/unlock functions return an error
+     * if is_valid is nonzero. The Mbed TLS unit test code uses this field
+     * to distinguish more states of the mutex; see helpers.function for
+     * details. */
     mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0;
 }
 
diff --git a/tests/suites/helpers.function b/tests/suites/helpers.function
index 19f0af5..65bb2ff 100644
--- a/tests/suites/helpers.function
+++ b/tests/suites/helpers.function
@@ -575,8 +575,13 @@
  * indicate the exact location of the problematic call. To locate the error,
  * use a debugger and set a breakpoint on mbedtls_test_mutex_usage_error().
  */
-enum value_of_mutex_is_valid
+enum value_of_mutex_is_valid_field
 {
+    /* Potential values for the is_valid field of mbedtls_threading_mutex_t.
+     * Note that MUTEX_FREED must be 0 and MUTEX_IDLE must be 1 for
+     * compatibility with threading_mutex_init_pthread() and
+     * threading_mutex_free_pthread(). MUTEX_LOCKED could be any nonzero
+     * value. */
     MUTEX_FREED = 0, //!< Set by threading_mutex_free_pthread
     MUTEX_IDLE = 1, //!< Set by threading_mutex_init_pthread and by our unlock
     MUTEX_LOCKED = 2, //!< Set by our lock