Browse code

- io_watch_chg fix for EPOLL_ET: handle possible pre-existing IO events

Andrei Pelinescu-Onciul authored on 13/12/2007 18:05:39
Showing 1 changed files
... ...
@@ -476,6 +476,7 @@ again_devpoll:
476 476
 		pf.fd=fd;
477 477
 		pf.events=events;
478 478
 check_io_again:
479
+		n=0;
479 480
 		while(e->type && ((n=poll(&pf, 1, 0))>0) && 
480 481
 				(handle_io(e, pf.revents, idx)>0) &&
481 482
 				(pf.revents & (e->events|POLLERR|POLLHUP)));
... ...
@@ -704,12 +705,16 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
704 704
 	struct fd_map* e;
705 705
 	int add_events;
706 706
 	int del_events;
707
+#ifdef HAVE_DEVPOLL
708
+	struct pollfd pfd;
709
+#endif
707 710
 #ifdef HAVE_EPOLL
708 711
 	int n;
709 712
 	struct epoll_event ep_event;
710
-#endif
711
-#ifdef HAVE_DEVPOLL
712
-	struct pollfd pfd;
713
+	struct pollfd pf;
714
+	int check_io;
715
+	
716
+	check_io=0;
713 717
 #endif
714 718
 	
715 719
 	if (unlikely((fd<0) || (fd>=h->max_fd_no))){
... ...
@@ -760,6 +765,8 @@ inline static int io_watch_chg(io_wait_h* h, int fd, short events, int idx )
760 760
 #ifdef HAVE_SIGIO_RT
761 761
 		case POLL_SIGIO_RT:
762 762
 			fd_array_chg(events);
763
+			/* no need for check_io, since SIGIO_RT listens by default for all
764
+			 * the events */
763 765
 			break;
764 766
 #endif
765 767
 #ifdef HAVE_EPOLL
... ...
@@ -789,6 +796,7 @@ again_epoll_et:
789 789
 							" failed: %s [%d]\n", strerror(errno), errno);
790 790
 					goto error;
791 791
 				}
792
+			check_io=1;
792 793
 			break;
793 794
 #endif
794 795
 #ifdef HAVE_KQUEUE
... ...
@@ -844,6 +852,24 @@ again_devpoll2:
844 844
 					h->poll_method);
845 845
 			goto error;
846 846
 	}
847
+#if defined (HAVE_EPOLL)
848
+	if (check_io){
849
+		/* handle possible pre-existing events, only for EPOLL_ET
850
+		 * (SIGIO_RT already listen for all the events) */
851
+		pf.fd=fd;
852
+		pf.events=add_events;
853
+check_io_again:
854
+		n=0;
855
+		while(e->type && ((n=poll(&pf, 1, 0))>0) && 
856
+				(handle_io(e, pf.revents, idx)>0) &&
857
+				(pf.revents & (e->events|POLLERR|POLLHUP)));
858
+		if (unlikely(e->type && (n==-1))){
859
+			if (errno==EINTR) goto check_io_again;
860
+			LOG(L_ERR, "ERROR: io_watch_chg: check_io poll: %s [%d]\n",
861
+						strerror(errno), errno);
862
+		}
863
+	}
864
+#endif /* HAVE_EPOLL */
847 865
 	return 0;
848 866
 error:
849 867
 	return -1;