This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: waking a thread that's in select()?
- To: grante at visi dot com (Grant Edwards)
- Subject: Re: [ECOS] waking a thread that's in select()?
- From: andrew dot lunn at ascom dot ch (Andrew Lunn)
- Date: Fri, 29 Sep 2000 13:19:40 +0200 (MET DST)
- Cc: andrew dot lunn at ascom dot ch, ecos-discuss at sources dot redhat dot com
Hi
There is a race condition in select which could be contributing to
your problem. Hugo has fixes this. Here is a patch which i am
using. An official patch will go into the anoncvs soon.
Andrew
Index: select.c
===================================================================
RCS file: /cvs/ecos/ecos-opt/net/net/tcpip/current/src/lib/select.c,v
retrieving revision 1.2
diff -u -5 -p -c -r1.2 select.c
*** select.c 2000/07/21 21:34:38 1.2
--- select.c 2000/09/29 11:18:32
*************** _cyg_select(int nfd, fd_set *in, fd_set
*** 100,116 ****
then = 0; // Compiler warnings :-(
ticks = 0;
}
// Scan sets for possible I/O until something found, timeout or error.
while (true) {
! num = 0; // Total file descriptors "ready"
for (mode = 0; mode < 3; mode++) {
if (selection[mode]) {
for (fd = 0; fd < nfd; fd++) {
if (FD_ISSET(fd, selection[mode])) {
if (getfp(fd, &fp)) {
errno = EBADF;
return -1;
}
if ((*fp->f_ops->fo_select)(fp, mode_type[mode])) {
FD_SET(fd, result[mode]);
num++;
--- 100,118 ----
then = 0; // Compiler warnings :-(
ticks = 0;
}
// Scan sets for possible I/O until something found, timeout or error.
while (true) {
! num = 0; // Total file descriptors "ready"
! cyg_scheduler_lock();
for (mode = 0; mode < 3; mode++) {
if (selection[mode]) {
for (fd = 0; fd < nfd; fd++) {
if (FD_ISSET(fd, selection[mode])) {
if (getfp(fd, &fp)) {
errno = EBADF;
+ cyg_scheduler_unlock();
return -1;
}
if ((*fp->f_ops->fo_select)(fp, mode_type[mode])) {
FD_SET(fd, result[mode]);
num++;
*************** _cyg_select(int nfd, fd_set *in, fd_set
*** 118,127 ****
--- 120,130 ----
}
}
}
}
if (num) {
+ cyg_scheduler_unlock();
// Found something, update user's sets
if (in) {
memcpy(in, &in_res, sizeof(in_res));
}
if (out) {
*************** _cyg_select(int nfd, fd_set *in, fd_set
*** 132,153 ****
}
return num;
}
// Nothing found, see if we want to wait
if (tv) {
! if (ticks == 0) {
// Special case of "poll"
return 0;
}
flag = cyg_flag_timed_wait(&select_flag, wait_flag,
CYG_FLAG_WAITMODE_OR,
then);
} else {
// Wait forever (until something happens)
flag = cyg_flag_wait(&select_flag, wait_flag,
CYG_FLAG_WAITMODE_OR);
}
if (flag & SELECT_ABORT) {
errno = EINTR;
return -1;
}
if (!flag) {
--- 135,158 ----
}
return num;
}
// Nothing found, see if we want to wait
if (tv) {
! if (ticks == 0) {
// Special case of "poll"
+ cyg_scheduler_unlock();
return 0;
}
flag = cyg_flag_timed_wait(&select_flag, wait_flag,
CYG_FLAG_WAITMODE_OR,
then);
} else {
// Wait forever (until something happens)
flag = cyg_flag_wait(&select_flag, wait_flag,
CYG_FLAG_WAITMODE_OR);
}
+ cyg_scheduler_unlock();
if (flag & SELECT_ABORT) {
errno = EINTR;
return -1;
}
if (!flag) {