From: Julian Seward Date: Thu, 23 May 2002 13:13:12 +0000 (+0000) Subject: Make accept() be nonblocking. X-Git-Tag: svn/VALGRIND_1_0_3~153 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aad98221b9194e50cbeb5afcb581d8a37ff54cb5;p=thirdparty%2Fvalgrind.git Make accept() be nonblocking. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@313 --- diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c index 46d1c65a79..6cd7e40d0c 100644 --- a/coregrind/arch/x86-linux/vg_libpthread.c +++ b/coregrind/arch/x86-linux/vg_libpthread.c @@ -61,6 +61,14 @@ #include #endif + +/* --------------------------------------------------------------------- + Forwardses. + ------------------------------------------------------------------ */ + +static void wait_for_fd_to_be_readable_or_erring ( int fd ); + + /* --------------------------------------------------------------------- Helpers. We have to be pretty self-sufficient. ------------------------------------------------------------------ */ @@ -1072,6 +1080,7 @@ int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); __attribute__((weak)) int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + wait_for_fd_to_be_readable_or_erring(s); return __libc_accept(s, addr, addrlen); } @@ -1469,6 +1478,7 @@ int select ( int n, typedef unsigned long int nfds_t; #endif + /* __attribute__((weak)) */ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) { @@ -1552,6 +1562,21 @@ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) } +/* Helper function used to make accept() non-blocking. Idea is to use + the above nonblocking poll() to make this thread ONLY wait for the + specified fd to become ready, and then return. */ +static void wait_for_fd_to_be_readable_or_erring ( int fd ) +{ + struct pollfd pfd; + fprintf(stderr, "wait_for_fd_to_be_readable_or_erring %d\n", fd); + pfd.fd = fd; + pfd.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; + /* ... but not POLLOUT, you may notice. */ + pfd.revents = 0; + (void)poll(&pfd, 1, -1 /* forever */); +} + + /* --------------------------------------------------------------------- Hacky implementation of semaphores. ------------------------------------------------------------------ */ diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index 46d1c65a79..6cd7e40d0c 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -61,6 +61,14 @@ #include #endif + +/* --------------------------------------------------------------------- + Forwardses. + ------------------------------------------------------------------ */ + +static void wait_for_fd_to_be_readable_or_erring ( int fd ); + + /* --------------------------------------------------------------------- Helpers. We have to be pretty self-sufficient. ------------------------------------------------------------------ */ @@ -1072,6 +1080,7 @@ int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); __attribute__((weak)) int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + wait_for_fd_to_be_readable_or_erring(s); return __libc_accept(s, addr, addrlen); } @@ -1469,6 +1478,7 @@ int select ( int n, typedef unsigned long int nfds_t; #endif + /* __attribute__((weak)) */ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) { @@ -1552,6 +1562,21 @@ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) } +/* Helper function used to make accept() non-blocking. Idea is to use + the above nonblocking poll() to make this thread ONLY wait for the + specified fd to become ready, and then return. */ +static void wait_for_fd_to_be_readable_or_erring ( int fd ) +{ + struct pollfd pfd; + fprintf(stderr, "wait_for_fd_to_be_readable_or_erring %d\n", fd); + pfd.fd = fd; + pfd.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; + /* ... but not POLLOUT, you may notice. */ + pfd.revents = 0; + (void)poll(&pfd, 1, -1 /* forever */); +} + + /* --------------------------------------------------------------------- Hacky implementation of semaphores. ------------------------------------------------------------------ */ diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 1c6dfede1d..5f023dae26 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -33,10 +33,7 @@ #include "valgrind.h" /* for VG_USERREQ__MAKE_NOACCESS and VG_USERREQ__DO_LEAK_CHECK */ -/* BORKAGE/ISSUES as of 14 Apr 02 - -Note! This pthreads implementation is so poor as to not be -suitable for use by anyone at all! +/* BORKAGE/ISSUES as of 23 May 02 - Currently, when a signal is run, just the ThreadStatus.status fields are saved in the signal frame, along with the CPU state. Question: @@ -55,18 +52,14 @@ suitable for use by anyone at all! - Read/write syscall starts: don't crap out when the initial nonblocking read/write returns an error. -- Get rid of restrictions re use of sigaltstack; they are no longer - needed. - -- Fix signals properly, so that each thread has its own blocking mask. - Currently this isn't done, and (worse?) signals are delivered to - Thread 1 (the root thread) regardless. - - So, what's the deal with signals and mutexes? If a thread is +- So, what's the deal with signals and mutexes? If a thread is blocked on a mutex, or for a condition variable for that matter, can signals still be delivered to it? This has serious consequences -- deadlocks, etc. +- Signals still not really right. Each thread should have its + own pending-set, but there is just one process-wide pending set. + */ diff --git a/vg_libpthread.c b/vg_libpthread.c index 46d1c65a79..6cd7e40d0c 100644 --- a/vg_libpthread.c +++ b/vg_libpthread.c @@ -61,6 +61,14 @@ #include #endif + +/* --------------------------------------------------------------------- + Forwardses. + ------------------------------------------------------------------ */ + +static void wait_for_fd_to_be_readable_or_erring ( int fd ); + + /* --------------------------------------------------------------------- Helpers. We have to be pretty self-sufficient. ------------------------------------------------------------------ */ @@ -1072,6 +1080,7 @@ int __libc_accept(int s, struct sockaddr *addr, socklen_t *addrlen); __attribute__((weak)) int accept(int s, struct sockaddr *addr, socklen_t *addrlen) { + wait_for_fd_to_be_readable_or_erring(s); return __libc_accept(s, addr, addrlen); } @@ -1469,6 +1478,7 @@ int select ( int n, typedef unsigned long int nfds_t; #endif + /* __attribute__((weak)) */ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) { @@ -1552,6 +1562,21 @@ int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) } +/* Helper function used to make accept() non-blocking. Idea is to use + the above nonblocking poll() to make this thread ONLY wait for the + specified fd to become ready, and then return. */ +static void wait_for_fd_to_be_readable_or_erring ( int fd ) +{ + struct pollfd pfd; + fprintf(stderr, "wait_for_fd_to_be_readable_or_erring %d\n", fd); + pfd.fd = fd; + pfd.events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; + /* ... but not POLLOUT, you may notice. */ + pfd.revents = 0; + (void)poll(&pfd, 1, -1 /* forever */); +} + + /* --------------------------------------------------------------------- Hacky implementation of semaphores. ------------------------------------------------------------------ */ diff --git a/vg_scheduler.c b/vg_scheduler.c index 1c6dfede1d..5f023dae26 100644 --- a/vg_scheduler.c +++ b/vg_scheduler.c @@ -33,10 +33,7 @@ #include "valgrind.h" /* for VG_USERREQ__MAKE_NOACCESS and VG_USERREQ__DO_LEAK_CHECK */ -/* BORKAGE/ISSUES as of 14 Apr 02 - -Note! This pthreads implementation is so poor as to not be -suitable for use by anyone at all! +/* BORKAGE/ISSUES as of 23 May 02 - Currently, when a signal is run, just the ThreadStatus.status fields are saved in the signal frame, along with the CPU state. Question: @@ -55,18 +52,14 @@ suitable for use by anyone at all! - Read/write syscall starts: don't crap out when the initial nonblocking read/write returns an error. -- Get rid of restrictions re use of sigaltstack; they are no longer - needed. - -- Fix signals properly, so that each thread has its own blocking mask. - Currently this isn't done, and (worse?) signals are delivered to - Thread 1 (the root thread) regardless. - - So, what's the deal with signals and mutexes? If a thread is +- So, what's the deal with signals and mutexes? If a thread is blocked on a mutex, or for a condition variable for that matter, can signals still be delivered to it? This has serious consequences -- deadlocks, etc. +- Signals still not really right. Each thread should have its + own pending-set, but there is just one process-wide pending set. + */ diff --git a/vg_syscall_mem.c b/vg_syscall_mem.c index 3cffd775b7..8331737933 100644 --- a/vg_syscall_mem.c +++ b/vg_syscall_mem.c @@ -2334,7 +2334,7 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid ) case __NR_sched_setparam: /* syscall 154 */ /* int sched_setparam(pid_t pid, const struct sched_param *p); */ - if (VG_(clo_instrument)) + if (VG_(clo_trace_syscalls)) VG_(printf)("sched_setparam ( %d, %p )\n", arg1, arg2 ); must_be_readable( tst, "sched_setparam(ptr)", arg2, sizeof(struct sched_param) ); @@ -2345,7 +2345,7 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid ) case __NR_sched_getparam: /* syscall 155 */ /* int sched_getparam(pid_t pid, struct sched_param *p); */ - if (VG_(clo_instrument)) + if (VG_(clo_trace_syscalls)) VG_(printf)("sched_getparam ( %d, %p )\n", arg1, arg2 ); must_be_writable( tst, "sched_getparam(ptr)", arg2, sizeof(struct sched_param) ); @@ -2356,7 +2356,7 @@ void VG_(perform_assumed_nonblocking_syscall) ( ThreadId tid ) case __NR_sched_yield: /* syscall 158 */ /* int sched_yield(void); */ - if (VG_(clo_instrument)) + if (VG_(clo_trace_syscalls)) VG_(printf)("sched_yield ()\n" ); KERNEL_DO_SYSCALL(tid,res); break;