fd_posix_test.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /*
  2. *
  3. * Copyright 2015 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #include "src/core/lib/iomgr/port.h"
  19. // This test won't work except with posix sockets enabled
  20. #ifdef GRPC_POSIX_SOCKET_EV
  21. #include <ctype.h>
  22. #include <errno.h>
  23. #include <fcntl.h>
  24. #include <netinet/in.h>
  25. #include <poll.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <sys/socket.h>
  30. #include <sys/time.h>
  31. #include <unistd.h>
  32. #include <grpc/grpc.h>
  33. #include <grpc/support/alloc.h>
  34. #include <grpc/support/log.h>
  35. #include <grpc/support/sync.h>
  36. #include <grpc/support/time.h>
  37. #include "src/core/lib/iomgr/ev_posix.h"
  38. #include "src/core/lib/iomgr/iomgr.h"
  39. #include "src/core/lib/iomgr/socket_utils_posix.h"
  40. #include "test/core/util/test_config.h"
  41. static gpr_mu* g_mu;
  42. static grpc_pollset* g_pollset;
  43. /* buffer size used to send and receive data.
  44. 1024 is the minimal value to set TCP send and receive buffer. */
  45. #define BUF_SIZE 1024
  46. /* Create a test socket with the right properties for testing.
  47. port is the TCP port to listen or connect to.
  48. Return a socket FD and sockaddr_in. */
  49. static void create_test_socket(int port, int* socket_fd,
  50. struct sockaddr_in* sin) {
  51. int fd;
  52. int one = 1;
  53. int buffer_size_bytes = BUF_SIZE;
  54. int flags;
  55. fd = socket(AF_INET, SOCK_STREAM, 0);
  56. setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
  57. /* Reset the size of socket send buffer to the minimal value to facilitate
  58. buffer filling up and triggering notify_on_write */
  59. GPR_ASSERT(grpc_set_socket_sndbuf(fd, buffer_size_bytes) == GRPC_ERROR_NONE);
  60. GPR_ASSERT(grpc_set_socket_rcvbuf(fd, buffer_size_bytes) == GRPC_ERROR_NONE);
  61. /* Make fd non-blocking */
  62. flags = fcntl(fd, F_GETFL, 0);
  63. GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
  64. *socket_fd = fd;
  65. /* Use local address for test */
  66. sin->sin_family = AF_INET;
  67. sin->sin_addr.s_addr = htonl(0x7f000001);
  68. GPR_ASSERT(port >= 0 && port < 65536);
  69. sin->sin_port = htons(static_cast<uint16_t>(port));
  70. }
  71. /* Phony gRPC callback */
  72. void no_op_cb(void* /*arg*/, int /*success*/) {}
  73. /* =======An upload server to test notify_on_read===========
  74. The server simply reads and counts a stream of bytes. */
  75. /* An upload server. */
  76. typedef struct {
  77. grpc_fd* em_fd; /* listening fd */
  78. ssize_t read_bytes_total; /* total number of received bytes */
  79. int done; /* set to 1 when a server finishes serving */
  80. grpc_closure listen_closure;
  81. } server;
  82. static void server_init(server* sv) {
  83. sv->read_bytes_total = 0;
  84. sv->done = 0;
  85. }
  86. /* An upload session.
  87. Created when a new upload request arrives in the server. */
  88. typedef struct {
  89. server* sv; /* not owned by a single session */
  90. grpc_fd* em_fd; /* fd to read upload bytes */
  91. char read_buf[BUF_SIZE]; /* buffer to store upload bytes */
  92. grpc_closure session_read_closure;
  93. } session;
  94. /* Called when an upload session can be safely shutdown.
  95. Close session FD and start to shutdown listen FD. */
  96. static void session_shutdown_cb(void* arg, /*session */
  97. bool /*success*/) {
  98. session* se = static_cast<session*>(arg);
  99. server* sv = se->sv;
  100. grpc_fd_orphan(se->em_fd, nullptr, nullptr, "a");
  101. gpr_free(se);
  102. /* Start to shutdown listen fd. */
  103. grpc_fd_shutdown(sv->em_fd,
  104. GRPC_ERROR_CREATE_FROM_STATIC_STRING("session_shutdown_cb"));
  105. }
  106. /* Called when data become readable in a session. */
  107. static void session_read_cb(void* arg, /*session */
  108. grpc_error_handle error) {
  109. session* se = static_cast<session*>(arg);
  110. int fd = grpc_fd_wrapped_fd(se->em_fd);
  111. ssize_t read_once = 0;
  112. ssize_t read_total = 0;
  113. if (error != GRPC_ERROR_NONE) {
  114. session_shutdown_cb(arg, true);
  115. return;
  116. }
  117. do {
  118. read_once = read(fd, se->read_buf, BUF_SIZE);
  119. if (read_once > 0) read_total += read_once;
  120. } while (read_once > 0);
  121. se->sv->read_bytes_total += read_total;
  122. /* read() returns 0 to indicate the TCP connection was closed by the client.
  123. read(fd, read_buf, 0) also returns 0 which should never be called as such.
  124. It is possible to read nothing due to spurious edge event or data has
  125. been drained, In such a case, read() returns -1 and set errno to EAGAIN. */
  126. if (read_once == 0) {
  127. session_shutdown_cb(arg, true);
  128. } else if (read_once == -1) {
  129. if (errno == EAGAIN) {
  130. /* An edge triggered event is cached in the kernel until next poll.
  131. In the current single thread implementation, session_read_cb is called
  132. in the polling thread, such that polling only happens after this
  133. callback, and will catch read edge event if data is available again
  134. before notify_on_read.
  135. TODO(chenw): in multi-threaded version, callback and polling can be
  136. run in different threads. polling may catch a persist read edge event
  137. before notify_on_read is called. */
  138. grpc_fd_notify_on_read(se->em_fd, &se->session_read_closure);
  139. } else {
  140. gpr_log(GPR_ERROR, "Unhandled read error %s", strerror(errno));
  141. abort();
  142. }
  143. }
  144. }
  145. /* Called when the listen FD can be safely shutdown.
  146. Close listen FD and signal that server can be shutdown. */
  147. static void listen_shutdown_cb(void* arg /*server*/, int /*success*/) {
  148. server* sv = static_cast<server*>(arg);
  149. grpc_fd_orphan(sv->em_fd, nullptr, nullptr, "b");
  150. gpr_mu_lock(g_mu);
  151. sv->done = 1;
  152. GPR_ASSERT(
  153. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)));
  154. gpr_mu_unlock(g_mu);
  155. }
  156. /* Called when a new TCP connection request arrives in the listening port. */
  157. static void listen_cb(void* arg, /*=sv_arg*/
  158. grpc_error_handle error) {
  159. server* sv = static_cast<server*>(arg);
  160. int fd;
  161. int flags;
  162. session* se;
  163. struct sockaddr_storage ss;
  164. socklen_t slen = sizeof(ss);
  165. grpc_fd* listen_em_fd = sv->em_fd;
  166. if (error != GRPC_ERROR_NONE) {
  167. listen_shutdown_cb(arg, 1);
  168. return;
  169. }
  170. fd = accept(grpc_fd_wrapped_fd(listen_em_fd),
  171. reinterpret_cast<struct sockaddr*>(&ss), &slen);
  172. GPR_ASSERT(fd >= 0);
  173. GPR_ASSERT(fd < FD_SETSIZE);
  174. flags = fcntl(fd, F_GETFL, 0);
  175. fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  176. se = static_cast<session*>(gpr_malloc(sizeof(*se)));
  177. se->sv = sv;
  178. se->em_fd = grpc_fd_create(fd, "listener", false);
  179. grpc_pollset_add_fd(g_pollset, se->em_fd);
  180. GRPC_CLOSURE_INIT(&se->session_read_closure, session_read_cb, se,
  181. grpc_schedule_on_exec_ctx);
  182. grpc_fd_notify_on_read(se->em_fd, &se->session_read_closure);
  183. grpc_fd_notify_on_read(listen_em_fd, &sv->listen_closure);
  184. }
  185. /* Max number of connections pending to be accepted by listen(). */
  186. #define MAX_NUM_FD 1024
  187. /* Start a test server, return the TCP listening port bound to listen_fd.
  188. listen_cb() is registered to be interested in reading from listen_fd.
  189. When connection request arrives, listen_cb() is called to accept the
  190. connection request. */
  191. static int server_start(server* sv) {
  192. int port = 0;
  193. int fd;
  194. struct sockaddr_in sin;
  195. socklen_t addr_len;
  196. create_test_socket(port, &fd, &sin);
  197. addr_len = sizeof(sin);
  198. GPR_ASSERT(bind(fd, (struct sockaddr*)&sin, addr_len) == 0);
  199. GPR_ASSERT(getsockname(fd, (struct sockaddr*)&sin, &addr_len) == 0);
  200. port = ntohs(sin.sin_port);
  201. GPR_ASSERT(listen(fd, MAX_NUM_FD) == 0);
  202. sv->em_fd = grpc_fd_create(fd, "server", false);
  203. grpc_pollset_add_fd(g_pollset, sv->em_fd);
  204. /* Register to be interested in reading from listen_fd. */
  205. GRPC_CLOSURE_INIT(&sv->listen_closure, listen_cb, sv,
  206. grpc_schedule_on_exec_ctx);
  207. grpc_fd_notify_on_read(sv->em_fd, &sv->listen_closure);
  208. return port;
  209. }
  210. /* Wait and shutdown a sever. */
  211. static void server_wait_and_shutdown(server* sv) {
  212. gpr_mu_lock(g_mu);
  213. while (!sv->done) {
  214. grpc_core::ExecCtx exec_ctx;
  215. grpc_pollset_worker* worker = nullptr;
  216. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  217. "pollset_work", grpc_pollset_work(g_pollset, &worker,
  218. grpc_core::Timestamp::InfFuture())));
  219. gpr_mu_unlock(g_mu);
  220. gpr_mu_lock(g_mu);
  221. }
  222. gpr_mu_unlock(g_mu);
  223. }
  224. /* ===An upload client to test notify_on_write=== */
  225. /* Client write buffer size */
  226. #define CLIENT_WRITE_BUF_SIZE 10
  227. /* Total number of times that the client fills up the write buffer */
  228. #define CLIENT_TOTAL_WRITE_CNT 3
  229. /* An upload client. */
  230. typedef struct {
  231. grpc_fd* em_fd;
  232. char write_buf[CLIENT_WRITE_BUF_SIZE];
  233. ssize_t write_bytes_total;
  234. /* Number of times that the client fills up the write buffer and calls
  235. notify_on_write to schedule another write. */
  236. int client_write_cnt;
  237. int done; /* set to 1 when a client finishes sending */
  238. grpc_closure write_closure;
  239. } client;
  240. static void client_init(client* cl) {
  241. memset(cl->write_buf, 0, sizeof(cl->write_buf));
  242. cl->write_bytes_total = 0;
  243. cl->client_write_cnt = 0;
  244. cl->done = 0;
  245. }
  246. /* Called when a client upload session is ready to shutdown. */
  247. static void client_session_shutdown_cb(void* arg /*client*/, int /*success*/) {
  248. client* cl = static_cast<client*>(arg);
  249. grpc_fd_orphan(cl->em_fd, nullptr, nullptr, "c");
  250. cl->done = 1;
  251. GPR_ASSERT(
  252. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)));
  253. }
  254. /* Write as much as possible, then register notify_on_write. */
  255. static void client_session_write(void* arg, /*client */
  256. grpc_error_handle error) {
  257. client* cl = static_cast<client*>(arg);
  258. int fd = grpc_fd_wrapped_fd(cl->em_fd);
  259. ssize_t write_once = 0;
  260. if (error != GRPC_ERROR_NONE) {
  261. gpr_mu_lock(g_mu);
  262. client_session_shutdown_cb(arg, 1);
  263. gpr_mu_unlock(g_mu);
  264. return;
  265. }
  266. do {
  267. write_once = write(fd, cl->write_buf, CLIENT_WRITE_BUF_SIZE);
  268. if (write_once > 0) cl->write_bytes_total += write_once;
  269. } while (write_once > 0);
  270. if (errno == EAGAIN) {
  271. gpr_mu_lock(g_mu);
  272. if (cl->client_write_cnt < CLIENT_TOTAL_WRITE_CNT) {
  273. GRPC_CLOSURE_INIT(&cl->write_closure, client_session_write, cl,
  274. grpc_schedule_on_exec_ctx);
  275. grpc_fd_notify_on_write(cl->em_fd, &cl->write_closure);
  276. cl->client_write_cnt++;
  277. } else {
  278. client_session_shutdown_cb(arg, 1);
  279. }
  280. gpr_mu_unlock(g_mu);
  281. } else {
  282. gpr_log(GPR_ERROR, "unknown errno %s", strerror(errno));
  283. abort();
  284. }
  285. }
  286. /* Start a client to send a stream of bytes. */
  287. static void client_start(client* cl, int port) {
  288. int fd;
  289. struct sockaddr_in sin;
  290. create_test_socket(port, &fd, &sin);
  291. if (connect(fd, reinterpret_cast<struct sockaddr*>(&sin), sizeof(sin)) ==
  292. -1) {
  293. if (errno == EINPROGRESS) {
  294. struct pollfd pfd;
  295. pfd.fd = fd;
  296. pfd.events = POLLOUT;
  297. pfd.revents = 0;
  298. if (poll(&pfd, 1, -1) == -1) {
  299. gpr_log(GPR_ERROR, "poll() failed during connect; errno=%d", errno);
  300. abort();
  301. }
  302. } else {
  303. gpr_log(GPR_ERROR, "Failed to connect to the server (errno=%d)", errno);
  304. abort();
  305. }
  306. }
  307. cl->em_fd = grpc_fd_create(fd, "client", false);
  308. grpc_pollset_add_fd(g_pollset, cl->em_fd);
  309. client_session_write(cl, GRPC_ERROR_NONE);
  310. }
  311. /* Wait for the signal to shutdown a client. */
  312. static void client_wait_and_shutdown(client* cl) {
  313. gpr_mu_lock(g_mu);
  314. while (!cl->done) {
  315. grpc_pollset_worker* worker = nullptr;
  316. grpc_core::ExecCtx exec_ctx;
  317. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  318. "pollset_work", grpc_pollset_work(g_pollset, &worker,
  319. grpc_core::Timestamp::InfFuture())));
  320. gpr_mu_unlock(g_mu);
  321. gpr_mu_lock(g_mu);
  322. }
  323. gpr_mu_unlock(g_mu);
  324. }
  325. /* Test grpc_fd. Start an upload server and client, upload a stream of
  326. bytes from the client to the server, and verify that the total number of
  327. sent bytes is equal to the total number of received bytes. */
  328. static void test_grpc_fd(void) {
  329. server sv;
  330. client cl;
  331. int port;
  332. grpc_core::ExecCtx exec_ctx;
  333. server_init(&sv);
  334. port = server_start(&sv);
  335. client_init(&cl);
  336. client_start(&cl, port);
  337. client_wait_and_shutdown(&cl);
  338. server_wait_and_shutdown(&sv);
  339. GPR_ASSERT(sv.read_bytes_total == cl.write_bytes_total);
  340. gpr_log(GPR_INFO, "Total read bytes %" PRIdPTR, sv.read_bytes_total);
  341. }
  342. typedef struct fd_change_data {
  343. grpc_iomgr_cb_func cb_that_ran;
  344. } fd_change_data;
  345. void init_change_data(fd_change_data* fdc) { fdc->cb_that_ran = nullptr; }
  346. void destroy_change_data(fd_change_data* /*fdc*/) {}
  347. static void first_read_callback(void* arg /* fd_change_data */,
  348. grpc_error_handle /*error*/) {
  349. fd_change_data* fdc = static_cast<fd_change_data*>(arg);
  350. gpr_mu_lock(g_mu);
  351. fdc->cb_that_ran = first_read_callback;
  352. GPR_ASSERT(
  353. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)));
  354. gpr_mu_unlock(g_mu);
  355. }
  356. static void second_read_callback(void* arg /* fd_change_data */,
  357. grpc_error_handle /*error*/) {
  358. fd_change_data* fdc = static_cast<fd_change_data*>(arg);
  359. gpr_mu_lock(g_mu);
  360. fdc->cb_that_ran = second_read_callback;
  361. GPR_ASSERT(
  362. GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, nullptr)));
  363. gpr_mu_unlock(g_mu);
  364. }
  365. /* Test that changing the callback we use for notify_on_read actually works.
  366. Note that we have two different but almost identical callbacks above -- the
  367. point is to have two different function pointers and two different data
  368. pointers and make sure that changing both really works. */
  369. static void test_grpc_fd_change(void) {
  370. grpc_fd* em_fd;
  371. fd_change_data a, b;
  372. int flags;
  373. int sv[2];
  374. char data;
  375. ssize_t result;
  376. grpc_closure first_closure;
  377. grpc_closure second_closure;
  378. grpc_core::ExecCtx exec_ctx;
  379. GRPC_CLOSURE_INIT(&first_closure, first_read_callback, &a,
  380. grpc_schedule_on_exec_ctx);
  381. GRPC_CLOSURE_INIT(&second_closure, second_read_callback, &b,
  382. grpc_schedule_on_exec_ctx);
  383. init_change_data(&a);
  384. init_change_data(&b);
  385. GPR_ASSERT(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
  386. flags = fcntl(sv[0], F_GETFL, 0);
  387. GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0);
  388. flags = fcntl(sv[1], F_GETFL, 0);
  389. GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
  390. em_fd = grpc_fd_create(sv[0], "test_grpc_fd_change", false);
  391. grpc_pollset_add_fd(g_pollset, em_fd);
  392. /* Register the first callback, then make its FD readable */
  393. grpc_fd_notify_on_read(em_fd, &first_closure);
  394. data = 0;
  395. result = write(sv[1], &data, 1);
  396. GPR_ASSERT(result == 1);
  397. /* And now wait for it to run. */
  398. gpr_mu_lock(g_mu);
  399. while (a.cb_that_ran == nullptr) {
  400. grpc_pollset_worker* worker = nullptr;
  401. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  402. "pollset_work", grpc_pollset_work(g_pollset, &worker,
  403. grpc_core::Timestamp::InfFuture())));
  404. gpr_mu_unlock(g_mu);
  405. gpr_mu_lock(g_mu);
  406. }
  407. GPR_ASSERT(a.cb_that_ran == first_read_callback);
  408. gpr_mu_unlock(g_mu);
  409. /* And drain the socket so we can generate a new read edge */
  410. result = read(sv[0], &data, 1);
  411. GPR_ASSERT(result == 1);
  412. /* Now register a second callback with distinct change data, and do the same
  413. thing again. */
  414. grpc_fd_notify_on_read(em_fd, &second_closure);
  415. data = 0;
  416. result = write(sv[1], &data, 1);
  417. GPR_ASSERT(result == 1);
  418. gpr_mu_lock(g_mu);
  419. while (b.cb_that_ran == nullptr) {
  420. grpc_pollset_worker* worker = nullptr;
  421. GPR_ASSERT(GRPC_LOG_IF_ERROR(
  422. "pollset_work", grpc_pollset_work(g_pollset, &worker,
  423. grpc_core::Timestamp::InfFuture())));
  424. gpr_mu_unlock(g_mu);
  425. gpr_mu_lock(g_mu);
  426. }
  427. /* Except now we verify that second_read_callback ran instead */
  428. GPR_ASSERT(b.cb_that_ran == second_read_callback);
  429. gpr_mu_unlock(g_mu);
  430. grpc_fd_orphan(em_fd, nullptr, nullptr, "d");
  431. destroy_change_data(&a);
  432. destroy_change_data(&b);
  433. close(sv[1]);
  434. }
  435. static void destroy_pollset(void* p, grpc_error_handle /*error*/) {
  436. grpc_pollset_destroy(static_cast<grpc_pollset*>(p));
  437. }
  438. int main(int argc, char** argv) {
  439. grpc_closure destroyed;
  440. grpc::testing::TestEnvironment env(argc, argv);
  441. grpc_init();
  442. {
  443. grpc_core::ExecCtx exec_ctx;
  444. g_pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
  445. grpc_pollset_init(g_pollset, &g_mu);
  446. test_grpc_fd();
  447. test_grpc_fd_change();
  448. GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset,
  449. grpc_schedule_on_exec_ctx);
  450. grpc_pollset_shutdown(g_pollset, &destroyed);
  451. grpc_core::ExecCtx::Get()->Flush();
  452. gpr_free(g_pollset);
  453. }
  454. grpc_shutdown();
  455. return 0;
  456. }
  457. #else /* GRPC_POSIX_SOCKET_EV */
  458. int main(int argc, char** argv) { return 1; }
  459. #endif /* GRPC_POSIX_SOCKET_EV */