| 
					
				 | 
			
			
				@@ -72,6 +72,9 @@ static grpc_fd *fd_freelist = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static gpr_mu fd_freelist_mu; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void freelist_fd(grpc_fd *fd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Note that this function must be called after a release store (or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // full-barrier operation) on refst so that prior actions on the fd are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // ordered before the fd becomes visible to the freelist 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   gpr_mu_lock(&fd_freelist_mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   fd->freelist_next = fd_freelist; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   fd_freelist = fd; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -92,7 +95,6 @@ static grpc_fd *alloc_fd(int fd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     gpr_mu_init(&r->mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  gpr_atm_rel_store(&r->refst, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->shutdown = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->read_closure = CLOSURE_NOT_READY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->write_closure = CLOSURE_NOT_READY; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -104,6 +106,11 @@ static grpc_fd *alloc_fd(int fd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->on_done_closure = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->closed = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   r->released = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // The last operation on r before returning it should be a release-store 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // so that all the above fields are globally visible before the value of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // r could escape to another thread. Our refcount itself needs a release-store 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // so use this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_atm_rel_store(&r->refst, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |