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 }