From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 33721 invoked by alias); 27 Mar 2019 13:02:51 -0000 Mailing-List: contact cygwin-cvs-help@cygwin.com; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cygwin-cvs-owner@cygwin.com Received: (qmail 33625 invoked by uid 9078); 27 Mar 2019 13:02:48 -0000 Date: Wed, 27 Mar 2019 13:02:00 -0000 Message-ID: <20190327130248.33624.qmail@sourceware.org> 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: FIFO: add a spinlock X-Act-Checkin: newlib-cygwin X-Git-Author: Ken Brown X-Git-Refname: refs/heads/master X-Git-Oldrev: 48d4cce3be58b1b0d4ca1befbcbe5467a0301f51 X-Git-Newrev: c75e077f9953e3ecc6ba371d7ef95e14883a68ba X-SW-Source: 2019-q1/txt/msg00249.txt.bz2 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=c75e077f9953e3ecc6ba371d7ef95e14883a68ba commit c75e077f9953e3ecc6ba371d7ef95e14883a68ba Author: Ken Brown Date: Fri Mar 22 19:30:38 2019 +0000 Cygwin: FIFO: add a spinlock Don't let listen_client_thread and raw_read access the client list simultaneously. Diff: --- winsup/cygwin/fhandler.h | 3 +++ winsup/cygwin/fhandler_fifo.cc | 34 +++++++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index e7c4af6..997dc0b 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1267,6 +1267,7 @@ class fhandler_fifo: public fhandler_base WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; fifo_client_handler client[MAX_CLIENTS]; int nclients, nconnected; + af_unix_spinlock_t _fifo_client_lock; bool __reg2 wait (HANDLE); NTSTATUS npfs_handle (HANDLE &); HANDLE create_pipe_instance (bool); @@ -1278,6 +1279,8 @@ public: fhandler_fifo (); PUNICODE_STRING get_pipe_name (); DWORD listen_client_thread (); + void fifo_client_lock () { _fifo_client_lock.lock (); } + void fifo_client_unlock () { _fifo_client_lock.unlock (); } int open (int, mode_t); off_t lseek (off_t offset, int whence); int close (); diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc index e91e880..b0016ee 100644 --- a/winsup/cygwin/fhandler_fifo.cc +++ b/winsup/cygwin/fhandler_fifo.cc @@ -349,13 +349,17 @@ fhandler_fifo::listen_client_thread () int i; DWORD wait_ret; + fifo_client_lock (); found = false; for (i = 0; i < nclients; i++) switch (client[i].state) { case fc_invalid: if (disconnect_and_reconnect (i) < 0) - goto errout; + { + fifo_client_unlock (); + goto errout; + } /* Fall through. */ case fc_connected: w[i] = client[i].dummy_evt; @@ -369,13 +373,15 @@ fhandler_fifo::listen_client_thread () break; } w[nclients] = lct_termination_evt; + int res = 0; if (!found) - { - if (add_client () < 0) - goto errout; - else - continue; - } + res = add_client (); + fifo_client_unlock (); + if (res < 0) + goto errout; + else if (!found) + continue; + if (!arm (read_ready)) { __seterrno (); @@ -391,9 +397,11 @@ fhandler_fifo::listen_client_thread () return 0; else { + fifo_client_lock (); client[i].state = fc_connected; nconnected++; set_pipe_non_blocking (client[i].fh->get_handle (), true); + fifo_client_unlock (); yield (); } } @@ -664,6 +672,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) } /* Poll the connected clients for input. */ + fifo_client_lock (); for (int i = 0; i < nclients; i++) if (client[i].state == fc_connected) { @@ -671,15 +680,22 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len) client[i].fh->fhandler_base::raw_read (in_ptr, len); ssize_t nread = (ssize_t) len; if (nread > 0) - return; + { + fifo_client_unlock (); + return; + } else if (nread < 0 && GetLastError () != ERROR_NO_DATA) - goto errout; + { + fifo_client_unlock (); + goto errout; + } else if (nread == 0) /* Client has disconnected. */ { client[i].state = fc_invalid; nconnected--; } } + fifo_client_unlock (); if (is_nonblocking ()) { set_errno (EAGAIN);