test-pr-poll-loop.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  1. /*
  2. * Copyright (c) 2015-2020 Red Hat, Inc.
  3. *
  4. * All rights reserved.
  5. *
  6. * Author: Jan Friesse (jfriesse@redhat.com)
  7. *
  8. * This software licensed under BSD license, the text of which follows:
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions are met:
  12. *
  13. * - Redistributions of source code must retain the above copyright notice,
  14. * this list of conditions and the following disclaimer.
  15. * - Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. * - Neither the name of the Red Hat, Inc. nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  23. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  26. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  27. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  28. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  29. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  30. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  31. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  32. * THE POSSIBILITY OF SUCH DAMAGE.
  33. */
  34. #include <stdio.h>
  35. #include <assert.h>
  36. #include <string.h>
  37. #include <errno.h>
  38. #include <unistd.h>
  39. #include "pr-poll-loop.h"
  40. /*
  41. * Needed for creating nspr handle from unix fd
  42. */
  43. #include <private/pprio.h>
  44. #define BUF_SIZE 256
  45. #define TIMER_TIMEOUT 10000
  46. #define TIMER_TEST_TIMEOUT 100
  47. /*
  48. * Must be smaller than BUF_SIZE
  49. */
  50. #define READ_STR "test"
  51. static int fd_set_events_cb1_return_called = 0;
  52. static int fd_set_events_cb2_return_called = 0;
  53. static int fd_read_cb1_called = 0;
  54. static int fd_read_cb2_called = 0;
  55. static int fd_write_cb1_called = 0;
  56. static int fd_err_cb1_called = 0;
  57. static int timeout_cb_called = 0;
  58. static int prfd_set_events_cb1_return_called = 0;
  59. static int prfd_set_events_cb2_return_called = 0;
  60. static int prfd_read_cb1_called = 0;
  61. static int prfd_read_cb2_called = 0;
  62. static int prfd_write_cb1_called = 0;
  63. static int prfd_err_cb1_called = 0;
  64. static int
  65. timeout_cb(void *data1, void *data2)
  66. {
  67. timeout_cb_called = 1;
  68. return (0);
  69. }
  70. static int
  71. fd_set_events_cb1_return(int fd, short *events, void *user_data1, void *user_data2)
  72. {
  73. fd_set_events_cb1_return_called++;
  74. assert(user_data1 == &fd_set_events_cb1_return_called);
  75. assert(user_data2 == NULL);
  76. return (-2);
  77. }
  78. static int
  79. fd_set_events_cb2_return(int fd, short *events, void *user_data1, void *user_data2)
  80. {
  81. fd_set_events_cb2_return_called++;
  82. assert(user_data1 == NULL);
  83. assert(user_data2 == &fd_set_events_cb2_return_called);
  84. return (-2);
  85. }
  86. static int
  87. fd_read_cb1(int fd, void *user_data1, void *user_data2)
  88. {
  89. char buf[BUF_SIZE];
  90. assert(user_data1 == &fd_read_cb1_called);
  91. assert(user_data2 == fd_read_cb1);
  92. fd_read_cb1_called++;
  93. assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  94. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  95. return (0);
  96. }
  97. static int
  98. fd_read_cb2(int fd, void *user_data1, void *user_data2)
  99. {
  100. char buf[BUF_SIZE];
  101. assert(user_data1 == &fd_read_cb2_called);
  102. assert(user_data2 == fd_read_cb2);
  103. fd_read_cb2_called++;
  104. assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  105. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  106. return (-1);
  107. }
  108. static int
  109. fd_write_cb1(int fd, void *user_data1, void *user_data2)
  110. {
  111. assert(user_data1 == &fd_write_cb1_called);
  112. assert(user_data2 == fd_write_cb1);
  113. fd_write_cb1_called++;
  114. return (0);
  115. }
  116. static int
  117. fd_err_cb1(int fd, short revents, void *user_data1, void *user_data2)
  118. {
  119. assert(user_data1 == &fd_err_cb1_called);
  120. assert(user_data2 == fd_err_cb1);
  121. fd_err_cb1_called++;
  122. return (0);
  123. }
  124. static int
  125. prfd_set_events_cb1_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  126. {
  127. prfd_set_events_cb1_return_called++;
  128. assert(user_data1 == &prfd_set_events_cb1_return_called);
  129. assert(user_data2 == NULL);
  130. return (-2);
  131. }
  132. static int
  133. prfd_set_events_cb2_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  134. {
  135. prfd_set_events_cb2_return_called++;
  136. assert(user_data1 == NULL);
  137. assert(user_data2 == &prfd_set_events_cb2_return_called);
  138. return (-2);
  139. }
  140. static int
  141. prfd_read_cb1(PRFileDesc *prfd, void *user_data1, void *user_data2)
  142. {
  143. char buf[BUF_SIZE];
  144. assert(user_data1 == &prfd_read_cb1_called);
  145. assert(user_data2 == prfd_read_cb1);
  146. prfd_read_cb1_called++;
  147. assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  148. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  149. return (0);
  150. }
  151. static int
  152. prfd_read_cb2(PRFileDesc *prfd, void *user_data1, void *user_data2)
  153. {
  154. char buf[BUF_SIZE];
  155. assert(user_data1 == &prfd_read_cb2_called);
  156. assert(user_data2 == prfd_read_cb2);
  157. prfd_read_cb2_called++;
  158. assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  159. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  160. return (-1);
  161. }
  162. static int
  163. prfd_write_cb1(PRFileDesc *prfd, void *user_data1, void *user_data2)
  164. {
  165. assert(user_data1 == &prfd_write_cb1_called);
  166. assert(user_data2 == prfd_write_cb1);
  167. prfd_write_cb1_called++;
  168. return (0);
  169. }
  170. static int
  171. prfd_err_cb1(PRFileDesc *prfd, short revents, void *user_data1, void *user_data2)
  172. {
  173. assert(user_data1 == &prfd_err_cb1_called);
  174. assert(user_data2 == prfd_err_cb1);
  175. prfd_err_cb1_called++;
  176. return (0);
  177. }
  178. static void
  179. init_global_vars(void)
  180. {
  181. fd_set_events_cb1_return_called = -1;
  182. fd_set_events_cb2_return_called = -1;
  183. fd_read_cb1_called = -1;
  184. fd_read_cb2_called = -1;
  185. fd_write_cb1_called = -1;
  186. fd_err_cb1_called = -1;
  187. timeout_cb_called = -1;
  188. prfd_set_events_cb1_return_called = -1;
  189. prfd_set_events_cb2_return_called = -1;
  190. prfd_read_cb1_called = -1;
  191. prfd_read_cb2_called = -1;
  192. prfd_write_cb1_called = -1;
  193. prfd_err_cb1_called = -1;
  194. }
  195. static void
  196. test_fd_basics(struct pr_poll_loop *poll_loop)
  197. {
  198. int pipe_fd1[2];
  199. struct timer_list_entry *timeout_timer;
  200. init_global_vars();
  201. /*
  202. * Add POLLNVAL -> failure
  203. */
  204. assert(pr_poll_loop_add_fd(poll_loop, 0, POLLNVAL, NULL, NULL, NULL, NULL,
  205. NULL, NULL) == -1);
  206. /*
  207. * Del non-existing fdL -> failure
  208. */
  209. assert(pr_poll_loop_del_fd(poll_loop, 0) == -1);
  210. /*
  211. * Add and delete fd twice
  212. */
  213. assert(pr_poll_loop_add_fd(poll_loop, 0, 0, NULL, NULL, NULL, NULL,
  214. NULL, NULL) == 0);
  215. assert(pr_poll_loop_add_fd(poll_loop, 0, 0, NULL, NULL, NULL, NULL,
  216. NULL, NULL) == -1);
  217. assert(pr_poll_loop_del_fd(poll_loop, 0) == 0);
  218. assert(pr_poll_loop_del_fd(poll_loop, 0) == -1);
  219. /*
  220. * Test timeout timer
  221. * with empty list
  222. */
  223. assert((timeout_timer = timer_list_add(
  224. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  225. timeout_cb_called = 0;
  226. assert(pr_poll_loop_exec(poll_loop) == 0);
  227. assert(timeout_cb_called == 1);
  228. /*
  229. * Test user_data passing
  230. */
  231. assert(pipe(pipe_fd1) == 0);
  232. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, fd_set_events_cb1_return,
  233. NULL, NULL, NULL, (void *)&fd_set_events_cb1_return_called, NULL) == 0);
  234. fd_set_events_cb1_return_called = 0;
  235. assert((timeout_timer = timer_list_add(
  236. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  237. assert(pr_poll_loop_exec(poll_loop) == -1);
  238. assert(fd_set_events_cb1_return_called == 1);
  239. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  240. /*
  241. * Remove entry and try different cb
  242. */
  243. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  244. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, fd_set_events_cb2_return,
  245. NULL, NULL, NULL, NULL, (void *)&fd_set_events_cb2_return_called) == 0);
  246. fd_set_events_cb1_return_called = 0;
  247. fd_set_events_cb2_return_called = 0;
  248. assert((timeout_timer = timer_list_add(
  249. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  250. assert(pr_poll_loop_exec(poll_loop) == -1);
  251. assert(fd_set_events_cb1_return_called == 0);
  252. assert(fd_set_events_cb2_return_called == 1);
  253. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  254. /*
  255. * Delete entry and try timeout again
  256. */
  257. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == -1);
  258. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0);
  259. assert((timeout_timer = timer_list_add(
  260. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  261. timeout_cb_called = 0;
  262. assert(pr_poll_loop_exec(poll_loop) == 0);
  263. assert(timeout_cb_called == 1);
  264. /*
  265. * Try reading
  266. */
  267. assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  268. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  269. fd_read_cb1, NULL, NULL,
  270. &fd_read_cb1_called, fd_read_cb1) == 0);
  271. fd_read_cb1_called = 0;
  272. timeout_cb_called = 0;
  273. assert((timeout_timer = timer_list_add(
  274. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  275. assert(pr_poll_loop_exec(poll_loop) == 0);
  276. assert(fd_read_cb1_called == 1);
  277. assert(timeout_cb_called == 0);
  278. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  279. /*
  280. * Try timeout with valid entry
  281. */
  282. assert((timeout_timer = timer_list_add(
  283. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  284. timeout_cb_called = 0;
  285. fd_read_cb1_called = 0;
  286. assert(pr_poll_loop_exec(poll_loop) == 0);
  287. assert(timeout_cb_called == 1);
  288. assert(fd_read_cb1_called == 0);
  289. /*
  290. * Try reading where cb returns err
  291. */
  292. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  293. assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  294. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  295. fd_read_cb2, NULL, NULL,
  296. &fd_read_cb2_called, fd_read_cb2) == 0);
  297. fd_read_cb1_called = 0;
  298. fd_read_cb2_called = 0;
  299. timeout_cb_called = 0;
  300. assert((timeout_timer = timer_list_add(
  301. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  302. assert(pr_poll_loop_exec(poll_loop) == -1);
  303. assert(fd_read_cb1_called == 0);
  304. assert(fd_read_cb2_called == 1);
  305. assert(timeout_cb_called == 0);
  306. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  307. /*
  308. * Try writing
  309. */
  310. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  311. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, NULL,
  312. NULL, fd_write_cb1, NULL,
  313. &fd_write_cb1_called, fd_write_cb1) == 0);
  314. fd_write_cb1_called = 0;
  315. timeout_cb_called = 0;
  316. assert((timeout_timer = timer_list_add(
  317. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  318. assert(pr_poll_loop_exec(poll_loop) == 0);
  319. assert(fd_write_cb1_called == 1);
  320. assert(timeout_cb_called == 0);
  321. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  322. /*
  323. * Try err cb
  324. */
  325. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0);
  326. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  327. NULL, NULL, fd_err_cb1,
  328. &fd_err_cb1_called, fd_err_cb1) == 0);
  329. assert(close(pipe_fd1[0]) == 0);
  330. assert(close(pipe_fd1[1]) == 0);
  331. fd_err_cb1_called = 0;
  332. timeout_cb_called = 0;
  333. fd_write_cb1_called = 0;
  334. assert((timeout_timer = timer_list_add(
  335. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  336. assert(pr_poll_loop_exec(poll_loop) == 0);
  337. assert(fd_err_cb1_called == 1);
  338. assert(fd_write_cb1_called == 0);
  339. assert(timeout_cb_called == 0);
  340. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  341. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  342. }
  343. static void
  344. test_prfd_basics(struct pr_poll_loop *poll_loop)
  345. {
  346. PRFileDesc *read_pipe;
  347. PRFileDesc *write_pipe;
  348. struct timer_list_entry *timeout_timer;
  349. int pipe_fd1[2];
  350. init_global_vars();
  351. assert(PR_CreatePipe(&read_pipe, &write_pipe) == PR_SUCCESS);
  352. /*
  353. * Add POLLNVAL -> failure
  354. */
  355. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLNVAL, NULL, NULL, NULL, NULL,
  356. NULL, NULL) == -1);
  357. /*
  358. * Del non-existing fdL -> failure
  359. */
  360. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  361. /*
  362. * Add and delete fd twice
  363. */
  364. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL,
  365. NULL, NULL) == 0);
  366. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL,
  367. NULL, NULL) == -1);
  368. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  369. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  370. /*
  371. * Test user_data passing
  372. */
  373. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, prfd_set_events_cb1_return,
  374. NULL, NULL, NULL, (void *)&prfd_set_events_cb1_return_called, NULL) == 0);
  375. prfd_set_events_cb1_return_called = 0;
  376. assert((timeout_timer = timer_list_add(
  377. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  378. assert(pr_poll_loop_exec(poll_loop) == -1);
  379. assert(prfd_set_events_cb1_return_called == 1);
  380. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  381. /*
  382. * Remove entry and try different cb
  383. */
  384. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  385. assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, prfd_set_events_cb2_return,
  386. NULL, NULL, NULL, NULL, (void *)&prfd_set_events_cb2_return_called) == 0);
  387. prfd_set_events_cb1_return_called = 0;
  388. prfd_set_events_cb2_return_called = 0;
  389. assert((timeout_timer = timer_list_add(
  390. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  391. assert(pr_poll_loop_exec(poll_loop) == -1);
  392. assert(prfd_set_events_cb1_return_called == 0);
  393. assert(prfd_set_events_cb2_return_called == 1);
  394. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  395. /*
  396. * Delete entry and try timeout again
  397. */
  398. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  399. assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0);
  400. assert((timeout_timer = timer_list_add(
  401. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  402. timeout_cb_called = 0;
  403. assert(pr_poll_loop_exec(poll_loop) == 0);
  404. assert(timeout_cb_called == 1);
  405. /*
  406. * Try reading
  407. */
  408. assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  409. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  410. prfd_read_cb1, NULL, NULL,
  411. &prfd_read_cb1_called, prfd_read_cb1) == 0);
  412. prfd_read_cb1_called = 0;
  413. timeout_cb_called = 0;
  414. assert((timeout_timer = timer_list_add(
  415. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  416. assert(pr_poll_loop_exec(poll_loop) == 0);
  417. assert(prfd_read_cb1_called == 1);
  418. assert(timeout_cb_called == 0);
  419. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  420. /*
  421. * Try timeout with valid entry
  422. */
  423. assert((timeout_timer = timer_list_add(
  424. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  425. timeout_cb_called = 0;
  426. prfd_read_cb1_called = 0;
  427. assert(pr_poll_loop_exec(poll_loop) == 0);
  428. assert(timeout_cb_called == 1);
  429. assert(prfd_read_cb1_called == 0);
  430. /*
  431. * Try reading where cb returns err
  432. */
  433. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  434. assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  435. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  436. prfd_read_cb2, NULL, NULL,
  437. &prfd_read_cb2_called, prfd_read_cb2) == 0);
  438. prfd_read_cb1_called = 0;
  439. prfd_read_cb2_called = 0;
  440. timeout_cb_called = 0;
  441. assert((timeout_timer = timer_list_add(
  442. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  443. assert(pr_poll_loop_exec(poll_loop) == -1);
  444. assert(prfd_read_cb1_called == 0);
  445. assert(prfd_read_cb2_called == 1);
  446. assert(timeout_cb_called == 0);
  447. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  448. /*
  449. * Try writing
  450. */
  451. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  452. assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, NULL,
  453. NULL, prfd_write_cb1, NULL,
  454. &prfd_write_cb1_called, prfd_write_cb1) == 0);
  455. prfd_write_cb1_called = 0;
  456. timeout_cb_called = 0;
  457. assert((timeout_timer = timer_list_add(
  458. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  459. assert(pr_poll_loop_exec(poll_loop) == 0);
  460. assert(prfd_write_cb1_called == 1);
  461. assert(timeout_cb_called == 0);
  462. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  463. assert(PR_Close(read_pipe) == 0);
  464. assert(PR_Close(write_pipe) == 0);
  465. /*
  466. * Try err cb
  467. */
  468. assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0);
  469. /*
  470. * Must use native pipe, because PR_Close deallocate PRFileDesc completelly
  471. */
  472. assert(pipe(pipe_fd1) == 0);
  473. assert((read_pipe = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL);
  474. assert(close(pipe_fd1[0]) == 0);
  475. assert(close(pipe_fd1[1]) == 0);
  476. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  477. NULL, NULL, prfd_err_cb1,
  478. &prfd_err_cb1_called, prfd_err_cb1) == 0);
  479. prfd_err_cb1_called = 0;
  480. timeout_cb_called = 0;
  481. prfd_write_cb1_called = 0;
  482. assert((timeout_timer = timer_list_add(
  483. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  484. assert(pr_poll_loop_exec(poll_loop) == 0);
  485. assert(prfd_err_cb1_called == 1);
  486. assert(prfd_write_cb1_called == 0);
  487. assert(timeout_cb_called == 0);
  488. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  489. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  490. assert(PR_DestroySocketPollFd(read_pipe) == PR_SUCCESS);
  491. }
  492. int
  493. main(void)
  494. {
  495. struct pr_poll_loop poll_loop;
  496. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  497. pr_poll_loop_init(&poll_loop);
  498. test_fd_basics(&poll_loop);
  499. test_prfd_basics(&poll_loop);
  500. pr_poll_loop_destroy(&poll_loop);
  501. assert(PR_Cleanup() == PR_SUCCESS);
  502. return (0);
  503. }