#include <sys/time.h>
#endif
+
+/* ---------------------------------------------------------------------
+ Forwardses.
+ ------------------------------------------------------------------ */
+
+static void wait_for_fd_to_be_readable_or_erring ( int fd );
+
+
/* ---------------------------------------------------------------------
Helpers. We have to be pretty self-sufficient.
------------------------------------------------------------------ */
__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);
}
typedef unsigned long int nfds_t;
#endif
+
/* __attribute__((weak)) */
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.
------------------------------------------------------------------ */
#include <sys/time.h>
#endif
+
+/* ---------------------------------------------------------------------
+ Forwardses.
+ ------------------------------------------------------------------ */
+
+static void wait_for_fd_to_be_readable_or_erring ( int fd );
+
+
/* ---------------------------------------------------------------------
Helpers. We have to be pretty self-sufficient.
------------------------------------------------------------------ */
__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);
}
typedef unsigned long int nfds_t;
#endif
+
/* __attribute__((weak)) */
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.
------------------------------------------------------------------ */
#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:
- 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.
+
*/
#include <sys/time.h>
#endif
+
+/* ---------------------------------------------------------------------
+ Forwardses.
+ ------------------------------------------------------------------ */
+
+static void wait_for_fd_to_be_readable_or_erring ( int fd );
+
+
/* ---------------------------------------------------------------------
Helpers. We have to be pretty self-sufficient.
------------------------------------------------------------------ */
__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);
}
typedef unsigned long int nfds_t;
#endif
+
/* __attribute__((weak)) */
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.
------------------------------------------------------------------ */
#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:
- 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.
+
*/
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) );
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) );
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;