test-pr-poll-loop.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022
  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 test_complex_state = 0;
  65. static int test_complex_set_events_pipe1_read_called = 0;
  66. static int test_complex_read_pipe1_read_called = 0;
  67. static int test_complex_set_events_pipe1_write_called = 0;
  68. static int test_complex_write_pipe1_write_called = 0;
  69. static int test_complex_set_events_pipe2_read_called = 0;
  70. static int test_complex_read_pipe2_read_called = 0;
  71. static int test_complex_set_events_pipe2_write_called = 0;
  72. static int test_complex_write_pipe2_write_called = 0;
  73. static int test_complex_read_pipe1_fd = 0;
  74. static int
  75. timeout_cb(void *data1, void *data2)
  76. {
  77. timeout_cb_called = 1;
  78. return (0);
  79. }
  80. static int
  81. fd_set_events_cb1_return(int fd, short *events, void *user_data1, void *user_data2)
  82. {
  83. fd_set_events_cb1_return_called++;
  84. assert(user_data1 == &fd_set_events_cb1_return_called);
  85. assert(user_data2 == NULL);
  86. return (-2);
  87. }
  88. static int
  89. fd_set_events_cb2_return(int fd, short *events, void *user_data1, void *user_data2)
  90. {
  91. fd_set_events_cb2_return_called++;
  92. assert(user_data1 == NULL);
  93. assert(user_data2 == &fd_set_events_cb2_return_called);
  94. return (-2);
  95. }
  96. static int
  97. fd_read_cb1(int fd, void *user_data1, void *user_data2)
  98. {
  99. char buf[BUF_SIZE];
  100. assert(user_data1 == &fd_read_cb1_called);
  101. assert(user_data2 == fd_read_cb1);
  102. fd_read_cb1_called++;
  103. assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  104. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  105. return (0);
  106. }
  107. static int
  108. fd_read_cb2(int fd, void *user_data1, void *user_data2)
  109. {
  110. char buf[BUF_SIZE];
  111. assert(user_data1 == &fd_read_cb2_called);
  112. assert(user_data2 == fd_read_cb2);
  113. fd_read_cb2_called++;
  114. assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  115. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  116. return (-1);
  117. }
  118. static int
  119. fd_write_cb1(int fd, void *user_data1, void *user_data2)
  120. {
  121. assert(user_data1 == &fd_write_cb1_called);
  122. assert(user_data2 == fd_write_cb1);
  123. fd_write_cb1_called++;
  124. return (0);
  125. }
  126. static int
  127. fd_err_cb1(int fd, short revents, void *user_data1, void *user_data2)
  128. {
  129. assert(user_data1 == &fd_err_cb1_called);
  130. assert(user_data2 == fd_err_cb1);
  131. fd_err_cb1_called++;
  132. return (0);
  133. }
  134. static int
  135. prfd_set_events_cb1_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  136. {
  137. prfd_set_events_cb1_return_called++;
  138. assert(user_data1 == &prfd_set_events_cb1_return_called);
  139. assert(user_data2 == NULL);
  140. return (-2);
  141. }
  142. static int
  143. prfd_set_events_cb2_return(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  144. {
  145. prfd_set_events_cb2_return_called++;
  146. assert(user_data1 == NULL);
  147. assert(user_data2 == &prfd_set_events_cb2_return_called);
  148. return (-2);
  149. }
  150. static int
  151. prfd_read_cb1(PRFileDesc *prfd, void *user_data1, void *user_data2)
  152. {
  153. char buf[BUF_SIZE];
  154. assert(user_data1 == &prfd_read_cb1_called);
  155. assert(user_data2 == prfd_read_cb1);
  156. prfd_read_cb1_called++;
  157. assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  158. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  159. return (0);
  160. }
  161. static int
  162. prfd_read_cb2(PRFileDesc *prfd, void *user_data1, void *user_data2)
  163. {
  164. char buf[BUF_SIZE];
  165. assert(user_data1 == &prfd_read_cb2_called);
  166. assert(user_data2 == prfd_read_cb2);
  167. prfd_read_cb2_called++;
  168. assert(PR_Read(prfd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  169. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  170. return (-1);
  171. }
  172. static int
  173. prfd_write_cb1(PRFileDesc *prfd, void *user_data1, void *user_data2)
  174. {
  175. assert(user_data1 == &prfd_write_cb1_called);
  176. assert(user_data2 == prfd_write_cb1);
  177. prfd_write_cb1_called++;
  178. return (0);
  179. }
  180. static int
  181. prfd_err_cb1(PRFileDesc *prfd, short revents, void *user_data1, void *user_data2)
  182. {
  183. assert(user_data1 == &prfd_err_cb1_called);
  184. assert(user_data2 == prfd_err_cb1);
  185. prfd_err_cb1_called++;
  186. return (0);
  187. }
  188. static int
  189. test_complex_set_events_pipe1_read_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  190. {
  191. test_complex_set_events_pipe1_read_called++;
  192. assert(user_data1 == &test_complex_set_events_pipe1_read_called);
  193. assert(user_data2 == test_complex_set_events_pipe1_read_cb);
  194. assert(*events == 0);
  195. if (test_complex_state == 2) {
  196. *events = POLLIN;
  197. }
  198. return (0);
  199. }
  200. static int
  201. test_complex_read_pipe1_read_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
  202. {
  203. char buf[BUF_SIZE];
  204. assert(user_data1 == &test_complex_set_events_pipe1_read_called);
  205. assert(user_data2 == test_complex_set_events_pipe1_read_cb);
  206. test_complex_read_pipe1_read_called++;
  207. /*
  208. * prfd for this case is just a wrapper, we need to use real fd
  209. */
  210. assert(read(test_complex_read_pipe1_fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  211. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  212. return (0);
  213. }
  214. static int
  215. test_complex_write_pipe1_read_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
  216. {
  217. assert(0);
  218. return (-1);
  219. }
  220. static int
  221. test_complex_set_events_pipe1_write_cb(int fd, short *events, void *user_data1, void *user_data2)
  222. {
  223. test_complex_set_events_pipe1_write_called++;
  224. assert(user_data1 == &test_complex_set_events_pipe1_write_called);
  225. assert(user_data2 == test_complex_set_events_pipe1_write_cb);
  226. assert(*events == 0);
  227. if (test_complex_state == 1) {
  228. *events = POLLOUT;
  229. }
  230. return (0);
  231. }
  232. static int
  233. test_complex_read_pipe1_write_cb(int fd, void *user_data1, void *user_data2)
  234. {
  235. assert(0);
  236. return (-1);
  237. }
  238. static int
  239. test_complex_write_pipe1_write_cb(int fd, void *user_data1, void *user_data2)
  240. {
  241. assert(user_data1 == &test_complex_set_events_pipe1_write_called);
  242. assert(user_data2 == test_complex_set_events_pipe1_write_cb);
  243. test_complex_write_pipe1_write_called++;
  244. return (0);
  245. }
  246. static int
  247. test_complex_set_events_pipe2_read_cb(int fd, short *events, void *user_data1, void *user_data2)
  248. {
  249. test_complex_set_events_pipe2_read_called++;
  250. assert(user_data1 == &test_complex_set_events_pipe2_read_called);
  251. assert(user_data2 == test_complex_set_events_pipe2_read_cb);
  252. assert(*events == POLLIN);
  253. return (0);
  254. }
  255. static int
  256. test_complex_read_pipe2_read_cb(int fd, void *user_data1, void *user_data2)
  257. {
  258. char buf[BUF_SIZE];
  259. assert(user_data1 == &test_complex_set_events_pipe2_read_called);
  260. assert(user_data2 == test_complex_set_events_pipe2_read_cb);
  261. test_complex_read_pipe2_read_called++;
  262. assert(read(fd, buf, BUF_SIZE) == strlen(READ_STR) + 1);
  263. assert(memcmp(buf, READ_STR, strlen(READ_STR) + 1) == 0);
  264. return (0);
  265. }
  266. static int
  267. test_complex_write_pipe2_read_cb(int fd, void *user_data1, void *user_data2)
  268. {
  269. assert(0);
  270. return (-1);
  271. }
  272. static int
  273. test_complex_set_events_pipe2_write_cb(PRFileDesc *prfd, short *events, void *user_data1, void *user_data2)
  274. {
  275. test_complex_set_events_pipe2_write_called++;
  276. assert(user_data1 == &test_complex_set_events_pipe2_write_called);
  277. assert(user_data2 == test_complex_set_events_pipe2_write_cb);
  278. assert(*events == POLLOUT);
  279. return (0);
  280. }
  281. static int
  282. test_complex_read_pipe2_write_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
  283. {
  284. assert(0);
  285. return (-1);
  286. }
  287. static int
  288. test_complex_write_pipe2_write_cb(PRFileDesc *prfd, void *user_data1, void *user_data2)
  289. {
  290. assert(user_data1 == &test_complex_set_events_pipe2_write_called);
  291. assert(user_data2 == test_complex_set_events_pipe2_write_cb);
  292. test_complex_write_pipe2_write_called++;
  293. return (0);
  294. }
  295. static void
  296. init_global_vars(void)
  297. {
  298. fd_set_events_cb1_return_called = -1;
  299. fd_set_events_cb2_return_called = -1;
  300. fd_read_cb1_called = -1;
  301. fd_read_cb2_called = -1;
  302. fd_write_cb1_called = -1;
  303. fd_err_cb1_called = -1;
  304. timeout_cb_called = -1;
  305. prfd_set_events_cb1_return_called = -1;
  306. prfd_set_events_cb2_return_called = -1;
  307. prfd_read_cb1_called = -1;
  308. prfd_read_cb2_called = -1;
  309. prfd_write_cb1_called = -1;
  310. prfd_err_cb1_called = -1;
  311. }
  312. static void
  313. test_fd_basics(struct pr_poll_loop *poll_loop)
  314. {
  315. int pipe_fd1[2];
  316. struct timer_list_entry *timeout_timer;
  317. init_global_vars();
  318. /*
  319. * Add POLLNVAL -> failure
  320. */
  321. assert(pr_poll_loop_add_fd(poll_loop, 0, POLLNVAL, NULL, NULL, NULL, NULL,
  322. NULL, NULL) == -1);
  323. /*
  324. * Del non-existing fdL -> failure
  325. */
  326. assert(pr_poll_loop_del_fd(poll_loop, 0) == -1);
  327. /*
  328. * Add and delete fd twice
  329. */
  330. assert(pr_poll_loop_add_fd(poll_loop, 0, 0, NULL, NULL, NULL, NULL,
  331. NULL, NULL) == 0);
  332. assert(pr_poll_loop_add_fd(poll_loop, 0, 0, NULL, NULL, NULL, NULL,
  333. NULL, NULL) == -1);
  334. assert(pr_poll_loop_del_fd(poll_loop, 0) == 0);
  335. assert(pr_poll_loop_del_fd(poll_loop, 0) == -1);
  336. /*
  337. * Test timeout timer
  338. * with empty list
  339. */
  340. assert((timeout_timer = timer_list_add(
  341. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  342. timeout_cb_called = 0;
  343. assert(pr_poll_loop_exec(poll_loop) == 0);
  344. assert(timeout_cb_called == 1);
  345. /*
  346. * Test user_data passing
  347. */
  348. assert(pipe(pipe_fd1) == 0);
  349. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, fd_set_events_cb1_return,
  350. NULL, NULL, NULL, (void *)&fd_set_events_cb1_return_called, NULL) == 0);
  351. fd_set_events_cb1_return_called = 0;
  352. assert((timeout_timer = timer_list_add(
  353. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  354. assert(pr_poll_loop_exec(poll_loop) == -1);
  355. assert(fd_set_events_cb1_return_called == 1);
  356. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  357. /*
  358. * Remove entry and try different cb
  359. */
  360. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  361. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, fd_set_events_cb2_return,
  362. NULL, NULL, NULL, NULL, (void *)&fd_set_events_cb2_return_called) == 0);
  363. fd_set_events_cb1_return_called = 0;
  364. fd_set_events_cb2_return_called = 0;
  365. assert((timeout_timer = timer_list_add(
  366. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  367. assert(pr_poll_loop_exec(poll_loop) == -1);
  368. assert(fd_set_events_cb1_return_called == 0);
  369. assert(fd_set_events_cb2_return_called == 1);
  370. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  371. /*
  372. * Delete entry and try timeout again
  373. */
  374. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == -1);
  375. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0);
  376. assert((timeout_timer = timer_list_add(
  377. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  378. timeout_cb_called = 0;
  379. assert(pr_poll_loop_exec(poll_loop) == 0);
  380. assert(timeout_cb_called == 1);
  381. /*
  382. * Try reading
  383. */
  384. assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  385. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  386. fd_read_cb1, NULL, NULL,
  387. &fd_read_cb1_called, fd_read_cb1) == 0);
  388. fd_read_cb1_called = 0;
  389. timeout_cb_called = 0;
  390. assert((timeout_timer = timer_list_add(
  391. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  392. assert(pr_poll_loop_exec(poll_loop) == 0);
  393. assert(fd_read_cb1_called == 1);
  394. assert(timeout_cb_called == 0);
  395. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  396. /*
  397. * Try timeout with valid entry
  398. */
  399. assert((timeout_timer = timer_list_add(
  400. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  401. timeout_cb_called = 0;
  402. fd_read_cb1_called = 0;
  403. assert(pr_poll_loop_exec(poll_loop) == 0);
  404. assert(timeout_cb_called == 1);
  405. assert(fd_read_cb1_called == 0);
  406. /*
  407. * Try reading where cb returns err
  408. */
  409. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  410. assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  411. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  412. fd_read_cb2, NULL, NULL,
  413. &fd_read_cb2_called, fd_read_cb2) == 0);
  414. fd_read_cb1_called = 0;
  415. fd_read_cb2_called = 0;
  416. timeout_cb_called = 0;
  417. assert((timeout_timer = timer_list_add(
  418. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  419. assert(pr_poll_loop_exec(poll_loop) == -1);
  420. assert(fd_read_cb1_called == 0);
  421. assert(fd_read_cb2_called == 1);
  422. assert(timeout_cb_called == 0);
  423. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  424. /*
  425. * Try writing
  426. */
  427. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  428. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], POLLOUT, NULL,
  429. NULL, fd_write_cb1, NULL,
  430. &fd_write_cb1_called, fd_write_cb1) == 0);
  431. fd_write_cb1_called = 0;
  432. timeout_cb_called = 0;
  433. assert((timeout_timer = timer_list_add(
  434. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  435. assert(pr_poll_loop_exec(poll_loop) == 0);
  436. assert(fd_write_cb1_called == 1);
  437. assert(timeout_cb_called == 0);
  438. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  439. /*
  440. * Try err cb
  441. */
  442. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[1]) == 0);
  443. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[0], POLLIN, NULL,
  444. NULL, NULL, fd_err_cb1,
  445. &fd_err_cb1_called, fd_err_cb1) == 0);
  446. assert(close(pipe_fd1[0]) == 0);
  447. assert(close(pipe_fd1[1]) == 0);
  448. fd_err_cb1_called = 0;
  449. timeout_cb_called = 0;
  450. fd_write_cb1_called = 0;
  451. assert((timeout_timer = timer_list_add(
  452. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  453. assert(pr_poll_loop_exec(poll_loop) == 0);
  454. assert(fd_err_cb1_called == 1);
  455. assert(fd_write_cb1_called == 0);
  456. assert(timeout_cb_called == 0);
  457. assert(pr_poll_loop_del_fd(poll_loop, pipe_fd1[0]) == 0);
  458. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  459. }
  460. static void
  461. test_prfd_basics(struct pr_poll_loop *poll_loop)
  462. {
  463. PRFileDesc *read_pipe;
  464. PRFileDesc *write_pipe;
  465. struct timer_list_entry *timeout_timer;
  466. int pipe_fd1[2];
  467. init_global_vars();
  468. assert(PR_CreatePipe(&read_pipe, &write_pipe) == PR_SUCCESS);
  469. /*
  470. * Add POLLNVAL -> failure
  471. */
  472. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLNVAL, NULL, NULL, NULL, NULL,
  473. NULL, NULL) == -1);
  474. /*
  475. * Del non-existing fdL -> failure
  476. */
  477. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  478. /*
  479. * Add and delete fd twice
  480. */
  481. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL,
  482. NULL, NULL) == 0);
  483. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, 0, NULL, NULL, NULL, NULL,
  484. NULL, NULL) == -1);
  485. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  486. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  487. /*
  488. * Test user_data passing
  489. */
  490. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, prfd_set_events_cb1_return,
  491. NULL, NULL, NULL, (void *)&prfd_set_events_cb1_return_called, NULL) == 0);
  492. prfd_set_events_cb1_return_called = 0;
  493. assert((timeout_timer = timer_list_add(
  494. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  495. assert(pr_poll_loop_exec(poll_loop) == -1);
  496. assert(prfd_set_events_cb1_return_called == 1);
  497. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  498. /*
  499. * Remove entry and try different cb
  500. */
  501. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  502. assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, prfd_set_events_cb2_return,
  503. NULL, NULL, NULL, NULL, (void *)&prfd_set_events_cb2_return_called) == 0);
  504. prfd_set_events_cb1_return_called = 0;
  505. prfd_set_events_cb2_return_called = 0;
  506. assert((timeout_timer = timer_list_add(
  507. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  508. assert(pr_poll_loop_exec(poll_loop) == -1);
  509. assert(prfd_set_events_cb1_return_called == 0);
  510. assert(prfd_set_events_cb2_return_called == 1);
  511. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  512. /*
  513. * Delete entry and try timeout again
  514. */
  515. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == -1);
  516. assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0);
  517. assert((timeout_timer = timer_list_add(
  518. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  519. timeout_cb_called = 0;
  520. assert(pr_poll_loop_exec(poll_loop) == 0);
  521. assert(timeout_cb_called == 1);
  522. /*
  523. * Try reading
  524. */
  525. assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  526. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  527. prfd_read_cb1, NULL, NULL,
  528. &prfd_read_cb1_called, prfd_read_cb1) == 0);
  529. prfd_read_cb1_called = 0;
  530. timeout_cb_called = 0;
  531. assert((timeout_timer = timer_list_add(
  532. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  533. assert(pr_poll_loop_exec(poll_loop) == 0);
  534. assert(prfd_read_cb1_called == 1);
  535. assert(timeout_cb_called == 0);
  536. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  537. /*
  538. * Try timeout with valid entry
  539. */
  540. assert((timeout_timer = timer_list_add(
  541. pr_poll_loop_get_timer_list(poll_loop), TIMER_TEST_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  542. timeout_cb_called = 0;
  543. prfd_read_cb1_called = 0;
  544. assert(pr_poll_loop_exec(poll_loop) == 0);
  545. assert(timeout_cb_called == 1);
  546. assert(prfd_read_cb1_called == 0);
  547. /*
  548. * Try reading where cb returns err
  549. */
  550. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  551. assert(PR_Write(write_pipe, READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  552. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  553. prfd_read_cb2, NULL, NULL,
  554. &prfd_read_cb2_called, prfd_read_cb2) == 0);
  555. prfd_read_cb1_called = 0;
  556. prfd_read_cb2_called = 0;
  557. timeout_cb_called = 0;
  558. assert((timeout_timer = timer_list_add(
  559. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  560. assert(pr_poll_loop_exec(poll_loop) == -1);
  561. assert(prfd_read_cb1_called == 0);
  562. assert(prfd_read_cb2_called == 1);
  563. assert(timeout_cb_called == 0);
  564. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  565. /*
  566. * Try writing
  567. */
  568. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  569. assert(pr_poll_loop_add_prfd(poll_loop, write_pipe, POLLOUT, NULL,
  570. NULL, prfd_write_cb1, NULL,
  571. &prfd_write_cb1_called, prfd_write_cb1) == 0);
  572. prfd_write_cb1_called = 0;
  573. timeout_cb_called = 0;
  574. assert((timeout_timer = timer_list_add(
  575. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  576. assert(pr_poll_loop_exec(poll_loop) == 0);
  577. assert(prfd_write_cb1_called == 1);
  578. assert(timeout_cb_called == 0);
  579. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  580. assert(PR_Close(read_pipe) == 0);
  581. assert(PR_Close(write_pipe) == 0);
  582. /*
  583. * Try err cb
  584. */
  585. assert(pr_poll_loop_del_prfd(poll_loop, write_pipe) == 0);
  586. /*
  587. * Must use native pipe, because PR_Close deallocate PRFileDesc completelly
  588. */
  589. assert(pipe(pipe_fd1) == 0);
  590. assert((read_pipe = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL);
  591. assert(close(pipe_fd1[0]) == 0);
  592. assert(close(pipe_fd1[1]) == 0);
  593. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe, POLLIN, NULL,
  594. NULL, NULL, prfd_err_cb1,
  595. &prfd_err_cb1_called, prfd_err_cb1) == 0);
  596. prfd_err_cb1_called = 0;
  597. timeout_cb_called = 0;
  598. prfd_write_cb1_called = 0;
  599. assert((timeout_timer = timer_list_add(
  600. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  601. assert(pr_poll_loop_exec(poll_loop) == 0);
  602. assert(prfd_err_cb1_called == 1);
  603. assert(prfd_write_cb1_called == 0);
  604. assert(timeout_cb_called == 0);
  605. assert(pr_poll_loop_del_prfd(poll_loop, read_pipe) == 0);
  606. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  607. assert(PR_DestroySocketPollFd(read_pipe) == PR_SUCCESS);
  608. }
  609. static void
  610. test_complex(struct pr_poll_loop *poll_loop)
  611. {
  612. int pipe_fd1[2], pipe_fd2[2];
  613. PRFileDesc *read_pipe1;
  614. PRFileDesc *write_pipe2;
  615. struct timer_list_entry *timeout_timer;
  616. assert(pipe(pipe_fd1) == 0);
  617. assert(pipe(pipe_fd2) == 0);
  618. test_complex_read_pipe1_fd = pipe_fd1[0];
  619. assert((read_pipe1 = PR_CreateSocketPollFd(pipe_fd1[0])) != NULL);
  620. assert((write_pipe2 = PR_CreateSocketPollFd(pipe_fd2[1])) != NULL);
  621. assert(pr_poll_loop_add_prfd(poll_loop, read_pipe1, 0, test_complex_set_events_pipe1_read_cb,
  622. test_complex_read_pipe1_read_cb, test_complex_write_pipe1_read_cb, NULL,
  623. &test_complex_set_events_pipe1_read_called, test_complex_set_events_pipe1_read_cb) == 0);
  624. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd1[1], 0, test_complex_set_events_pipe1_write_cb,
  625. test_complex_read_pipe1_write_cb, test_complex_write_pipe1_write_cb, NULL,
  626. &test_complex_set_events_pipe1_write_called, test_complex_set_events_pipe1_write_cb) == 0);
  627. assert(pr_poll_loop_add_fd(poll_loop, pipe_fd2[0], POLLIN, test_complex_set_events_pipe2_read_cb,
  628. test_complex_read_pipe2_read_cb, test_complex_write_pipe2_read_cb, NULL,
  629. &test_complex_set_events_pipe2_read_called, test_complex_set_events_pipe2_read_cb) == 0);
  630. assert(pr_poll_loop_add_prfd(poll_loop, write_pipe2, POLLOUT, test_complex_set_events_pipe2_write_cb,
  631. test_complex_read_pipe2_write_cb, test_complex_write_pipe2_write_cb, NULL,
  632. &test_complex_set_events_pipe2_write_called, test_complex_set_events_pipe2_write_cb) == 0);
  633. /*
  634. * Call for first time -> all set_events should be called and pipe2_write should be called
  635. */
  636. assert((timeout_timer = timer_list_add(
  637. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  638. assert(pr_poll_loop_exec(poll_loop) == 0);
  639. assert(test_complex_set_events_pipe1_read_called == 1);
  640. assert(test_complex_read_pipe1_read_called == 0);
  641. assert(test_complex_set_events_pipe1_write_called == 1);
  642. assert(test_complex_write_pipe1_write_called == 0);
  643. assert(test_complex_set_events_pipe2_read_called == 1);
  644. assert(test_complex_read_pipe2_read_called == 0);
  645. assert(test_complex_set_events_pipe2_write_called == 1);
  646. assert(test_complex_write_pipe2_write_called == 1);
  647. assert(timeout_cb_called == 0);
  648. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  649. /*
  650. * Call for second time -> same as first time
  651. */
  652. assert((timeout_timer = timer_list_add(
  653. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  654. assert(pr_poll_loop_exec(poll_loop) == 0);
  655. assert(test_complex_set_events_pipe1_read_called == 2);
  656. assert(test_complex_read_pipe1_read_called == 0);
  657. assert(test_complex_set_events_pipe1_write_called == 2);
  658. assert(test_complex_write_pipe1_write_called == 0);
  659. assert(test_complex_set_events_pipe2_read_called == 2);
  660. assert(test_complex_read_pipe2_read_called == 0);
  661. assert(test_complex_set_events_pipe2_write_called == 2);
  662. assert(test_complex_write_pipe2_write_called == 2);
  663. assert(timeout_cb_called == 0);
  664. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  665. /*
  666. * Change state to prepare for writing
  667. */
  668. test_complex_state = 1;
  669. assert((timeout_timer = timer_list_add(
  670. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  671. assert(pr_poll_loop_exec(poll_loop) == 0);
  672. assert(test_complex_set_events_pipe1_read_called == 3);
  673. assert(test_complex_read_pipe1_read_called == 0);
  674. assert(test_complex_set_events_pipe1_write_called == 3);
  675. assert(test_complex_write_pipe1_write_called == 1);
  676. assert(test_complex_set_events_pipe2_read_called == 3);
  677. assert(test_complex_read_pipe2_read_called == 0);
  678. assert(test_complex_set_events_pipe2_write_called == 3);
  679. assert(test_complex_write_pipe2_write_called == 3);
  680. assert(timeout_cb_called == 0);
  681. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  682. /*
  683. * Write to first pipe
  684. */
  685. assert(write(pipe_fd1[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  686. assert((timeout_timer = timer_list_add(
  687. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  688. assert(pr_poll_loop_exec(poll_loop) == 0);
  689. assert(test_complex_set_events_pipe1_read_called == 4);
  690. assert(test_complex_read_pipe1_read_called == 0);
  691. assert(test_complex_set_events_pipe1_write_called == 4);
  692. assert(test_complex_write_pipe1_write_called == 2);
  693. assert(test_complex_set_events_pipe2_read_called == 4);
  694. assert(test_complex_read_pipe2_read_called == 0);
  695. assert(test_complex_set_events_pipe2_write_called == 4);
  696. assert(test_complex_write_pipe2_write_called == 4);
  697. assert(timeout_cb_called == 0);
  698. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  699. /*
  700. * Change state so write can propagate
  701. */
  702. test_complex_state = 2;
  703. assert((timeout_timer = timer_list_add(
  704. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  705. assert(pr_poll_loop_exec(poll_loop) == 0);
  706. assert(test_complex_set_events_pipe1_read_called == 5);
  707. assert(test_complex_read_pipe1_read_called == 1);
  708. assert(test_complex_set_events_pipe1_write_called == 5);
  709. assert(test_complex_write_pipe1_write_called == 2);
  710. assert(test_complex_set_events_pipe2_read_called == 5);
  711. assert(test_complex_read_pipe2_read_called == 0);
  712. assert(test_complex_set_events_pipe2_write_called == 5);
  713. assert(test_complex_write_pipe2_write_called == 5);
  714. assert(timeout_cb_called == 0);
  715. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  716. /*
  717. * Change state so pipe1 events are not called any longer
  718. */
  719. test_complex_state = 4;
  720. assert((timeout_timer = timer_list_add(
  721. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  722. assert(pr_poll_loop_exec(poll_loop) == 0);
  723. assert(test_complex_set_events_pipe1_read_called == 6);
  724. assert(test_complex_read_pipe1_read_called == 1);
  725. assert(test_complex_set_events_pipe1_write_called == 6);
  726. assert(test_complex_write_pipe1_write_called == 2);
  727. assert(test_complex_set_events_pipe2_read_called == 6);
  728. assert(test_complex_read_pipe2_read_called == 0);
  729. assert(test_complex_set_events_pipe2_write_called == 6);
  730. assert(test_complex_write_pipe2_write_called == 6);
  731. assert(timeout_cb_called == 0);
  732. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  733. /*
  734. * Write to second pipe
  735. */
  736. assert(write(pipe_fd2[1], READ_STR, strlen(READ_STR) + 1) == strlen(READ_STR) + 1);
  737. assert((timeout_timer = timer_list_add(
  738. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  739. assert(pr_poll_loop_exec(poll_loop) == 0);
  740. assert(test_complex_set_events_pipe1_read_called == 7);
  741. assert(test_complex_read_pipe1_read_called == 1);
  742. assert(test_complex_set_events_pipe1_write_called == 7);
  743. assert(test_complex_write_pipe1_write_called == 2);
  744. assert(test_complex_set_events_pipe2_read_called == 7);
  745. assert(test_complex_read_pipe2_read_called == 1);
  746. assert(test_complex_set_events_pipe2_write_called == 7);
  747. assert(test_complex_write_pipe2_write_called == 7);
  748. assert(timeout_cb_called == 0);
  749. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  750. /*
  751. * And call again
  752. */
  753. assert((timeout_timer = timer_list_add(
  754. pr_poll_loop_get_timer_list(poll_loop), TIMER_TIMEOUT, timeout_cb, NULL, NULL)) != NULL);
  755. assert(pr_poll_loop_exec(poll_loop) == 0);
  756. assert(test_complex_set_events_pipe1_read_called == 8);
  757. assert(test_complex_read_pipe1_read_called == 1);
  758. assert(test_complex_set_events_pipe1_write_called == 8);
  759. assert(test_complex_write_pipe1_write_called == 2);
  760. assert(test_complex_set_events_pipe2_read_called == 8);
  761. assert(test_complex_read_pipe2_read_called == 1);
  762. assert(test_complex_set_events_pipe2_write_called == 8);
  763. assert(test_complex_write_pipe2_write_called == 8);
  764. assert(timeout_cb_called == 0);
  765. timer_list_delete(pr_poll_loop_get_timer_list(poll_loop), timeout_timer);
  766. assert(PR_DestroySocketPollFd(read_pipe1) == PR_SUCCESS);
  767. assert(PR_DestroySocketPollFd(write_pipe2) == PR_SUCCESS);
  768. assert(close(pipe_fd1[0]) == 0);
  769. assert(close(pipe_fd1[1]) == 0);
  770. assert(close(pipe_fd2[0]) == 0);
  771. assert(close(pipe_fd2[1]) == 0);
  772. }
  773. int
  774. main(void)
  775. {
  776. struct pr_poll_loop poll_loop;
  777. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  778. pr_poll_loop_init(&poll_loop);
  779. test_fd_basics(&poll_loop);
  780. test_prfd_basics(&poll_loop);
  781. test_complex(&poll_loop);
  782. pr_poll_loop_destroy(&poll_loop);
  783. assert(PR_Cleanup() == PR_SUCCESS);
  784. return (0);
  785. }