From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 9687F3857818; Tue, 14 Sep 2021 15:06:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9687F3857818 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: new class fhandler_pipe_fifo X-Act-Checkin: newlib-cygwin X-Git-Author: Ken Brown X-Git-Refname: refs/heads/master X-Git-Oldrev: eb50f82677c914aadee41a5df4d8693a5af81e25 X-Git-Newrev: 085fc12948881e624921f568a29881ce38795368 Message-Id: <20210914150644.9687F3857818@sourceware.org> Date: Tue, 14 Sep 2021 15:06:44 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Sep 2021 15:06:44 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=085fc12948881e624921f568a29881ce38795368 commit 085fc12948881e624921f568a29881ce38795368 Author: Ken Brown Date: Fri Sep 3 19:41:52 2021 -0400 Cygwin: new class fhandler_pipe_fifo This is a parent of fhandler_pipe and fhandler_fifo for code that is common between the two classes. Currently it just contains max_atomic_write and raw_write(). The latter is identical to what used to be fhandler_pipe::raw_write(). Diff: --- winsup/cygwin/fhandler.h | 21 ++++++--- winsup/cygwin/fhandler_fifo.cc | 96 +----------------------------------------- winsup/cygwin/fhandler_pipe.cc | 13 ++++-- 3 files changed, 25 insertions(+), 105 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 032ab5fb0..bb7eb09ce 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1168,12 +1168,24 @@ class fhandler_socket_unix : public fhandler_socket #endif /* __WITH_AF_UNIX */ -class fhandler_pipe: public fhandler_base +/* A parent of fhandler_pipe and fhandler_fifo. */ +class fhandler_pipe_fifo: public fhandler_base +{ + protected: + size_t max_atomic_write; + + public: + fhandler_pipe_fifo (); + + ssize_t __reg3 raw_write (const void *ptr, size_t len); + +}; + +class fhandler_pipe: public fhandler_pipe_fifo { private: HANDLE read_mtx; pid_t popen_pid; - size_t max_atomic_write; void set_pipe_non_blocking (bool nonblocking); public: fhandler_pipe (); @@ -1193,7 +1205,6 @@ public: int dup (fhandler_base *child, int); int close (); void __reg3 raw_read (void *ptr, size_t& len); - ssize_t __reg3 raw_write (const void *ptr, size_t len); int ioctl (unsigned int cmd, void *); int fcntl (int cmd, intptr_t); int __reg2 fstat (struct stat *buf); @@ -1319,7 +1330,7 @@ public: { InterlockedExchange (&_sh_fc_handler_updated, val); } }; -class fhandler_fifo: public fhandler_base +class fhandler_fifo: public fhandler_pipe_fifo { /* Handles to named events shared by all fhandlers for a given FIFO. */ HANDLE read_ready; /* A reader is open; OK for a writer to open. */ @@ -1342,7 +1353,6 @@ class fhandler_fifo: public fhandler_base int nhandlers; /* Number of elements in the array. */ af_unix_spinlock_t _fifo_client_lock; bool reader, writer, duplexer; - size_t max_atomic_write; fifo_reader_id_t me; HANDLE shmem_handle; @@ -1447,7 +1457,6 @@ public: bool isfifo () const { return true; } void set_close_on_exec (bool val); void __reg3 raw_read (void *ptr, size_t& ulen); - ssize_t __reg3 raw_write (const void *ptr, size_t ulen); void fixup_after_fork (HANDLE); void fixup_after_exec (); int __reg2 fstat (struct stat *buf); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index 08b292cad..6709fb974 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -128,13 +128,12 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ static NO_COPY fifo_reader_id_t null_fr_id = { .winpid = 0, .fh = NULL }; fhandler_fifo::fhandler_fifo (): - fhandler_base (), + fhandler_pipe_fifo (), read_ready (NULL), write_ready (NULL), writer_opening (NULL), owner_needed_evt (NULL), owner_found_evt (NULL), update_needed_evt (NULL), cancel_evt (NULL), thr_sync_evt (NULL), pipe_name_buf (NULL), fc_handler (NULL), shandlers (0), nhandlers (0), reader (false), writer (false), duplexer (false), - max_atomic_write (DEFAULT_PIPEBUFSIZE), me (null_fr_id), shmem_handle (NULL), shmem (NULL), shared_fc_hdl (NULL), shared_fc_handler (NULL) { @@ -1138,99 +1137,6 @@ fhandler_fifo::wait (HANDLE h) } } -ssize_t __reg3 -fhandler_fifo::raw_write (const void *ptr, size_t len) -{ - ssize_t ret = -1; - size_t nbytes = 0; - ULONG chunk; - NTSTATUS status = STATUS_SUCCESS; - IO_STATUS_BLOCK io; - HANDLE evt = NULL; - - if (!len) - return 0; - - if (len <= max_atomic_write) - chunk = len; - else if (is_nonblocking ()) - chunk = len = max_atomic_write; - else - chunk = max_atomic_write; - - /* Create a wait event if the FIFO is in blocking mode. */ - if (!is_nonblocking () && !(evt = CreateEvent (NULL, false, false, NULL))) - { - __seterrno (); - return -1; - } - - /* Write in chunks, accumulating a total. If there's an error, just - return the accumulated total unless the first write fails, in - which case return -1. */ - while (nbytes < len) - { - ULONG_PTR nbytes_now = 0; - size_t left = len - nbytes; - ULONG len1; - DWORD waitret = WAIT_OBJECT_0; - - if (left > chunk) - len1 = chunk; - else - len1 = (ULONG) left; - nbytes_now = 0; - status = NtWriteFile (get_handle (), evt, NULL, NULL, &io, - (PVOID) ptr, len1, NULL, NULL); - if (evt && status == STATUS_PENDING) - { - waitret = cygwait (evt); - if (waitret == WAIT_OBJECT_0) - status = io.Status; - } - if (waitret == WAIT_CANCELED) - status = STATUS_THREAD_CANCELED; - else if (waitret == WAIT_SIGNALED) - status = STATUS_THREAD_SIGNALED; - else if (isclosed ()) /* A signal handler might have closed the fd. */ - { - if (waitret == WAIT_OBJECT_0) - set_errno (EBADF); - else - __seterrno (); - } - else if (NT_SUCCESS (status)) - { - nbytes_now = io.Information; - /* NtWriteFile returns success with # of bytes written == 0 - if writing on a non-blocking pipe fails because the pipe - buffer doesn't have sufficient space. */ - if (nbytes_now == 0) - set_errno (EAGAIN); - ptr = ((char *) ptr) + chunk; - nbytes += nbytes_now; - } - else if (STATUS_PIPE_IS_CLOSED (status)) - { - set_errno (EPIPE); - raise (SIGPIPE); - } - else - __seterrno_from_nt_status (status); - if (nbytes_now == 0) - len = 0; /* Terminate loop. */ - if (nbytes > 0) - ret = nbytes; - } - if (evt) - NtClose (evt); - if (status == STATUS_THREAD_SIGNALED && ret < 0) - set_errno (EINTR); - else if (status == STATUS_THREAD_CANCELED) - pthread::static_cancel_self (); - return ret; -} - /* Called from raw_read and select.cc:peek_fifo. */ int fhandler_fifo::take_ownership (DWORD timeout) diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc index 81b1aed5e..68974eb80 100644 --- a/winsup/cygwin/fhandler_pipe.cc +++ b/winsup/cygwin/fhandler_pipe.cc @@ -28,10 +28,15 @@ STATUS_PIPE_EMPTY simply means there's no data to be read. */ || _s == STATUS_PIPE_BROKEN \ || _s == STATUS_PIPE_EMPTY; }) +fhandler_pipe_fifo::fhandler_pipe_fifo () + : fhandler_base (), max_atomic_write (DEFAULT_PIPEBUFSIZE) +{ +} + + fhandler_pipe::fhandler_pipe () - : fhandler_base (), popen_pid (0) + : fhandler_pipe_fifo (), popen_pid (0) { - max_atomic_write = DEFAULT_PIPEBUFSIZE; need_fork_fixup (true); } @@ -340,7 +345,7 @@ fhandler_pipe::raw_read (void *ptr, size_t& len) } ssize_t __reg3 -fhandler_pipe::raw_write (const void *ptr, size_t len) +fhandler_pipe_fifo::raw_write (const void *ptr, size_t len) { size_t nbytes = 0; ULONG chunk; @@ -358,7 +363,7 @@ fhandler_pipe::raw_write (const void *ptr, size_t len) else chunk = max_atomic_write; - /* Create a wait event if the pipe is in blocking mode. */ + /* Create a wait event if the pipe or fifo is in blocking mode. */ if (!is_nonblocking () && !(evt = CreateEvent (NULL, false, false, NULL))) { __seterrno ();