This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]