comparison packages/net/tcpip/current/src/lib/select.c @ 128:0c2b7be0d798 ecos-sw-2000-10-12

Merge from eCos master repository on 2000-10-12-08:46:24-BST
author jlarmour
date Thu, 12 Oct 2000 20:31:43 +0000
parents 02ea4320376c
children 38892b97b685
comparison
equal deleted inserted replaced
127:67f0ef5f8ee9 128:0c2b7be0d798
101 ticks = 0; 101 ticks = 0;
102 } 102 }
103 // Scan sets for possible I/O until something found, timeout or error. 103 // Scan sets for possible I/O until something found, timeout or error.
104 while (true) { 104 while (true) {
105 num = 0; // Total file descriptors "ready" 105 num = 0; // Total file descriptors "ready"
106
107 cyg_scheduler_lock(); // Scan the list atomically wrt electing to sleep
108
106 for (mode = 0; mode < 3; mode++) { 109 for (mode = 0; mode < 3; mode++) {
107 if (selection[mode]) { 110 if (selection[mode]) {
108 for (fd = 0; fd < nfd; fd++) { 111 for (fd = 0; fd < nfd; fd++) {
109 if (FD_ISSET(fd, selection[mode])) { 112 if (FD_ISSET(fd, selection[mode])) {
110 if (getfp(fd, &fp)) { 113 if (getfp(fd, &fp)) {
114 cyg_scheduler_unlock(); // return.
111 errno = EBADF; 115 errno = EBADF;
112 return -1; 116 return -1;
113 } 117 }
114 if ((*fp->f_ops->fo_select)(fp, mode_type[mode])) { 118 if ((*fp->f_ops->fo_select)(fp, mode_type[mode])) {
115 FD_SET(fd, result[mode]); 119 FD_SET(fd, result[mode]);
118 } 122 }
119 } 123 }
120 } 124 }
121 } 125 }
122 if (num) { 126 if (num) {
127
128 cyg_scheduler_unlock(); // Happy, about to return.
129
123 // Found something, update user's sets 130 // Found something, update user's sets
124 if (in) { 131 if (in) {
125 memcpy(in, &in_res, sizeof(in_res)); 132 memcpy(in, &in_res, sizeof(in_res));
126 } 133 }
127 if (out) { 134 if (out) {
134 } 141 }
135 // Nothing found, see if we want to wait 142 // Nothing found, see if we want to wait
136 if (tv) { 143 if (tv) {
137 if (ticks == 0) { 144 if (ticks == 0) {
138 // Special case of "poll" 145 // Special case of "poll"
146 cyg_scheduler_unlock(); // About to return.
139 return 0; 147 return 0;
140 } 148 }
141 flag = cyg_flag_timed_wait(&select_flag, wait_flag, 149 flag = cyg_flag_timed_wait(&select_flag, wait_flag,
142 CYG_FLAG_WAITMODE_OR, 150 CYG_FLAG_WAITMODE_OR,
143 then); 151 then);
144 } else { 152 } else {
145 // Wait forever (until something happens) 153 // Wait forever (until something happens)
146 flag = cyg_flag_wait(&select_flag, wait_flag, 154 flag = cyg_flag_wait(&select_flag, wait_flag,
147 CYG_FLAG_WAITMODE_OR); 155 CYG_FLAG_WAITMODE_OR);
148 } 156 }
157
158 cyg_scheduler_unlock(); // waited atomically
159
149 if (flag & SELECT_ABORT) { 160 if (flag & SELECT_ABORT) {
150 errno = EINTR; 161 errno = EINTR;
151 return -1; 162 return -1;
152 } 163 }
153 if (!flag) { 164 if (!flag) {
173 // may have occurred. 184 // may have occurred.
174 // 185 //
175 void 186 void
176 selwakeup(struct selinfo *info) 187 selwakeup(struct selinfo *info)
177 { 188 {
178 cyg_scheduler_lock(); // Need this test to be indivisible 189 // Need these ops to be atomic to make sure the clear occurs -
179 if (cyg_flag_waiting(&select_flag)) { 190 // otherwise a higher prio thread could hog the CPU when its fds are
180 // Signal any threads doing a 'select()' that I/O may be possible 191 // not ready, but the flag is (already) set, or set for someone else.
181 cyg_flag_setbits(&select_flag, SELECT_WAKE); 192 cyg_scheduler_lock();
182 cyg_flag_maskbits(&select_flag, 0 ); // clear all 193 cyg_flag_setbits(&select_flag, SELECT_WAKE);
183 } 194 cyg_flag_maskbits(&select_flag, 0 ); // clear all
184 cyg_scheduler_unlock(); 195 cyg_scheduler_unlock();
185 } 196 }
186 197
187 // 198 //
188 // The public function used by 'normal' programs. This interface does not allow 199 // The public function used by 'normal' programs. This interface does not allow
211 // current selects. 222 // current selects.
212 // 223 //
213 void 224 void
214 cyg_select_abort(void) 225 cyg_select_abort(void)
215 { 226 {
216 cyg_scheduler_lock(); // Need this test to be indivisible 227 // See comments in selwakeup()...
217 if (cyg_flag_waiting(&select_flag)) { 228 cyg_scheduler_lock();
218 // Signal any threads doing a 'select()' that I/O may be possible 229 cyg_flag_setbits(&select_flag, SELECT_ABORT);
219 cyg_flag_setbits(&select_flag, SELECT_ABORT); 230 cyg_flag_maskbits(&select_flag, 0 );
220 cyg_flag_maskbits(&select_flag, 0 ); // clear all
221 }
222 cyg_scheduler_unlock(); 231 cyg_scheduler_unlock();
223 } 232 }
224 233
225 234