OSDN Git Service

* cygtls.h (_cygtls::inside_kernel): Move function declaration into _cygtls
authorcgf <cgf>
Sun, 29 Jul 2007 05:22:05 +0000 (05:22 +0000)
committercgf <cgf>
Sun, 29 Jul 2007 05:22:05 +0000 (05:22 +0000)
class.
* exceptions.cc (_cygtls::inside_kernel): Move function definition into _cygtls
class.
* fhandler.cc (fhandler_base::wait_overlapped): Make return tri-state to detect
when there is a EINTR situation.  Add a pointer to a length parameter.  Move
GetOverlappedResult into this function.
(fhandler_base::read_overlapped): Accommodate above changes and loop if we
receive a restartable signal.
(fhandler_base::write_overlapped): Ditto.
* fhandler.h (fhandler_base::wait_overlapped): Reflect above changes.
* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.

winsup/cygwin/ChangeLog
winsup/cygwin/cygtls.h
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler.h
winsup/cygwin/fhandler_fifo.cc

index 6f8e623..0ef56eb 100644 (file)
@@ -1,3 +1,19 @@
+2007-07-29  Christopher Faylor  <me+cygwin@cgf.cx>
+
+       * cygtls.h (_cygtls::inside_kernel): Move function declaration into
+       _cygtls class.
+       * exceptions.cc (_cygtls::inside_kernel): Move function definition into
+       _cygtls class.
+
+       * fhandler.cc (fhandler_base::wait_overlapped): Make return tri-state
+       to detect when there is a EINTR situation.  Add a pointer to a length
+       parameter.  Move GetOverlappedResult into this function.
+       (fhandler_base::read_overlapped): Accommodate above changes and loop if
+       we receive a restartable signal.
+       (fhandler_base::write_overlapped): Ditto.
+       * fhandler.h (fhandler_base::wait_overlapped): Reflect above changes.
+       * fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
+
 2007-07-28  Corinna Vinschen  <corinna@vinschen.de>
 
        * ntdll.h (RtlEqualUnicodePathPrefix): Rename from RtlEqualPathPrefix.
index d42ccc6..7e584f6 100644 (file)
@@ -190,7 +190,8 @@ struct _cygtls
 
   /* exception handling */
   static int handle_exceptions (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
-  static int handle_threadlist_exception (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT *c, void *);
+  static int handle_threadlist_exception (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *);
+  bool inside_kernel (CONTEXT *);
   void init_exception_handler (int (*) (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void*));
   void init_threadlist_exceptions ();
   void signal_exit (int) __attribute__ ((noreturn, regparm(2)));
index efb7a54..648a39f 100644 (file)
@@ -282,13 +282,13 @@ stackdump (DWORD ebp, int open_file, bool isexception)
              i == 16 ? " (more stack frames may be present)" : "");
 }
 
-static bool
-inside_kernel (CONTEXT *cx)
+bool
+_cygtls::inside_kernel (CONTEXT *cx)
 {
   int res;
   MEMORY_BASIC_INFORMATION m;
 
-  if (!_my_tls.isinitialized ())
+  if (!isinitialized ())
     return true;
 
   memset (&m, 0, sizeof m);
@@ -627,7 +627,7 @@ _cygtls::handle_exceptions (EXCEPTION_RECORD *e, exception_list *frame, CONTEXT
            error_code |= 1;
          if (e->ExceptionInformation[0])       /* Write access */
            error_code |= 2;
-         if (!inside_kernel (in))              /* User space */
+         if (!me.inside_kernel (in))           /* User space */
            error_code |= 4;
          klog (LOG_INFO, "%s[%d]: segfault at %08x rip %08x rsp %08x error %d",
                          __progname, myself->pid,
index ac9527a..efe2aa6 100644 (file)
@@ -1694,9 +1694,11 @@ fhandler_base::destroy_overlapped ()
     }
 }
 
-bool
-fhandler_base::wait_overlapped (bool& res, bool writing)
+int
+fhandler_base::wait_overlapped (bool& res, bool writing, DWORD *bytes)
 {
+  if (bytes)
+    *bytes = (DWORD) -1;
   if (!res && GetLastError () != ERROR_IO_PENDING)
     __seterrno ();
   else
@@ -1712,15 +1714,27 @@ fhandler_base::wait_overlapped (bool& res, bool writing)
       w4[0] = get_overlapped ()->hEvent;
       if (&_my_tls == _main_tls)
        w4[n++] = signal_arrived;
+      HANDLE h = writing ? get_output_handle () : get_handle ();
       switch (WaitForMultipleObjects (n, w4, false, INFINITE))
        {
        case WAIT_OBJECT_0:
-         res = true;
+         if (!bytes ||
+             GetOverlappedResult (h, get_overlapped (), bytes, false))
+           res = 1;
+         else
+           {
+             __seterrno ();
+             res = -1;
+           }
          break;
        case WAIT_OBJECT_0 + 1:
-         CancelIo (writing ? get_output_handle () : get_handle ());
+         CancelIo (h);
          set_errno (EINTR);
-         res = false;
+         res = 0;
+         break;
+       default:
+         __seterrno ();
+         res = -1;
          break;
        }
     }
@@ -1735,11 +1749,14 @@ fhandler_base::read_overlapped (void *ptr, size_t& len)
   assert (get_overlapped ());
   assert (get_overlapped ()->hEvent);
 #endif
-  bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len,
-                      get_overlapped ());
-  if (!wait_overlapped (res, false)
-      || !GetOverlappedResult (get_handle (), get_overlapped (), (DWORD *) &len, false))
-    len = 0;
+  while (1)
+    {
+      bool res = ReadFile (get_handle (), ptr, len, (DWORD *) &len,
+                          get_overlapped ());
+      int wres = wait_overlapped (res, false, (DWORD *) &len);
+      if (wres || !_my_tls.call_signal_handler ())
+       break;
+    }
 }
 
 int
@@ -1747,11 +1764,15 @@ fhandler_base::write_overlapped (const void *ptr, size_t len)
 {
   DWORD bytes_written;
 
-  bool res = WriteFile (get_output_handle (), ptr, len, &bytes_written,
-                       get_overlapped ());
-  if (!wait_overlapped (res, true)
-      || !GetOverlappedResult (get_handle (), get_overlapped (),
-                              &bytes_written, false))
-    return -1;
+  while (1)
+    {
+      bool res = WriteFile (get_output_handle (), ptr, len, &bytes_written,
+                           get_overlapped ());
+      int wres = wait_overlapped (res, true, &bytes_written);
+      if (wres < 0)
+       return -1;
+      if (wres || !_my_tls.call_signal_handler ())
+       break;
+    }
   return bytes_written;
 }
index af505e8..9a91191 100644 (file)
@@ -139,7 +139,7 @@ class fhandler_base
   DWORD fs_flags;
   HANDLE read_state;
   path_conv pc;
-  bool wait_overlapped (bool&, bool) __attribute__ ((regparm (2)));
+  int wait_overlapped (bool&, bool, DWORD *) __attribute__ ((regparm (3)));
   bool setup_overlapped () __attribute__ ((regparm (1)));
   void destroy_overlapped () __attribute__ ((regparm (1)));
 
index ec1bbf2..668c4e2 100644 (file)
@@ -139,7 +139,7 @@ fhandler_fifo::wait (bool iswrite)
       bool res = ConnectNamedPipe (get_handle (), get_overlapped ());
       if (res || GetLastError () == ERROR_PIPE_CONNECTED)
        return true;
-      return wait_overlapped (res, iswrite);
+      return wait_overlapped (res, iswrite, NULL);
     default:
       break;
     }