From f8b8b1be3cbd92e934a173823d656f3e8363eb49 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Sat, 13 Aug 2011 10:28:15 +0000 Subject: [PATCH] * miscfuncs.cc (CreatePipeOverlapped): New function. (ReadPipeOverlapped): Ditto. (WritePipeOverlapped): Ditto. * miscfuncs.h: Declare new functions. * pinfo.cc (commune_process): Call WritePipeOverlapped instead of WriteFile. Set timeout to 1 sec. (_pinfo::commune_request): Call ReadPipeOverlapped instead of ReadFile. Set timeout to 0.5 secs. * sigproc.cc (sig_send): Create pipe using CreatePipeOverlapped. --- winsup/cygwin/ChangeLog | 12 ++++++++ winsup/cygwin/miscfuncs.cc | 51 ++++++++++++++++++++++++++++++++ winsup/cygwin/miscfuncs.h | 7 +++++ winsup/cygwin/pinfo.cc | 60 ++++++++++++++++++++------------------ winsup/cygwin/sigproc.cc | 2 +- 5 files changed, 103 insertions(+), 29 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 759d0c880..67b8441e5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2011-08-13 Corinna Vinschen + + * miscfuncs.cc (CreatePipeOverlapped): New function. + (ReadPipeOverlapped): Ditto. + (WritePipeOverlapped): Ditto. + * miscfuncs.h: Declare new functions. + * pinfo.cc (commune_process): Call WritePipeOverlapped instead of + WriteFile. Set timeout to 1 sec. + (_pinfo::commune_request): Call ReadPipeOverlapped instead of ReadFile. + Set timeout to 0.5 secs. + * sigproc.cc (sig_send): Create pipe using CreatePipeOverlapped. + 2011-08-12 Christopher Faylor * miscfuncs.cc (create_pipe): Delete obsolete function. diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc index 42880c12c..755a05829 100644 --- a/winsup/cygwin/miscfuncs.cc +++ b/winsup/cygwin/miscfuncs.cc @@ -332,6 +332,57 @@ nice_to_winprio (int &nice) return prio; } +/* Minimal overlapped pipe I/O implementation for signal and commune stuff. */ + +BOOL WINAPI +CreatePipeOverlapped (PHANDLE hr, PHANDLE hw, LPSECURITY_ATTRIBUTES sa) +{ + int ret = fhandler_pipe::create_selectable (sa, *hr, *hw, 0); + if (ret) + SetLastError (ret); + return ret == 0; +} + +BOOL WINAPI +ReadPipeOverlapped (HANDLE h, PVOID buf, DWORD len, LPDWORD ret_len, + DWORD timeout) +{ + OVERLAPPED ov; + BOOL ret; + + memset (&ov, 0, sizeof ov); + ov.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); + ret = ReadFile (h, buf, len, NULL, &ov); + if (ret || GetLastError () == ERROR_IO_PENDING) + { + if (!ret && WaitForSingleObject (ov.hEvent, timeout) != WAIT_OBJECT_0) + CancelIo (h); + ret = GetOverlappedResult (h, &ov, ret_len, FALSE); + } + CloseHandle (ov.hEvent); + return ret; +} + +BOOL WINAPI +WritePipeOverlapped (HANDLE h, PCVOID buf, DWORD len, LPDWORD ret_len, + DWORD timeout) +{ + OVERLAPPED ov; + BOOL ret; + + memset (&ov, 0, sizeof ov); + ov.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); + ret = WriteFile (h, buf, len, NULL, &ov); + if (ret || GetLastError () == ERROR_IO_PENDING) + { + if (!ret && WaitForSingleObject (ov.hEvent, timeout) != WAIT_OBJECT_0) + CancelIo (h); + ret = GetOverlappedResult (h, &ov, ret_len, FALSE); + } + CloseHandle (ov.hEvent); + return ret; +} + /* backslashify: Convert all forward slashes in src path to back slashes in dst path. Add a trailing slash to dst when trailing_slash_p arg is set to 1. */ diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h index 0cff6c2b2..9ec6f5916 100644 --- a/winsup/cygwin/miscfuncs.h +++ b/winsup/cygwin/miscfuncs.h @@ -17,6 +17,13 @@ DWORD nice_to_winprio (int &) __attribute__ ((regparm (1))); bool __stdcall create_pipe (PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD) __attribute__ ((regparm (3))); +BOOL WINAPI CreatePipeOverlapped (PHANDLE read_handle, PHANDLE write_handle, + LPSECURITY_ATTRIBUTES sa); +BOOL WINAPI ReadPipeOverlapped (HANDLE h, PVOID buf, DWORD len, + LPDWORD ret_len, DWORD timeout); +BOOL WINAPI WritePipeOverlapped (HANDLE h, PCVOID buf, DWORD len, + LPDWORD ret_len, DWORD timeout); + extern "C" void yield (); void backslashify (const char *, char *, bool); diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc index 89a96ef16..4e63e238d 100644 --- a/winsup/cygwin/pinfo.cc +++ b/winsup/cygwin/pinfo.cc @@ -483,16 +483,17 @@ commune_process (void *arg) n += strlen (argv[i]) + 1; } argv[__argc_safe] = NULL; - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) { /*__seterrno ();*/ // this is run from the signal thread, so don't set errno - sigproc_printf ("WriteFile sizeof argv failed, %E"); + sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E"); } else for (const char **a = argv; *a; a++) - if (!WriteFile (tothem, *a, strlen (*a) + 1, &nr, NULL)) + if (!WritePipeOverlapped (tothem, *a, strlen (*a) + 1, &nr, 1000L)) { - sigproc_printf ("WriteFile arg %d failed, %E", a - argv); + sigproc_printf ("WritePipeOverlapped arg %d failed, %E", + a - argv); break; } break; @@ -501,10 +502,10 @@ commune_process (void *arg) { sigproc_printf ("processing PICOM_CWD"); unsigned int n = strlen (cygheap->cwd.get (path, 1, 1, NT_MAX_PATH)) + 1; - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof cwd failed, %E"); - else if (!WriteFile (tothem, path, n, &nr, NULL)) - sigproc_printf ("WriteFile cwd failed, %E"); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof cwd failed, %E"); + else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped cwd failed, %E"); break; } case PICOM_ROOT: @@ -515,10 +516,10 @@ commune_process (void *arg) n = strlen (strcpy (path, cygheap->root.posix_path ())) + 1; else n = strlen (strcpy (path, "/")) + 1; - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof root failed, %E"); - else if (!WriteFile (tothem, path, n, &nr, NULL)) - sigproc_printf ("WriteFile root failed, %E"); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof root failed, %E"); + else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped root failed, %E"); break; } case PICOM_FDS: @@ -530,13 +531,13 @@ commune_process (void *arg) while ((fd = cfd.next ()) >= 0) n += sizeof (int); cfd.rewind (); - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof fds failed, %E"); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof fds failed, %E"); else while ((fd = cfd.next ()) >= 0) - if (!WriteFile (tothem, &fd, sizeof fd, &nr, NULL)) + if (!WritePipeOverlapped (tothem, &fd, sizeof fd, &nr, 1000L)) { - sigproc_printf ("WriteFile fd %d failed, %E", fd); + sigproc_printf ("WritePipeOverlapped fd %d failed, %E", fd); break; } break; @@ -552,14 +553,14 @@ commune_process (void *arg) { fhandler_pipe *fh = cfd; n = sizeof *fh; - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof hdl failed, %E"); - else if (!WriteFile (tothem, fh, n, &nr, NULL)) - sigproc_printf ("WriteFile hdl failed, %E"); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E"); + else if (!WritePipeOverlapped (tothem, fh, n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped hdl failed, %E"); break; } - if (!n && !WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof hdl failed, %E"); + if (!n && !WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof hdl failed, %E"); break; } case PICOM_FD: @@ -572,10 +573,10 @@ commune_process (void *arg) n = strlen (strcpy (path, "")) + 1; else n = strlen (cfd->get_proc_fd_name (path)) + 1; - if (!WriteFile (tothem, &n, sizeof n, &nr, NULL)) - sigproc_printf ("WriteFile sizeof fd failed, %E"); - else if (!WriteFile (tothem, path, n, &nr, NULL)) - sigproc_printf ("WriteFile fd failed, %E"); + if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped sizeof fd failed, %E"); + else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L)) + sigproc_printf ("WritePipeOverlapped fd failed, %E"); break; } } @@ -655,7 +656,8 @@ _pinfo::commune_request (__uint32_t code, ...) case PICOM_FDS: case PICOM_FD: case PICOM_PIPE_FHANDLER: - if (!ReadFile (fromthem, &n, sizeof n, &nr, NULL) || nr != sizeof n) + if (!ReadPipeOverlapped (fromthem, &n, sizeof n, &nr, 500L) + || nr != sizeof n) { __seterrno (); goto err; @@ -666,7 +668,9 @@ _pinfo::commune_request (__uint32_t code, ...) { res.s = (char *) cmalloc_abort (HEAP_COMMUNE, n); char *p; - for (p = res.s; n && ReadFile (fromthem, p, n, &nr, NULL); p += nr, n -= nr) + for (p = res.s; + n && ReadPipeOverlapped (fromthem, p, n, &nr, 500L); + p += nr, n -= nr) continue; if (n) { diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index db4c02fbf..26f50f7be 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -608,7 +608,7 @@ sig_send (_pinfo *p, siginfo_t& si, _cygtls *tls) HANDLE& tome = si._si_commune._si_write_handle; HANDLE& fromthem = si._si_commune._si_read_handle; - if (!CreatePipe (&fromthem, &tome, &sec_all_nih, 0)) + if (!CreatePipeOverlapped (&fromthem, &tome, &sec_all_nih)) { sigproc_printf ("CreatePipe for __SIGCOMMUNE failed, %E"); __seterrno ();