From 412693ab6529ecd163630785064f2c989db9ad4a Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 4 May 2011 12:23:00 +0000 Subject: [PATCH] * fhandler.h (fhandler_dev_tape::_lock): Add bool parameter. * fhandler_tape.cc (lock): Call _lock with false argument. (_lock): Take bool cancelable parameter. Handle O_NONBLOCK. Make cancelable if cancelabe parameter is true. (fhandler_dev_tape::raw_read): Call _lock with true argument. (fhandler_dev_tape::raw_write): Ditto. --- winsup/cygwin/ChangeLog | 9 ++++++++ winsup/cygwin/fhandler.h | 2 +- winsup/cygwin/fhandler_tape.cc | 40 +++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1631f643a..7ac1a54f5 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +2011-05-04 Corinna Vinschen + + * fhandler.h (fhandler_dev_tape::_lock): Add bool parameter. + * fhandler_tape.cc (lock): Call _lock with false argument. + (_lock): Take bool cancelable parameter. Handle O_NONBLOCK. + Make cancelable if cancelabe parameter is true. + (fhandler_dev_tape::raw_read): Call _lock with true argument. + (fhandler_dev_tape::raw_write): Ditto. + 2011-05-04 Corinna Vinschen * fhandler_dsp.cc (fhandler_dev_dsp::Audio): Add fh member. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 48ec5cec9..398aca913 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -751,7 +751,7 @@ class fhandler_dev_tape: public fhandler_dev_raw unsigned int driveno () { return (unsigned int) get_minor () & 0x7f; } void drive_init (); - inline bool _lock (); + inline bool _lock (bool); inline int unlock (int ret = 0); public: diff --git a/winsup/cygwin/fhandler_tape.cc b/winsup/cygwin/fhandler_tape.cc index ff7e84aab..97e5d6010 100644 --- a/winsup/cygwin/fhandler_tape.cc +++ b/winsup/cygwin/fhandler_tape.cc @@ -2,7 +2,7 @@ classes. Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2010 Red Hat, Inc. + 2008, 2010, 2011 Red Hat, Inc. This file is part of Cygwin. @@ -1136,19 +1136,38 @@ mtinfo::initialize () #define mt (cygwin_shared->mt) -#define lock(err_ret_val) if (!_lock ()) return err_ret_val; +#define lock(err_ret_val) if (!_lock (false)) return (err_ret_val); inline bool -fhandler_dev_tape::_lock () +fhandler_dev_tape::_lock (bool cancelable) { - HANDLE obj[2] = { mt_mtx, signal_arrived }; - BOOL ret = WaitForMultipleObjects (2, obj, FALSE, INFINITE) == WAIT_OBJECT_0; - if (!ret) + HANDLE w4[3] = { mt_mtx, signal_arrived, NULL }; + DWORD cnt = 2; + if (cancelable && (w4[2] = pthread::get_cancel_event ()) != NULL) + cnt = 3; + /* O_NONBLOCK is only valid in a read or write call. Only those are + cancelable. */ + DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE; +restart: + switch (WaitForMultipleObjects (cnt, w4, FALSE, timeout)) { - debug_printf ("signal_arrived"); \ + case WAIT_OBJECT_0: + return true; + case WAIT_OBJECT_0 + 1: + if (_my_tls.call_signal_handler ()) + goto restart; set_errno (EINTR); + return false; + case WAIT_OBJECT_0 + 2: + pthread::static_cancel_self (); + /*NOTREACHED*/ + case WAIT_TIMEOUT: + set_errno (EAGAIN); + return false; + default: + __seterrno (); + return false; } - return ret; } inline int @@ -1248,7 +1267,7 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) ulen = 0; return; } - if (!_lock ()) + if (!_lock (true)) { ulen = (size_t) -1; return; @@ -1336,7 +1355,8 @@ fhandler_dev_tape::raw_read (void *ptr, size_t &ulen) ssize_t __stdcall fhandler_dev_tape::raw_write (const void *ptr, size_t len) { - lock (-1); + if (!_lock (true)) + return -1; if (!mt_evt && !(mt_evt = CreateEvent (&sec_none, TRUE, FALSE, NULL))) debug_printf ("Creating event failed, %E"); int ret = mt.drive (driveno ())->write (get_handle (), mt_evt, ptr, len); -- 2.43.5