@@ -1240,21 +1240,23 @@ class MutexBase {
1240
1240
void Lock () {
1241
1241
GTEST_CHECK_POSIX_SUCCESS_ (pthread_mutex_lock (&mutex_));
1242
1242
owner_ = pthread_self ();
1243
+ has_owner_ = true ;
1243
1244
}
1244
1245
1245
1246
// Releases this mutex.
1246
1247
void Unlock () {
1247
- // We don't protect writing to owner_ here, as it's the caller's
1248
- // responsibility to ensure that the current thread holds the
1248
+ // Since the lock is being released the owner_ field should no longer be
1249
+ // considered valid. We don't protect writing to has_owner_ here, as it's
1250
+ // the caller's responsibility to ensure that the current thread holds the
1249
1251
// mutex when this is called.
1250
- owner_ = 0 ;
1252
+ has_owner_ = false ;
1251
1253
GTEST_CHECK_POSIX_SUCCESS_ (pthread_mutex_unlock (&mutex_));
1252
1254
}
1253
1255
1254
1256
// Does nothing if the current thread holds the mutex. Otherwise, crashes
1255
1257
// with high probability.
1256
1258
void AssertHeld () const {
1257
- GTEST_CHECK_ (owner_ == pthread_self ())
1259
+ GTEST_CHECK_ (has_owner_ && pthread_equal (owner_, pthread_self () ))
1258
1260
<< " The current thread is not holding the mutex @" << this ;
1259
1261
}
1260
1262
@@ -1265,24 +1267,36 @@ class MutexBase {
1265
1267
// have to be public.
1266
1268
public:
1267
1269
pthread_mutex_t mutex_; // The underlying pthread mutex.
1268
- pthread_t owner_; // The thread holding the mutex; 0 means no one holds it.
1270
+ // has_owner_ indicates whether the owner_ field below contains a valid thread
1271
+ // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All
1272
+ // accesses to the owner_ field should be protected by a check of this field.
1273
+ // An alternative might be to memset() owner_ to all zeros, but there's no
1274
+ // guarantee that a zero'd pthread_t is necessarily invalid or even different
1275
+ // from pthread_self().
1276
+ bool has_owner_;
1277
+ pthread_t owner_; // The thread holding the mutex.
1269
1278
};
1270
1279
1271
1280
// Forward-declares a static mutex.
1272
1281
# define GTEST_DECLARE_STATIC_MUTEX_ (mutex ) \
1273
1282
extern ::testing::internal::MutexBase mutex
1274
1283
1275
1284
// Defines and statically (i.e. at link time) initializes a static mutex.
1285
+ // The initialization list here does not explicitly initialize each field,
1286
+ // instead relying on default initialization for the unspecified fields. In
1287
+ // particular, the owner_ field (a pthread_t) is not explicitly initialized.
1288
+ // This allows initialization to work whether pthread_t is a scalar or struct.
1289
+ // The flag -Wmissing-field-initializers must not be specified for this to work.
1276
1290
# define GTEST_DEFINE_STATIC_MUTEX_ (mutex ) \
1277
- ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 }
1291
+ ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false }
1278
1292
1279
1293
// The Mutex class can only be used for mutexes created at runtime. It
1280
1294
// shares its API with MutexBase otherwise.
1281
1295
class Mutex : public MutexBase {
1282
1296
public:
1283
1297
Mutex () {
1284
1298
GTEST_CHECK_POSIX_SUCCESS_ (pthread_mutex_init (&mutex_, NULL ));
1285
- owner_ = 0 ;
1299
+ has_owner_ = false ;
1286
1300
}
1287
1301
~Mutex () {
1288
1302
GTEST_CHECK_POSIX_SUCCESS_ (pthread_mutex_destroy (&mutex_));
0 commit comments