summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-28 19:25:12 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-10-28 19:25:12 +0000
commitb4e3b2bd68e78769ad75361e880976b40c1d6a7b (patch)
tree93cb7e067d3fcdd62b683e27d6fae978cf4dda36
parent692b9f7fddd50daa9fc4052193a2b315717a3e54 (diff)
downloadrtems-b4e3b2bd68e78769ad75361e880976b40c1d6a7b.tar.bz2
Patch from Ian Lance Taylor <ian@airs.com>.
I just happened across the sync_io support in c/src/exec/score/cpu/unix/cpu.c (is this documented anywhere?). That looked more useful than the signal driven I/O I was using before, so I tried it. I ran across a few bugs in the way it uses select. Select changes its fd_set arguments, so you can't use global variables for them. You have to copy them into local variables first. If select returns -1 with errno set to EINTR, then it has not changed any of the fd_sets. You can't start looking at them. When clearing a descriptor, the code has the usual select off by one error when setting sync_io_nfds. I don't see how this code could ever have worked correctly. I have appended a patch for the problems I found.
-rw-r--r--c/src/exec/score/cpu/unix/cpu.c30
-rw-r--r--cpukit/score/cpu/unix/cpu.c30
2 files changed, 38 insertions, 22 deletions
diff --git a/c/src/exec/score/cpu/unix/cpu.c b/c/src/exec/score/cpu/unix/cpu.c
index 796d46d267..3b3dbcd383 100644
--- a/c/src/exec/score/cpu/unix/cpu.c
+++ b/c/src/exec/score/cpu/unix/cpu.c
@@ -400,26 +400,34 @@ void _CPU_Thread_Idle_body( void )
#if CPU_SYNC_IO
if (sync_io_nfds) {
int result;
+ fd_set readfds, writefds, exceptfds;
+ readfds = sync_io_readfds;
+ writefds = sync_io_writefds;
+ exceptfds = sync_io_exceptfds;
result = select(sync_io_nfds,
- &sync_io_readfds,
- &sync_io_writefds,
- &sync_io_exceptfds,
+ &readfds,
+ &writefds,
+ &exceptfds,
NULL);
- if ((result < 0) && (errno != EINTR))
- _CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
+ if (result < 0) {
+ if (errno != EINTR)
+ _CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
+ _Thread_Dispatch();
+ continue;
+ }
for (fd = 0; fd < sync_io_nfds; fd++) {
- boolean read = FD_ISSET(fd, &sync_io_readfds);
- boolean write = FD_ISSET(fd, &sync_io_writefds);
- boolean except = FD_ISSET(fd, &sync_io_exceptfds);
+ boolean read = FD_ISSET(fd, &readfds);
+ boolean write = FD_ISSET(fd, &writefds);
+ boolean except = FD_ISSET(fd, &exceptfds);
if (_CPU_Sync_io_handlers[fd] && (read || write || except))
_CPU_Sync_io_handlers[fd](fd, read, write, except);
-
- _Thread_Dispatch();
}
+
+ _Thread_Dispatch();
} else
pause();
#else
@@ -869,7 +877,7 @@ int _CPU_Clear_sync_io_handler(
if (FD_ISSET(fd, &sync_io_readfds) ||
FD_ISSET(fd, &sync_io_writefds) ||
FD_ISSET(fd, &sync_io_exceptfds))
- sync_io_nfds = fd;
+ sync_io_nfds = fd + 1;
return 0;
}
return -1;
diff --git a/cpukit/score/cpu/unix/cpu.c b/cpukit/score/cpu/unix/cpu.c
index 796d46d267..3b3dbcd383 100644
--- a/cpukit/score/cpu/unix/cpu.c
+++ b/cpukit/score/cpu/unix/cpu.c
@@ -400,26 +400,34 @@ void _CPU_Thread_Idle_body( void )
#if CPU_SYNC_IO
if (sync_io_nfds) {
int result;
+ fd_set readfds, writefds, exceptfds;
+ readfds = sync_io_readfds;
+ writefds = sync_io_writefds;
+ exceptfds = sync_io_exceptfds;
result = select(sync_io_nfds,
- &sync_io_readfds,
- &sync_io_writefds,
- &sync_io_exceptfds,
+ &readfds,
+ &writefds,
+ &exceptfds,
NULL);
- if ((result < 0) && (errno != EINTR))
- _CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
+ if (result < 0) {
+ if (errno != EINTR)
+ _CPU_Fatal_error(0x200); /* FIXME : what number should go here !! */
+ _Thread_Dispatch();
+ continue;
+ }
for (fd = 0; fd < sync_io_nfds; fd++) {
- boolean read = FD_ISSET(fd, &sync_io_readfds);
- boolean write = FD_ISSET(fd, &sync_io_writefds);
- boolean except = FD_ISSET(fd, &sync_io_exceptfds);
+ boolean read = FD_ISSET(fd, &readfds);
+ boolean write = FD_ISSET(fd, &writefds);
+ boolean except = FD_ISSET(fd, &exceptfds);
if (_CPU_Sync_io_handlers[fd] && (read || write || except))
_CPU_Sync_io_handlers[fd](fd, read, write, except);
-
- _Thread_Dispatch();
}
+
+ _Thread_Dispatch();
} else
pause();
#else
@@ -869,7 +877,7 @@ int _CPU_Clear_sync_io_handler(
if (FD_ISSET(fd, &sync_io_readfds) ||
FD_ISSET(fd, &sync_io_writefds) ||
FD_ISSET(fd, &sync_io_exceptfds))
- sync_io_nfds = fd;
+ sync_io_nfds = fd + 1;
return 0;
}
return -1;