1 module during.tests.poll;
2 
3 import during;
4 import during.tests.base;
5 
6 import core.sys.linux.errno;
7 import core.sys.linux.sys.eventfd;
8 import core.sys.posix.unistd;
9 
10 import std.algorithm : among;
11 
12 @("poll add/remove")
13 unittest
14 {
15     if (!checkKernelVersion(5, 1)) return;
16 
17     Uring io;
18     long res = io.setup();
19     assert(res >= 0, "Error initializing IO");
20 
21     auto evt = eventfd(0, EFD_NONBLOCK);
22     assert(evt != -1, "eventfd()");
23 
24     res = io
25         .putWith!((ref SubmissionEntry e, ref const(int) evt)
26             {
27                 e.prepPollAdd(evt, PollEvents.IN);
28                 e.setUserData(evt); // to identify poll operation later
29             })(evt)
30         .submit(0);
31     assert(res == 1);
32 
33     ulong val = 1;
34     res = write(evt, cast(ubyte*)&val, 8);
35     assert(res == 8);
36     io.wait(1);
37 
38     assert(!io.empty);
39     assert(io.front.res == 1); // one event available from poll()
40     io.popFront();
41 
42     res = read(evt, cast(ubyte*)&val, 8);
43     assert(res == 8);
44 
45     // try to remove it - should fail with ENOENT as we've consumed it already
46     res = io.putWith!((ref SubmissionEntry e, ref const(int) evt) => e.prepPollRemove(evt))(evt).submit(1);
47     assert(res == 1);
48     assert(io.front.res == -ENOENT);
49     io.popFront();
50 
51     // add it again
52     res = io
53         .putWith!((ref SubmissionEntry e, ref const(int) evt)
54             {
55                 e.prepPollAdd(evt, PollEvents.IN);
56                 e.setUserData(evt); // to identify poll operation later
57             })(evt)
58         .submit(0);
59     assert(res == 1);
60 
61     // and remove/cancel it - now should pass ok
62     res = io.putWith!((ref SubmissionEntry e, ref const(int) evt) => e.prepPollRemove(evt))(evt).submit(1);
63     assert(res == 1);
64 
65     io.wait(2);
66     foreach (_; 0..2)
67     {
68         if (io.front.user_data == cast(ulong)cast(void*)&evt)
69             assert(io.front.res == -ECANCELED);
70         else assert(!io.front.res);
71         io.popFront();
72     }
73 }