From b4e3b2bd68e78769ad75361e880976b40c1d6a7b Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 28 Oct 1998 19:25:12 +0000 Subject: Patch from Ian Lance Taylor . 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. --- cpukit/score/cpu/unix/cpu.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'cpukit/score/cpu/unix/cpu.c') 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; -- cgit v1.2.3