@@ -328,6 +328,115 @@ func TestEpollConnectSameFD(t *testing.T) {
328328 Assert (t , n == 0 )
329329}
330330
331+ func TestEpollWaitEpollFD (t * testing.T ) {
332+ epollfd1 , err := EpollCreate (0 ) // monitor epollfd2
333+ MustNil (t , err )
334+ epollfd2 , err := EpollCreate (0 ) // monitor io fds
335+ MustNil (t , err )
336+ MustNil (t , err )
337+ defer syscall .Close (epollfd1 )
338+ defer syscall .Close (epollfd2 )
339+
340+ rfd , wfd := GetSysFdPairs ()
341+ defer syscall .Close (wfd )
342+ send := []byte ("hello" )
343+ recv := make ([]byte , 5 )
344+ events := make ([]epollevent , 128 )
345+ n := 0
346+
347+ // register epollfd2 into epollfd1
348+ event := & epollevent {
349+ events : syscall .EPOLLIN | syscall .EPOLLRDHUP | syscall .EPOLLERR ,
350+ data : [8 ]byte {},
351+ }
352+ err = EpollCtl (epollfd1 , syscall .EPOLL_CTL_ADD , epollfd2 , event )
353+ MustNil (t , err )
354+ _ , err = epollWaitUntil (epollfd1 , events , 0 )
355+ MustNil (t , err )
356+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
357+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
358+
359+ // register rfd into epollfd2
360+ err = EpollCtl (epollfd2 , syscall .EPOLL_CTL_ADD , rfd , event )
361+ MustNil (t , err )
362+ n , err = epollWaitUntil (epollfd2 , events , 0 )
363+ Equal (t , n , 1 )
364+ MustNil (t , err )
365+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
366+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
367+
368+ // check epollfd2 readable
369+ n , err = syscall .Write (wfd , send )
370+ Equal (t , n , len (send ))
371+ MustNil (t , err )
372+ n , err = epollWaitUntil (epollfd1 , events , 0 )
373+ Equal (t , n , 1 )
374+ MustNil (t , err )
375+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
376+
377+ // check rfd readable
378+ n , err = epollWaitUntil (epollfd2 , events , 0 )
379+ Equal (t , n , 1 )
380+ MustNil (t , err )
381+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
382+
383+ // read rfd
384+ n , err = syscall .Read (rfd , recv )
385+ Equal (t , n , len (send ))
386+ MustTrue (t , err == nil && string (recv ) == string (send ))
387+
388+ // check epollfd1 non-readable
389+ n , err = epollWaitUntil (epollfd1 , events , 0 )
390+ Equal (t , n , 1 )
391+ MustNil (t , err )
392+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
393+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
394+
395+ // check epollfd2 non-readable
396+ n , err = epollWaitUntil (epollfd2 , events , 0 )
397+ Equal (t , n , 1 )
398+ MustNil (t , err )
399+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
400+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
401+
402+ // close wfd
403+ err = syscall .Close (wfd )
404+ MustNil (t , err )
405+
406+ // check epollfd1 notified when peer closed
407+ n , err = epollWaitUntil (epollfd1 , events , 0 )
408+ Equal (t , n , 1 )
409+ MustNil (t , err )
410+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
411+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
412+
413+ // check epollfd2 notified when peer closed
414+ n , err = epollWaitUntil (epollfd2 , events , 0 )
415+ Equal (t , n , 1 )
416+ MustNil (t , err )
417+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
418+ Assert (t , events [0 ].events & syscall .EPOLLRDHUP != 0 )
419+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
420+
421+ // close rfd
422+ err = syscall .Close (rfd )
423+ MustNil (t , err )
424+
425+ // check epollfd1 non-readable
426+ n , err = epollWaitUntil (epollfd1 , events , 0 )
427+ Equal (t , n , 1 )
428+ MustNil (t , err )
429+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
430+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
431+
432+ // check epollfd2 non-readable
433+ n , err = epollWaitUntil (epollfd2 , events , 0 )
434+ Equal (t , n , 1 )
435+ MustNil (t , err )
436+ Assert (t , events [0 ].events & syscall .EPOLLIN == 0 )
437+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
438+ }
439+
331440func TestRuntimeNetpoller (t * testing.T ) {
332441 pfd , err := openPollFile ()
333442 MustNil (t , err )
0 commit comments