| 
					
				 | 
			
			
				@@ -380,6 +380,19 @@ void grpc_test_init(int /*argc*/, char** /*argv*/) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   srand(seed()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool grpc_wait_until_shutdown(int64_t time_s) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(time_s); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  while (grpc_is_initialized()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_maybe_wait_for_async_shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 gpr_time_from_millis(1, GPR_TIMESPAN))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace grpc { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 namespace testing { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -390,15 +403,8 @@ TestEnvironment::TestEnvironment(int argc, char** argv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 TestEnvironment::~TestEnvironment() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // This will wait until gRPC shutdown has actually happened to make sure 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // no gRPC resources (such as thread) are active. (timeout = 10s) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  while (grpc_is_initialized()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    grpc_maybe_wait_for_async_shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 gpr_time_from_millis(1, GPR_TIMESPAN))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (gpr_time_cmp(gpr_now(GPR_CLOCK_MONOTONIC), deadline) > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      gpr_log(GPR_ERROR, "Timeout in waiting for gRPC shutdown"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!grpc_wait_until_shutdown(10)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_ERROR, "Timeout in waiting for gRPC shutdown"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (BuiltUnderMsan()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // This is a workaround for MSAN. MSAN doesn't like having shutdown thread 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -412,5 +418,14 @@ TestEnvironment::~TestEnvironment() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_log(GPR_INFO, "TestEnvironment ends"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+TestGrpcScope::TestGrpcScope() { grpc_init(); } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+TestGrpcScope::~TestGrpcScope() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!grpc_wait_until_shutdown(10)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_ERROR, "Timeout in waiting for gRPC shutdown"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }  // namespace testing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }  // namespace grpc 
			 |