|  | @@ -17,6 +17,7 @@
 | 
	
		
			
				|  |  |   */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #include <grpc/support/port_platform.h>
 | 
	
		
			
				|  |  | +#include <grpc/support/alloc.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #ifdef GPR_POSIX_SYNC
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -72,27 +73,58 @@ gpr_atm gpr_counter_atm_add = 0;
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void gpr_mu_init(gpr_mu* mu) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_mutex_init(&mu->mutex, nullptr) == 0);
 | 
	
		
			
				|  |  | +  mu->leak_checker = (int*)gpr_malloc(sizeof(*mu->leak_checker));
 | 
	
		
			
				|  |  | +  GPR_ASSERT(mu->leak_checker != nullptr);
 | 
	
		
			
				|  |  | +  /* Initial it with a magic number, make no sense, just use the memory.
 | 
	
		
			
				|  |  | +  * This only take effect when ASAN enabled, so,
 | 
	
		
			
				|  |  | +  * if memory allocation failed, let it crash.
 | 
	
		
			
				|  |  | +  */
 | 
	
		
			
				|  |  | +  *mu->leak_checker = 0x12F34D0;
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_mutex_init(mu, nullptr) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void gpr_mu_destroy(gpr_mu* mu) { GPR_ASSERT(pthread_mutex_destroy(mu) == 0); }
 | 
	
		
			
				|  |  | +void gpr_mu_destroy(gpr_mu* mu) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_mutex_destroy(&mu->mutex) == 0);
 | 
	
		
			
				|  |  | +  gpr_free(mu->leak_checker);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_mutex_destroy(mu) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void gpr_mu_lock(gpr_mu* mu) {
 | 
	
		
			
				|  |  |  #ifdef GPR_LOW_LEVEL_COUNTERS
 | 
	
		
			
				|  |  |    GPR_ATM_INC_COUNTER(gpr_mu_locks);
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |    GPR_TIMER_SCOPE("gpr_mu_lock", 0);
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_mutex_lock(&mu->mutex) == 0);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_mutex_lock(mu) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void gpr_mu_unlock(gpr_mu* mu) {
 | 
	
		
			
				|  |  |    GPR_TIMER_SCOPE("gpr_mu_unlock", 0);
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_mutex_unlock(&mu->mutex) == 0);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_mutex_unlock(mu) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  int gpr_mu_trylock(gpr_mu* mu) {
 | 
	
		
			
				|  |  |    GPR_TIMER_SCOPE("gpr_mu_trylock", 0);
 | 
	
		
			
				|  |  | -  int err = pthread_mutex_trylock(mu);
 | 
	
		
			
				|  |  | +  int err = 0;
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  err = pthread_mutex_trylock(&mu->mutex);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +  err = pthread_mutex_trylock(mu);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |    GPR_ASSERT(err == 0 || err == EBUSY);
 | 
	
		
			
				|  |  |    return err == 0;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -105,10 +137,29 @@ void gpr_cv_init(gpr_cv* cv) {
 | 
	
		
			
				|  |  |  #if GPR_LINUX
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0);
 | 
	
		
			
				|  |  |  #endif  // GPR_LINUX
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_init(&cv->cond_var, &attr) == 0);
 | 
	
		
			
				|  |  | +  cv->leak_checker = (int*)gpr_malloc(sizeof(*cv->leak_checker));
 | 
	
		
			
				|  |  | +  GPR_ASSERT(cv->leak_checker != nullptr);
 | 
	
		
			
				|  |  | +  /* Initial it with a magic number, make no sense, just use the memory.
 | 
	
		
			
				|  |  | +  * This only take effect when ASAN enabled, so,
 | 
	
		
			
				|  |  | +  * if memory allocation failed, let it crash.
 | 
	
		
			
				|  |  | +  */
 | 
	
		
			
				|  |  | +  *cv->leak_checker = 0x12F34D0;
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_cond_init(cv, &attr) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); }
 | 
	
		
			
				|  |  | +void gpr_cv_destroy(gpr_cv* cv) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_destroy(&cv->cond_var) == 0);
 | 
	
		
			
				|  |  | +  gpr_free(cv->leak_checker);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_destroy(cv) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  // For debug of the timer manager crash only.
 | 
	
		
			
				|  |  |  // TODO (mxyan): remove after bug is fixed.
 | 
	
	
		
			
				|  | @@ -169,7 +220,11 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
 | 
	
		
			
				|  |  |  #endif
 | 
	
		
			
				|  |  |    if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
 | 
	
		
			
				|  |  |        0) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +    err = pthread_cond_wait(&cv->cond_var, &mu->mutex);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |      err = pthread_cond_wait(cv, mu);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |    } else {
 | 
	
		
			
				|  |  |      struct timespec abs_deadline_ts;
 | 
	
		
			
				|  |  |  #if GPR_LINUX
 | 
	
	
		
			
				|  | @@ -181,7 +236,13 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
 | 
	
		
			
				|  |  |  #endif  // GPR_LINUX
 | 
	
		
			
				|  |  |      abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
 | 
	
		
			
				|  |  |      abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +    err = pthread_cond_timedwait(&cv->cond_var, &mu->mutex, &abs_deadline_ts);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |      err = pthread_cond_timedwait(cv, mu, &abs_deadline_ts);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  #ifdef GRPC_DEBUG_TIMER_MANAGER
 | 
	
		
			
				|  |  |      // For debug of the timer manager crash only.
 | 
	
		
			
				|  |  |      // TODO (mxyan): remove after bug is fixed.
 | 
	
	
		
			
				|  | @@ -226,10 +287,20 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
 | 
	
		
			
				|  |  |    return err == ETIMEDOUT;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -void gpr_cv_signal(gpr_cv* cv) { GPR_ASSERT(pthread_cond_signal(cv) == 0); }
 | 
	
		
			
				|  |  | +void gpr_cv_signal(gpr_cv* cv) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_signal(&cv->cond_var) == 0);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_signal(cv) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void gpr_cv_broadcast(gpr_cv* cv) {
 | 
	
		
			
				|  |  | +#ifdef GRPC_ASAN_ENABLED
 | 
	
		
			
				|  |  | +  GPR_ASSERT(pthread_cond_broadcast(&cv->cond_var) == 0);
 | 
	
		
			
				|  |  | +#else
 | 
	
		
			
				|  |  |    GPR_ASSERT(pthread_cond_broadcast(cv) == 0);
 | 
	
		
			
				|  |  | +#endif
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /*----------------------------------------*/
 |