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 166
 	fd_set master_wset; /* write set */
154 167
 	int max_fd_select; /* maximum select used fd */
155 168
 #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 169
 };
166 170
 
167 171
 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 531
 			if (likely(idx<h->fd_no)){ \
528 532
 				memmove(&h->fd_array[idx], &h->fd_array[idx+1], \
529 533
 					(h->fd_no-(idx+1))*sizeof(*(h->fd_array))); \
534
+				if ((idx<=h->crt_fd_array_idx) && (h->crt_fd_array_idx>=0)) \
535
+					h->crt_fd_array_idx--; \
530 536
 			} \
531 537
 	}while(0)
532 538
 	
... ...
@@ -858,6 +864,8 @@ error:
858 864
 #undef fix_fd_array
859 865
 }
860 866
 
867
+
868
+
861 869
 /* io_wait_loop_x style function 
862 870
  * wait for io using poll()
863 871
  * 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 878
 	int n, r;
871 879
 	int ret;
872 880
 	struct fd_map* fm;
881
+	
873 882
 again:
874 883
 		ret=n=poll(h->fd_array, h->fd_no, t*1000);
875 884
 		if (n==-1){
... ...
@@ -894,6 +903,7 @@ again:
894 903
 					h->fd_array[r].events=0; /* clear the events */
895 904
 					continue;
896 905
 				}
906
+				h->crt_fd_array_idx=r;
897 907
 				/* repeat handle_io if repeat, fd still watched (not deleted
898 908
 				 *  inside handle_io), handle_io returns that there's still
899 909
 				 *  IO and the fd is still watched for the triggering event */
... ...
@@ -901,6 +911,8 @@ again:
901 911
 						(handle_io(fm, h->fd_array[r].revents, r) > 0) &&
902 912
 						repeat && ((fm->events|POLLERR|POLLHUP) &
903 913
 													h->fd_array[r].revents));
914
+				r=h->crt_fd_array_idx; /* can change due to io_watch_del(fd) 
915
+										  array shifting */
904 916
 			}
905 917
 		}
906 918
 error:
... ...
@@ -935,16 +947,19 @@ again:
935 947
 			/* continue */
936 948
 		}
937 949
 		/* use poll fd array */
938
-		for(r=0; (r<h->max_fd_no) && n; r++){
950
+		for(r=0; (r<h->fd_no) && n; r++){
939 951
 			revents=0;
940 952
 			if (likely(FD_ISSET(h->fd_array[r].fd, &sel_rset)))
941 953
 				revents|=POLLIN;
942 954
 			if (unlikely(FD_ISSET(h->fd_array[r].fd, &sel_wset)))
943 955
 				revents|=POLLOUT;
944
-			if (likely(revents)){
956
+			if (unlikely(revents)){
957
+				h->crt_fd_array_idx=r;
945 958
 				fm=get_fd_map(h, h->fd_array[r].fd);
946 959
 				while(fm->type && (fm->events & revents) && 
947 960
 						(handle_io(fm, revents, r)>0) && repeat);
961
+				r=h->crt_fd_array_idx; /* can change due to io_watch_del(fd) 
962
+										  array shifting */
948 963
 				n--;
949 964
 			}
950 965
 		};
... ...
@@ -1056,7 +1071,7 @@ again:
1056 1071
 					while(fm->type && (fm->events & revents) && 
1057 1072
 							(handle_io(fm, revents, -1)>0) && repeat);
1058 1073
 				}
1059
-			//}
1074
+			/*} */
1060 1075
 		}
1061 1076
 error:
1062 1077
 	return n;
... ...
@@ -1088,7 +1103,6 @@ inline static int io_wait_loop_sigio_rt(io_wait_h* h, int t)
1088 1103
 				" is not properly set!\n");
1089 1104
 		goto error;
1090 1105
 	}
1091
-
1092 1106
 again:
1093 1107
 	n=sigtimedwait(&h->sset, &siginfo, &ts);
1094 1108
 	if (unlikely(n==-1)){