| 
					
				 | 
			
			
				@@ -0,0 +1,472 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Copyright 2016, Google Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * All rights reserved. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Redistribution and use in source and binary forms, with or without 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * modification, are permitted provided that the following conditions are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * met: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *     * Redistributions of source code must retain the above copyright 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * notice, this list of conditions and the following disclaimer. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *     * Redistributions in binary form must reproduce the above 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * copyright notice, this list of conditions and the following disclaimer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * in the documentation and/or other materials provided with the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * distribution. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *     * Neither the name of Google Inc. nor the names of its 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * contributors may be used to endorse or promote products derived from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * this software without specific prior written permission. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/iomgr/port.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* This test only relevant on linux systems */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef GRPC_POSIX_SOCKET 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/iomgr/ev_posix.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <errno.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <string.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <unistd.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <grpc/support/alloc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include <grpc/support/log.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "src/core/lib/iomgr/iomgr.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "test/core/util/test_config.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/******************************************************************************* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * test_pollset_set 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct test_pollset_set { grpc_pollset_set *pss; } test_pollset_set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void init_test_pollset_sets(test_pollset_set pollset_sets[], int num_pss) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_pss; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollset_sets[i].pss = grpc_pollset_set_create(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void cleanup_test_pollset_sets(test_pollset_set pollset_sets[], int num_pss) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_pss; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_pollset_set_destroy(pollset_sets[i].pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollset_sets[i].pss = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/******************************************************************************* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * test_pollset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct test_pollset { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset *ps; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu *mu; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} test_pollset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void init_test_pollsets(test_pollset pollsets[], int num_pollsets) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_pollsets; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollsets[i].ps = gpr_malloc(grpc_pollset_size()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_pollset_init(pollsets[i].ps, &pollsets[i].mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            grpc_error *error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_destroy(p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void cleanup_test_pollsets(grpc_exec_ctx *exec_ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  test_pollset pollsets[], int num_pollsets) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_closure destroyed; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_pollsets; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_pollset_shutdown(exec_ctx, pollsets[i].ps, &destroyed); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_exec_ctx_flush(exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_free(pollsets[i].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollsets[i].ps = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/******************************************************************************* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * test_fd 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+typedef struct test_fd { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_fd *fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_wakeup_fd wakeup_fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  bool is_on_readable_called; /* Is on_readable closure is called ? */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_closure on_readable;   /* Closure to call when this fd is readable */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} test_fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void on_readable(grpc_exec_ctx *exec_ctx, void *tfd, grpc_error *error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ((test_fd *)tfd)->is_on_readable_called = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void reset_test_fd(grpc_exec_ctx *exec_ctx, test_fd *tfd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  tfd->is_on_readable_called = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_closure_init(&tfd->on_readable, on_readable, tfd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_fd_notify_on_read(exec_ctx, tfd->fd, &tfd->on_readable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void init_test_fds(grpc_exec_ctx *exec_ctx, test_fd tfds[], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          int num_fds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_fds; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_init(&tfds[i].wakeup_fd)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tfds[i].fd = grpc_fd_create(GRPC_WAKEUP_FD_GET_READ_FD(&tfds[i].wakeup_fd), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                "test_fd"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    reset_test_fd(exec_ctx, &tfds[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void cleanup_test_fds(grpc_exec_ctx *exec_ctx, test_fd *tfds, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             int num_fds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int release_fd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_fds; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_fd_shutdown(exec_ctx, tfds[i].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_exec_ctx_flush(exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * calls close() on the underlying fd. In our case, we are using 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * grpc_wakeup_fd and we would like to destroy it ourselves (by calling 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * grpc_wakeup_fd_destroy). To prevent grpc_fd from calling close() on the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * underlying fd, call it with a non-NULL 'release_fd' parameter */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, "test_fd_cleanup"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_exec_ctx_flush(exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_wakeup_fd_destroy(&tfds[i].wakeup_fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void make_test_fds_readable(test_fd tfds[], int num_fds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_fds; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_wakeup(&tfds[i].wakeup_fd)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void verify_readable_and_reset(grpc_exec_ctx *exec_ctx, test_fd tfds[], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      int num_fds) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_fds; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Verify that the on_readable callback was called */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(tfds[i].is_on_readable_called); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* Reset the tfd[i] structure */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(GRPC_ERROR_NONE == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               grpc_wakeup_fd_consume_wakeup(&tfds[i].wakeup_fd)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    reset_test_fd(exec_ctx, &tfds[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/******************************************************************************* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Main tests 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Test some typical scenarios in pollset_set */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void pollset_set_test_basic() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* We construct the following structure for this test: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> FD0 (Added before PSS1, PS1 and PS2 are added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> FD5 (Added after PSS1, PS1 and PS2 are added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD1 (Added before PSS1 is added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD6 (Added after PSS1 is added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PSS1--+           +--> FD2 (Added before PS0 is added to PSS1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> PS0---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |                       | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * PSS0---+                       +--> FD7 (Added after PS0 is added to PSS1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD3 (Added before PS1 is added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PS1---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD8 (Added after PS1 added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD4 (Added before PS2 is added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PS2---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    +---> FD9 (Added after PS2 is added to PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_worker *worker; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_timespec deadline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_fd tfds[10]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset pollsets[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset_set pollset_sets[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_fds = sizeof(tfds) / sizeof(tfds[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_ps = sizeof(pollsets) / sizeof(pollsets[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_pss = sizeof(pollset_sets) / sizeof(pollset_sets[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollsets(pollsets, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollset_sets(pollset_sets, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Construct the pollset_set/pollset/fd tree (see diagram above) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[0].ps, tfds[2].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[3].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[2].ps, tfds[4].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset_set(&exec_ctx, pollset_sets[0].pss, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   pollset_sets[1].pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[1].pss, pollsets[0].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[1].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[2].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[5].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[6].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[0].ps, tfds[7].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[8].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[2].ps, tfds[9].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Test that if any FD in the above structure is readable, it is observable by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * doing grpc_pollset_work on any pollset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *   For every pollset, do the following: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *     - (Ensure that all FDs are in reset state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *     - Make all FDs readable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *     - Call grpc_pollset_work() on the pollset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *     - Flush the exec_ctx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *     - Verify that on_readable call back was called for all FDs (and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *       reset the FDs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; i < num_ps; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    make_test_fds_readable(tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_mu_lock(pollsets[i].mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    deadline = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    GPR_ASSERT(GRPC_ERROR_NONE == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               grpc_pollset_work(&exec_ctx, pollsets[i].ps, &worker, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 gpr_now(GPR_CLOCK_MONOTONIC), deadline)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_mu_unlock(pollsets[i].mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    verify_readable_and_reset(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Test tear down */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[5].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[6].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[1].pss, pollsets[0].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[1].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[2].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset_set(&exec_ctx, pollset_sets[0].pss, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   pollset_sets[1].pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollsets(&exec_ctx, pollsets, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollset_sets(pollset_sets, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_finish(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Same FD added multiple times to the pollset_set tree */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void pollset_set_test_dup_fds() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* We construct the following structure for this test: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> FD0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * PSS0---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           +---> FD0 (also under PSS0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PSS1--+           +--> FD1 (also under PSS1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    +---> PS ---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    |           | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    |           +--> FD2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                    +---> FD1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_worker *worker; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_timespec deadline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_fd tfds[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset pollset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset_set pollset_sets[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_fds = sizeof(tfds) / sizeof(tfds[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_ps = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_pss = sizeof(pollset_sets) / sizeof(pollset_sets[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollsets(&pollset, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollset_sets(pollset_sets, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Construct the structure */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollset.ps, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollset.ps, tfds[2].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[1].pss, pollset.ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset_set(&exec_ctx, pollset_sets[0].pss, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   pollset_sets[1].pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Test. Make all FDs readable and make sure that can be observed by doing a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * grpc_pollset_work on the pollset 'PS' */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  make_test_fds_readable(tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_lock(pollset.mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  deadline = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_ERROR_NONE == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             grpc_pollset_work(&exec_ctx, pollset.ps, &worker, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               gpr_now(GPR_CLOCK_MONOTONIC), deadline)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_unlock(pollset.mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  verify_readable_and_reset(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Tear down */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[1].pss, pollset.ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset_set(&exec_ctx, pollset_sets[0].pss, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   pollset_sets[1].pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollsets(&exec_ctx, &pollset, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollset_sets(pollset_sets, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_finish(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Pollset_set with an empty pollset */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void pollset_set_test_empty_pollset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* We construct the following structure for this test: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PS0 (EMPTY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> FD0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * PSS0---+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |          +---> FD1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        |          | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *        +---> PS1--+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                   | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   *                   +---> FD2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_worker *worker; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_timespec deadline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_fd tfds[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset pollsets[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  test_pollset_set pollset_set; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_fds = sizeof(tfds) / sizeof(tfds[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_ps = sizeof(pollsets) / sizeof(pollsets[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  int num_pss = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollsets(pollsets, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  init_test_pollset_sets(&pollset_set, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Construct the structure */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_fd(&exec_ctx, pollset_set.pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[1].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[2].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_set.pss, pollsets[0].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_add_pollset(&exec_ctx, pollset_set.pss, pollsets[1].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Test. Make all FDs readable and make sure that can be observed by doing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * grpc_pollset_work on the empty pollset 'PS0' */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  make_test_fds_readable(tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_lock(pollsets[0].mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  deadline = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  GPR_ASSERT(GRPC_ERROR_NONE == 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             grpc_pollset_work(&exec_ctx, pollsets[0].ps, &worker, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               gpr_now(GPR_CLOCK_MONOTONIC), deadline)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  gpr_mu_unlock(pollsets[0].mu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  verify_readable_and_reset(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* Tear down */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_fd(&exec_ctx, pollset_set.pss, tfds[0].fd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_set.pss, pollsets[0].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_pollset_set_del_pollset(&exec_ctx, pollset_set.pss, pollsets[1].ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_flush(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_fds(&exec_ctx, tfds, num_fds); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollsets(&exec_ctx, pollsets, num_ps); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  cleanup_test_pollset_sets(&pollset_set, num_pss); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_exec_ctx_finish(&exec_ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int main(int argc, char **argv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  const char *poll_strategy = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_test_init(argc, argv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_iomgr_init(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  poll_strategy = grpc_get_poll_strategy_name(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (poll_strategy != NULL && strcmp(poll_strategy, "epoll") == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollset_set_test_basic(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollset_set_test_dup_fds(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pollset_set_test_empty_pollset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    gpr_log(GPR_INFO, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "Skipping the test. The test is only relevant for 'epoll' " 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "strategy. and the current strategy is: '%s'", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            poll_strategy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  grpc_iomgr_shutdown(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else /* defined(GRPC_LINUX_EPOLL) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int main(int argc, char **argv) { return 0; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif /* !defined(GRPC_LINUX_EPOLL) */ 
			 |