[haiku-commits] r34655 - haiku/trunk/src/system/kernel/device_manager

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 13 Dec 2009 20:28:33 +0100 (CET)

Author: bonefish
Date: 2009-12-13 20:28:33 +0100 (Sun, 13 Dec 2009)
New Revision: 34655
Changeset: http://dev.haiku-os.org/changeset/34655/haiku
Ticket: http://dev.haiku-os.org/ticket/4431
Ticket: http://dev.haiku-os.org/ticket/3048
Ticket: http://dev.haiku-os.org/ticket/4883
Ticket: http://dev.haiku-os.org/ticket/4517
Ticket: http://dev.haiku-os.org/ticket/2845
Ticket: http://dev.haiku-os.org/ticket/3428
Ticket: http://dev.haiku-os.org/ticket/3429

Modified:
   haiku/trunk/src/system/kernel/device_manager/IORequest.cpp
   haiku/trunk/src/system/kernel/device_manager/IORequest.h
Log:
Fixed a stupid race condition between IORequest finishing and
IORequest::Wait(). Wait() immediately returned when IsFinished() returned
true, but this is the case as soon as the last IOOperation has finished. The
I/O scheduler is not done with the request at this point, though, since it
will still be sitting in at least one of three doubly linked lists. Since the
usual procedure to issue synchronous I/O requests is to create an IORequest
on the stack, pass it to the I/O scheduler, and Wait() on it, Wait()
returning early might cause the IORequest object to be destroyed while it is
still in use, leading to invalid memory access in the I/O scheduler,
corruption of its list structures, as well as later corruption of the issuing
thread's stack.
Related tickets:
* #4431: The request issuing thread returned and already deleted the area the
  request was writing to before NotifyFinished() was called.
* #3048, #4883: Caused by the on stack IORequest being overwritten with other
  data while being handled by the I/O scheduler thread.
* #4517: Hard to say, but I've seen a such a problem too, after a thread
  scheduling related change. An explanation would be a list structure
  corruption in the I/O scheduler causing an infinite loop with disabled
  interrupts.
* #2845, #3428, #3429: The block notifier/writer is I/O heavy and as such
  quite likely to run into the stack corruption issue.


Modified: haiku/trunk/src/system/kernel/device_manager/IORequest.cpp
===================================================================
--- haiku/trunk/src/system/kernel/device_manager/IORequest.cpp  2009-12-13 
16:35:25 UTC (rev 34654)
+++ haiku/trunk/src/system/kernel/device_manager/IORequest.cpp  2009-12-13 
19:28:33 UTC (rev 34655)
@@ -692,6 +692,7 @@
 
 IORequest::IORequest()
        :
+       fIsNotified(false),
        fFinishedCallback(NULL),
        fFinishedCookie(NULL),
        fIterationCallback(NULL),
@@ -869,7 +870,7 @@
 {
        MutexLocker locker(fLock);
 
-       if (IsFinished())
+       if (IsFinished() && fIsNotified)
                return Status();
 
        ConditionVariableEntry entry;
@@ -932,6 +933,7 @@
        bool deleteRequest = (fFlags & B_DELETE_IO_REQUEST) != 0;
 
        // unblock waiters
+       fIsNotified = true;
        fFinishedCondition.NotifyAll();
 
        locker.Unlock();

Modified: haiku/trunk/src/system/kernel/device_manager/IORequest.h
===================================================================
--- haiku/trunk/src/system/kernel/device_manager/IORequest.h    2009-12-13 
16:35:25 UTC (rev 34654)
+++ haiku/trunk/src/system/kernel/device_manager/IORequest.h    2009-12-13 
19:28:33 UTC (rev 34655)
@@ -334,6 +334,7 @@
                        bool                            fIsWrite;
                        bool                            fPartialTransfer;
                        bool                            
fSuppressChildNotifications;
+                       bool                            fIsNotified;
 
                        io_request_finished_callback    fFinishedCallback;
                        void*                           fFinishedCookie;


Other related posts:

  • » [haiku-commits] r34655 - haiku/trunk/src/system/kernel/device_manager - ingo_weinhold