[haiku-commits] r37860 - haiku/trunk/src/system/kernel/fs

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 3 Aug 2010 08:55:28 +0200 (CEST)

Author: axeld
Date: 2010-08-03 08:55:28 +0200 (Tue, 03 Aug 2010)
New Revision: 37860
Changeset: http://dev.haiku-os.org/changeset/37860
Ticket: http://dev.haiku-os.org/ticket/5947

Modified:
   haiku/trunk/src/system/kernel/fs/fifo.cpp
Log:
* Implemented a different way to notify waiting read()s when a file descriptor
  is closed; their ReadRequest will now be notified with B_FILE_ERROR.
* This is a better fix for #5947, though note that I left the changes in
  Inode::ReadDataFromBuffer() in place, as I think this is what POSIX requires.


Modified: haiku/trunk/src/system/kernel/fs/fifo.cpp
===================================================================
--- haiku/trunk/src/system/kernel/fs/fifo.cpp   2010-08-03 04:46:21 UTC (rev 
37859)
+++ haiku/trunk/src/system/kernel/fs/fifo.cpp   2010-08-03 06:55:28 UTC (rev 
37860)
@@ -51,8 +51,11 @@
 
 namespace fifo {
 
+
+struct file_cookie;
 class Inode;
 
+
 class RingBuffer {
        public:
                RingBuffer();
@@ -76,9 +79,10 @@
 
 class ReadRequest : public DoublyLinkedListLinkImpl<ReadRequest> {
        public:
-               ReadRequest()
+               ReadRequest(file_cookie* cookie)
                        :
                        fThread(thread_get_current_thread()),
+                       fCookie(cookie),
                        fNotified(true)
                {
                        B_INITIALIZE_SPINLOCK(&fLock);
@@ -90,21 +94,27 @@
                        fNotified = notified;
                }
 
-               void Notify()
+               void Notify(status_t status = B_OK)
                {
                        InterruptsSpinLocker _(fLock);
                        TRACE("ReadRequest %p::Notify(), fNotified %d\n", this, 
fNotified);
 
                        if (!fNotified) {
                                SpinLocker threadLocker(gThreadSpinlock);
-                               thread_unblock_locked(fThread, B_OK);
+                               thread_unblock_locked(fThread, status);
                                fNotified = true;
                        }
                }
 
+               file_cookie* Cookie() const
+               {
+                       return fCookie;
+               }
+
        private:
                spinlock                        fLock;
                struct thread*          fThread;
+               file_cookie*            fCookie;
                volatile bool           fNotified;
 };
 
@@ -165,7 +175,7 @@
                void            NotifyEndClosed(bool writer);
 
                void            Open(int openMode);
-               void            Close(int openMode);
+               void            Close(int openMode, file_cookie* cookie);
                int32           ReaderCount() const { return fReaderCount; }
                int32           WriterCount() const { return fWriterCount; }
 
@@ -215,7 +225,7 @@
 };
 
 
-//---------------------
+// #pragma mark -
 
 
 RingBuffer::RingBuffer()
@@ -390,7 +400,7 @@
                }
 
                // write only as long as there are readers left
-               if (fReaderCount == 0) {
+               if (fActive && fReaderCount == 0) {
                        if (written == 0)
                                send_signal(find_thread(NULL), SIGPIPE);
                        return EPIPE;
@@ -615,12 +625,19 @@
 
 
 void
-Inode::Close(int openMode)
+Inode::Close(int openMode, file_cookie* cookie)
 {
        TRACE("Inode %p::Close(openMode = %d)\n", this, openMode);
 
        MutexLocker locker(RequestLock());
 
+       // Notify all currently reading file descriptors
+       ReadRequestList::Iterator iterator = fReadRequests.GetIterator();
+       while (ReadRequest* request = iterator.Next()) {
+               if (request->Cookie() == cookie)
+                       request->Notify(B_FILE_ERROR);
+       }
+
        if ((openMode & O_ACCMODE) == O_WRONLY && --fWriterCount == 0)
                NotifyEndClosed(true);
 
@@ -750,7 +767,7 @@
        file_cookie *cookie = (file_cookie *)_cookie;
        FIFOInode* fifo = (FIFOInode*)vnode->private_node;
 
-       fifo->Close(cookie->open_mode);
+       fifo->Close(cookie->open_mode, cookie);
 
        return B_OK;
 }
@@ -802,7 +819,7 @@
 
        // issue read request
 
-       ReadRequest request;
+       ReadRequest request(cookie);
        inode->AddReadRequest(request);
 
        TRACE("  issue read request %p\n", &request);


Other related posts: