| 
					
				 | 
			
			
				@@ -447,7 +447,395 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   config.tear_down_data(&f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void test_max_concurrent_streams_with_timeout_on_first( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_end2end_test_config config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_end2end_test_fixture f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_arg server_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_args server_args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *c1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *c2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *s1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *s2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier *cqv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details call_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array request_metadata_recv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array initial_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array trailing_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array initial_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array trailing_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_status_code status1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_error error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice details1 = grpc_empty_slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_status_code status2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice details2 = grpc_empty_slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op ops[6]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op *op; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int was_cancelled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.key = GRPC_ARG_MAX_CONCURRENT_STREAMS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.type = GRPC_ARG_INTEGER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.value.integer = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_args.num_args = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_args.args = &server_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  f = begin_test(config, "test_max_concurrent_streams_with_timeout_on_first", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 NULL, &server_args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cqv = cq_verifier_create(f.cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&request_metadata_recv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&initial_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&trailing_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&initial_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&trailing_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_init(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* perform a ping-pong to ensure that settings have had a chance to round 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     trip */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  simple_request_body(config, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* perform another one to make sure that the one stream case still works */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  simple_request_body(config, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* start two requests - ensuring that the second is not accepted until 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     the first completes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  c1 = grpc_channel_create_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice_from_static_string("/alpha"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get_host_override_slice("foo.test.google.fr:1234", config), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      n_seconds_time(3), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(c1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  c2 = grpc_channel_create_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice_from_static_string("/beta"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get_host_override_slice("foo.test.google.fr:1234", config), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      n_seconds_time(1000), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(c2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 f.server, &s1, &call_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 &request_metadata_recv, f.cq, f.cq, tag(101))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status = &status1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status_details = &details1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_initial_metadata.recv_initial_metadata = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      &initial_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(301), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status = &status2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status_details = &details2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_initial_metadata.recv_initial_metadata = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      &initial_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(402), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_destroy(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_init(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 f.server, &s2, &call_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 &request_metadata_recv, f.cq, f.cq, tag(201))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(302), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* first request is finished, we should be able to start the second */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(401), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(201), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_close_on_server.cancelled = &was_cancelled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.trailing_metadata_count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice status_details = grpc_slice_from_static_string("xyz"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.status_details = &status_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(s2, ops, (size_t)(op - ops), tag(202), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(402), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(202), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier_destroy(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(c1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(s1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(c2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(s2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice_unref(details1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice_unref(details2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&initial_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&trailing_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&initial_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&trailing_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&request_metadata_recv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_destroy(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end_test(&f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config.tear_down_data(&f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void test_max_concurrent_streams_with_timeout_on_second( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_end2end_test_config config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_end2end_test_fixture f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_arg server_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_channel_args server_args; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *c1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *c2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call *s1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier *cqv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details call_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array request_metadata_recv; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array initial_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array trailing_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array initial_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array trailing_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_status_code status1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_error error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice details1 = grpc_empty_slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_status_code status2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice details2 = grpc_empty_slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op ops[6]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_op *op; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int was_cancelled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.key = GRPC_ARG_MAX_CONCURRENT_STREAMS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.type = GRPC_ARG_INTEGER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_arg.value.integer = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_args.num_args = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  server_args.args = &server_arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  f = begin_test(config, "test_max_concurrent_streams_with_timeout_on_second", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 NULL, &server_args); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cqv = cq_verifier_create(f.cq); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&request_metadata_recv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&initial_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&trailing_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&initial_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_init(&trailing_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_init(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* perform a ping-pong to ensure that settings have had a chance to round 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     trip */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  simple_request_body(config, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* perform another one to make sure that the one stream case still works */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  simple_request_body(config, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* start two requests - ensuring that the second is not accepted until 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     the first completes , and the second request will timeout in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     concurrent_list */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  c1 = grpc_channel_create_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice_from_static_string("/alpha"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get_host_override_slice("foo.test.google.fr:1234", config), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      n_seconds_time(1000), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(c1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  c2 = grpc_channel_create_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      grpc_slice_from_static_string("/beta"), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get_host_override_slice("foo.test.google.fr:1234", config), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      n_seconds_time(3), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(c2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 f.server, &s1, &call_details, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 &request_metadata_recv, f.cq, f.cq, tag(101))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status = &status1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status_details = &details1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_initial_metadata.recv_initial_metadata = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      &initial_metadata_recv1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(301), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status = &status2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_status_on_client.status_details = &details2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_initial_metadata.recv_initial_metadata = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      &initial_metadata_recv2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(402), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* the second request is time out*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(401), 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(402), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* second request is finished because of time out, so destroy the second call 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(c2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* now reply the first call */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  memset(ops, 0, sizeof(ops)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op = ops; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_INITIAL_METADATA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_initial_metadata.count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.recv_close_on_server.cancelled = &was_cancelled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.trailing_metadata_count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice status_details = grpc_slice_from_static_string("xyz"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->data.send_status_from_server.status_details = &status_details; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op->reserved = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  op++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  error = grpc_call_start_batch(s1, ops, (size_t)(op - ops), tag(102), NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_CALL_OK == error); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(302), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CQ_EXPECT_COMPLETION(cqv, tag(102), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verify(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cq_verifier_destroy(cqv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(c1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_destroy(s1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice_unref(details1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_slice_unref(details2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&initial_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&trailing_metadata_recv1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&initial_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&trailing_metadata_recv2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_metadata_array_destroy(&request_metadata_recv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_call_details_destroy(&call_details); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  end_test(&f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  config.tear_down_data(&f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void max_concurrent_streams(grpc_end2end_test_config config) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_max_concurrent_streams_with_timeout_on_first(config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_max_concurrent_streams_with_timeout_on_second(config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   test_max_concurrent_streams(config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |