@@ -328,6 +328,104 @@ 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+ n , err = epollWaitUntil (epollfd1 , events , 0 )
355+ Equal (t , n , 0 )
356+ MustNil (t , err )
357+
358+ // register rfd into epollfd2
359+ err = EpollCtl (epollfd2 , syscall .EPOLL_CTL_ADD , rfd , event )
360+ MustNil (t , err )
361+ n , err = epollWaitUntil (epollfd2 , events , 0 )
362+ Equal (t , n , 0 )
363+ MustNil (t , err )
364+
365+ // check epollfd2 readable
366+ n , err = syscall .Write (wfd , send )
367+ Equal (t , n , len (send ))
368+ MustNil (t , err )
369+ n , err = epollWaitUntil (epollfd1 , events , 0 )
370+ Equal (t , n , 1 )
371+ MustNil (t , err )
372+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
373+
374+ // check rfd readable
375+ n , err = epollWaitUntil (epollfd2 , events , 0 )
376+ Equal (t , n , 1 )
377+ MustNil (t , err )
378+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
379+
380+ // read rfd
381+ n , err = syscall .Read (rfd , recv )
382+ Equal (t , n , len (send ))
383+ MustTrue (t , err == nil && string (recv ) == string (send ))
384+
385+ // check epollfd1 non-readable
386+ n , err = epollWaitUntil (epollfd1 , events , 0 )
387+ Equal (t , n , 0 )
388+ MustNil (t , err )
389+
390+ // check epollfd2 non-readable
391+ n , err = epollWaitUntil (epollfd2 , events , 0 )
392+ Equal (t , n , 0 )
393+ MustNil (t , err )
394+
395+ // close wfd
396+ err = syscall .Close (wfd )
397+ MustNil (t , err )
398+
399+ // check epollfd1 notified when peer closed
400+ n , err = epollWaitUntil (epollfd1 , events , 0 )
401+ Equal (t , n , 1 )
402+ MustNil (t , err )
403+ Assert (t , events [0 ].events & syscall .EPOLLIN != 0 )
404+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
405+
406+ // check epollfd2 notified when peer closed
407+ n , err = epollWaitUntil (epollfd2 , 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 .EPOLLRDHUP != 0 )
412+ Assert (t , events [0 ].events & syscall .EPOLLERR == 0 )
413+
414+ // close rfd
415+ err = syscall .Close (rfd )
416+ MustNil (t , err )
417+
418+ // check epollfd1 non-readable
419+ n , err = epollWaitUntil (epollfd1 , events , 0 )
420+ Equal (t , n , 0 )
421+ MustNil (t , err )
422+
423+ // check epollfd2 non-readable
424+ n , err = epollWaitUntil (epollfd2 , events , 0 )
425+ Equal (t , n , 0 )
426+ MustNil (t , err )
427+ }
428+
331429func TestRuntimeNetpoller (t * testing.T ) {
332430 pfd , err := openPollFile ()
333431 MustNil (t , err )
0 commit comments