This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: SMP-ix86-threads-fork: Linux 2.4.x kernel problem identified [phantom read()]
On Tue, Sep 11, 2001 at 04:54:04PM +0200, Wolfram Gloger wrote:
>
> > There's another such place (line 135) with __libc_read in
> > __pthread_manager:
> >
> > /* Synchronize debugging of the thread manager */
> > n = __libc_read(reqfd, (char *)&request, sizeof(request));
> > ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
> >
> > We should account for a return value of -1 here also, shouldn't we?
>
> Yes, but that is only executed once without any threads running,
> so I can't see how that
>
How about this patch?
H.J.
---
2001-09-11 H.J. Lu <hjl@gnu.org>
* internals.h: Include <errno.h>.
(pthread_read): New.
(pthread_write): Likewise.
* join.c (__pthread_do_exit): Replace __libc_write with
pthread_write.
(pthread_join): Likewise.
(pthread_detach): Likewise.
* manager.c (pthread_start_thread): Likewise.
(__pthread_manager_sighandler): Likewise.
* pthread.c (__pthread_initialize_manager): Likewise.
(__pthread_create_2_1): Likewise.
(pthread_onexit_process): Likewise.
(__pthread_message): Likewise.
* semaphore.c (__new_sem_post): Likewise.
* manager.c (__pthread_manager): Replace __libc_read with
pthread_read.
--- linuxthreads/internals.h.intr Fri Aug 31 09:36:49 2001
+++ linuxthreads/internals.h Tue Sep 11 08:23:19 2001
@@ -25,6 +25,7 @@
#include <signal.h>
#include <unistd.h>
#include <stackinfo.h>
+#include <errno.h>
#include <sys/types.h>
#include <bits/libc-tsd.h> /* for _LIBC_TSD_KEY_N */
@@ -322,6 +323,46 @@ static inline int nonexisting_handle(pth
return h->h_descr == NULL || h->h_descr->p_tid != id;
}
+static inline ssize_t pthread_read (int fd, char *buf, size_t n)
+{
+ ssize_t sz_read, nb;
+ sz_read = 0;
+ while (n > 0)
+ {
+ nb = __libc_read (fd, buf, n);
+ if (nb <= 0)
+ {
+ if (nb == -1 && errno == EINTR)
+ continue;
+ return sz_read ?: nb;
+ }
+ buf += nb;
+ sz_read += nb;
+ n -= nb;
+ }
+ return sz_read;
+}
+
+static inline ssize_t pthread_write (int fd, const char *buf, size_t n)
+{
+ ssize_t sz_write, nb;
+ sz_write = 0;
+ while (n > 0)
+ {
+ nb = __libc_write (fd, buf, n);
+ if (nb <= 0)
+ {
+ if (nb == -1 && errno == EINTR)
+ continue;
+ return sz_write ?: nb;
+ }
+ buf += nb;
+ sz_write += nb;
+ n -= nb;
+ }
+ return sz_write;
+}
+
/* Fill in defaults left unspecified by pt-machine.h. */
/* We round up a value with page size. */
--- linuxthreads/join.c.intr Tue Apr 10 17:25:16 2001
+++ linuxthreads/join.c Tue Sep 11 08:22:15 2001
@@ -77,7 +77,7 @@ void __pthread_do_exit(void *retval, cha
if (self == __pthread_main_thread && __pthread_manager_request >= 0) {
request.req_thread = self;
request.req_kind = REQ_MAIN_THREAD_EXIT;
- __libc_write(__pthread_manager_request, (char *)&request, sizeof(request));
+ pthread_write(__pthread_manager_request, (char *)&request, sizeof(request));
suspend(self);
/* Main thread flushes stdio streams and runs atexit functions.
It also calls a handler within LinuxThreads which sends a process exit
@@ -172,7 +172,7 @@ int pthread_join(pthread_t thread_id, vo
request.req_thread = self;
request.req_kind = REQ_FREE;
request.req_args.free.thread_id = thread_id;
- __libc_write(__pthread_manager_request,
+ pthread_write(__pthread_manager_request,
(char *) &request, sizeof(request));
}
return 0;
@@ -210,7 +210,7 @@ int pthread_detach(pthread_t thread_id)
request.req_thread = thread_self();
request.req_kind = REQ_FREE;
request.req_args.free.thread_id = thread_id;
- __libc_write(__pthread_manager_request,
+ pthread_write(__pthread_manager_request,
(char *) &request, sizeof(request));
}
return 0;
--- linuxthreads/manager.c.intr Tue Sep 11 08:04:32 2001
+++ linuxthreads/manager.c Tue Sep 11 08:22:31 2001
@@ -130,7 +130,7 @@ __pthread_manager(void *arg)
/* Raise our priority to match that of main thread */
__pthread_manager_adjust_prio(__pthread_main_thread->p_priority);
/* Synchronize debugging of the thread manager */
- n = __libc_read(reqfd, (char *)&request, sizeof(request));
+ n = pthread_read(reqfd, (char *)&request, sizeof(request));
ASSERT(n == sizeof(request) && request.req_kind == REQ_DEBUG);
ufd.fd = reqfd;
ufd.events = POLLIN;
@@ -150,7 +150,7 @@ __pthread_manager(void *arg)
}
/* Read and execute request */
if (n == 1 && (ufd.revents & POLLIN)) {
- n = __libc_read(reqfd, (char *)&request, sizeof(request));
+ n = pthread_read(reqfd, (char *)&request, sizeof(request));
ASSERT(n == sizeof(request));
switch(request.req_kind) {
case REQ_CREATE:
@@ -266,7 +266,7 @@ pthread_start_thread(void *arg)
if (__pthread_threads_debug && __pthread_sig_debug > 0) {
request.req_thread = self;
request.req_kind = REQ_DEBUG;
- __libc_write(__pthread_manager_request,
+ pthread_write(__pthread_manager_request,
(char *) &request, sizeof(request));
suspend(self);
}
@@ -921,7 +921,7 @@ void __pthread_manager_sighandler(int si
struct pthread_request request;
request.req_thread = 0;
request.req_kind = REQ_KICK;
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
+ pthread_write(__pthread_manager_request, (char *) &request, sizeof(request));
}
}
--- linuxthreads/pthread.c.intr Thu Aug 16 07:58:43 2001
+++ linuxthreads/pthread.c Tue Sep 11 08:22:20 2001
@@ -631,7 +631,7 @@ int __pthread_initialize_manager(void)
}
/* Synchronize debugging of the thread manager */
request.req_kind = REQ_DEBUG;
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
+ pthread_write(__pthread_manager_request, (char *) &request, sizeof(request));
return 0;
}
@@ -653,7 +653,7 @@ int __pthread_create_2_1(pthread_t *thre
request.req_args.create.arg = arg;
sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
&request.req_args.create.mask);
- __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
+ pthread_write(__pthread_manager_request, (char *) &request, sizeof(request));
suspend(self);
retval = THREAD_GETMEM(self, p_retcode);
if (__builtin_expect (retval, 0) == 0)
@@ -785,7 +785,7 @@ static void pthread_onexit_process(int r
request.req_thread = self;
request.req_kind = REQ_PROCESS_EXIT;
request.req_args.exit.code = retcode;
- __libc_write(__pthread_manager_request,
+ pthread_write(__pthread_manager_request,
(char *) &request, sizeof(request));
suspend(self);
/* Main thread should accumulate times for thread manager and its
@@ -1151,7 +1151,7 @@ void __pthread_message(char * fmt, ...)
va_start(args, fmt);
vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
va_end(args);
- __libc_write(2, buffer, strlen(buffer));
+ pthread_write(2, buffer, strlen(buffer));
}
#endif
--- linuxthreads/semaphore.c.intr Fri Jun 15 09:25:59 2001
+++ linuxthreads/semaphore.c Tue Sep 11 08:22:25 2001
@@ -168,7 +168,7 @@ int __new_sem_post(sem_t * sem)
}
request.req_kind = REQ_POST;
request.req_args.post = sem;
- __libc_write(__pthread_manager_request,
+ pthread_write(__pthread_manager_request,
(char *) &request, sizeof(request));
}
return 0;