Mercurial > ecos-v2_0-branch
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 |
