Browse code

- fix: io_wait* :- safe delete for select, poll & sigiort (sigiort was affected only if it did fallback to poll) - select fd array size

Andrei Pelinescu-Onciul authored on 21/01/2008 13:00:35
Showing 1 changed files
... ...
@@ -130,20 +130,33 @@ struct fd_map{
130 130
 
131 131
 /* handler structure */
132 132
 struct io_wait_handler{
133
+	enum poll_types poll_method;
134
+	int flags;
135
+	struct fd_map* fd_hash;
136
+	int fd_no; /*  current index used in fd_array and the passed size for 
137
+				   ep_array & kq_array*/
138
+	int max_fd_no; /* maximum fd no, is also the size of fd_array,
139
+						       fd_hash  and ep_array*/
140
+	/* common stuff for POLL, SIGIO_RT and SELECT
141
+	 * since poll support is always compiled => this will always be compiled */
142
+	struct pollfd* fd_array; /* used also by devpoll as devpoll array */
143
+	int crt_fd_array_idx; /*  crt idx for which handle_io is called
144
+							 (updated also by del -> internal optimization) */
145
+	/* end of common stuff */
133 146
 #ifdef HAVE_EPOLL
134
-	struct epoll_event* ep_array;
135 147
 	int epfd; /* epoll ctrl fd */
148
+	struct epoll_event* ep_array;
136 149
 #endif
137 150
 #ifdef HAVE_SIGIO_RT
138 151
 	sigset_t sset; /* signal mask for sigio & sigrtmin */
139 152
 	int signo;     /* real time signal used */
140 153
 #endif
141 154
 #ifdef HAVE_KQUEUE
155
+	int kq_fd;
142 156
 	struct kevent* kq_array;   /* used for the eventlist*/
143 157
 	struct kevent* kq_changes; /* used for the changelist */
144 158
 	size_t kq_nchanges;
145 159
 	size_t kq_changes_size; /* size of the changes array */
146
-	int kq_fd;
147 160
 #endif
148 161
 #ifdef HAVE_DEVPOLL
149 162
 	int dpoll_fd;
... ...
@@ -153,15 +166,6 @@ struct io_wait_handler{
153 153
 	fd_set master_wset; /* write set */
154 154
 	int max_fd_select; /* maximum select used fd */
155 155
 #endif
156
-	/* common stuff for POLL, SIGIO_RT and SELECT
157
-	 * since poll support is always compiled => this will always be compiled */
158
-	struct fd_map* fd_hash;
159
-	struct pollfd* fd_array;
160
-	int fd_no; /*  current index used in fd_array */
161
-	int max_fd_no; /* maximum fd no, is also the size of fd_array,
162
-						       fd_hash  and ep_array*/
163
-	enum poll_types poll_method;
164
-	int flags;
165 156
 };
166 157
 
167 158
 typedef struct io_wait_handler io_wait_h;
... ...
@@ -527,6 +531,8 @@ inline static int io_watch_del(io_wait_h* h, int fd, int idx, int flags)
527 527
 			if (likely(idx<h->fd_no)){ \
528 528
 				memmove(&h->fd_array[idx], &h->fd_array[idx+1], \
529 529
 					(h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \
530
+				if ((idx<=h->crt_fd_array_idx) && (h->crt_fd_array_idx>=0)) \
531
+					h->crt_fd_array_idx--; \
530 532
 			} \
531 533
 	}while(0)
532 534
 	
... ...
@@ -858,6 +864,8 @@ error:
858 858
 #undef fix_fd_array
859 859
 }
860 860
 
861
+
862
+
861 863
 /* io_wait_loop_x style function 
862 864
  * wait for io using poll()
863 865
  * params: h      - io_wait handle
... ...
@@ -870,6 +878,7 @@ inline static int io_wait_loop_poll(io_wait_h* h, int t, int repeat)
870 870
 	int n, r;
871 871
 	int ret;
872 872
 	struct fd_map* fm;
873
+	
873 874
 again:
874 875
 		ret=n=poll(h->fd_array, h->fd_no, t*1000);
875 876
 		if (n==-1){
... ...
@@ -894,6 +903,7 @@ again:
894 894
 					h->fd_array[r].events=0; /* clear the events */
895 895
 					continue;
896 896
 				}
897
+				h->crt_fd_array_idx=r;
897 898
 				/* repeat handle_io if repeat, fd still watched (not deleted
898 899
 				 *  inside handle_io), handle_io returns that there's still
899 900
 				 *  IO and the fd is still watched for the triggering event */
... ...
@@ -901,6 +911,8 @@ again:
901 901
 						(handle_io(fm, h->fd_array[r].revents, r) > 0) &&
902 902
 						repeat && ((fm->events|POLLERR|POLLHUP) &
903 903
 													h->fd_array[r].revents));
904
+				r=h->crt_fd_array_idx; /* can change due to io_watch_del(fd) 
905
+										  array shifting */
904 906
 			}
905 907
 		}
906 908
 error:
... ...
@@ -935,16 +947,19 @@ again:
935 935
 			/* continue */
936 936
 		}
937 937
 		/* use poll fd array */
938
-		for(r=0; (r<h->max_fd_no) && n; r++){
938
+		for(r=0; (r<h->fd_no) && n; r++){
939 939
 			revents=0;
940 940
 			if (likely(FD_ISSET(h->fd_array[r].fd, &sel_rset)))
941 941
 				revents|=POLLIN;
942 942
 			if (unlikely(FD_ISSET(h->fd_array[r].fd, &sel_wset)))
943 943
 				revents|=POLLOUT;
944
-			if (likely(revents)){
944
+			if (unlikely(revents)){
945
+				h->crt_fd_array_idx=r;
945 946
 				fm=get_fd_map(h, h->fd_array[r].fd);
946 947
 				while(fm->type && (fm->events & revents) && 
947 948
 						(handle_io(fm, revents, r)>0) && repeat);
949
+				r=h->crt_fd_array_idx; /* can change due to io_watch_del(fd) 
950
+										  array shifting */
948 951
 				n--;
949 952
 			}
950 953
 		};
... ...
@@ -1056,7 +1071,7 @@ again:
1056 1056
 					while(fm->type && (fm->events & revents) && 
1057 1057
 							(handle_io(fm, revents, -1)>0) && repeat);
1058 1058
 				}
1059
-			//}
1059
+			/*} */
1060 1060
 		}
1061 1061
 error:
1062 1062
 	return n;
... ...
@@ -1088,7 +1103,6 @@ inline static int io_wait_loop_sigio_rt(io_wait_h* h, int t)
1088 1088
 				" is not properly set!\n");
1089 1089
 		goto error;
1090 1090
 	}
1091
-
1092 1091
 again:
1093 1092
 	n=sigtimedwait(&h->sset, &siginfo, &ts);
1094 1093
 	if (unlikely(n==-1)){