]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOPMinformeeList.cpp
xnu-4903.241.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOPMinformeeList.cpp
index 48a87045725f2fec232196f41543ad6f87abf7c4..5857bb6b4507928a4c01bf05d0747155f6592bb4 100644 (file)
@@ -1,23 +1,29 @@
 /*
  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 #include <IOKit/pwr_mgt/IOPM.h>
 #include <IOKit/pwr_mgt/IOPMinformeeList.h>
@@ -36,24 +42,135 @@ void IOPMinformeeList::initialize ( void )
     length = 0;
 }
 
+//******************************************************************************
+// getSharedRecursiveLock
+//
+//******************************************************************************
+IORecursiveLock *IOPMinformeeList::getSharedRecursiveLock( void )
+{
+    static IORecursiveLock *sharedListLock = NULL;
+    
+    /* A running system could have 50-60+ instances of IOPMInformeeList. 
+     * They'll share this lock, since list insertion and removal is relatively
+     * rare, and generally tied to major events like device discovery.
+     *
+     * getSharedRecursiveLock() is called from IOStartIOKit to initialize
+     * the sharedListLock before any IOPMinformeeLists are instantiated.
+     *
+     * The IOPMinformeeList class will be around for the lifetime of the system,
+     * we don't worry about freeing this lock.
+     */
+
+    if ( NULL == sharedListLock )
+    {
+        sharedListLock = IORecursiveLockAlloc();
+    }
+    return sharedListLock;
+}
+
+ //*********************************************************************************
+// appendNewInformee
+ //
+ //*********************************************************************************
+IOPMinformee *IOPMinformeeList::appendNewInformee ( IOService * newObject )
+{
+    IOPMinformee * newInformee;
+    
+    if (!newObject)
+        return NULL;
+    newInformee = IOPMinformee::withObject (newObject);    
+
+    if (!newInformee)
+        return NULL;
+
+    if( IOPMNoErr == addToList (newInformee))
+        return newInformee;
+    else
+        return NULL;
+}
+
+
 //*********************************************************************************
 // addToList
-//
+// *OBSOLETE* do not call from outside of this file.
+// Try appendNewInformee() instead
 //*********************************************************************************
-
 IOReturn IOPMinformeeList::addToList ( IOPMinformee * newInformee )
 {
     IOPMinformee * nextInformee;
-    nextInformee = firstItem;                          // Is new object already in the list?
-    while (  nextInformee != NULL ) {
-        if ( nextInformee->whatObject == newInformee->whatObject ) {
-            return IOPMNoErr;                          // yes, just return
+    IORecursiveLock    *listLock = getSharedRecursiveLock();
+
+    if(!listLock)
+        return kIOReturnError;
+
+    IORecursiveLockLock(listLock);
+    nextInformee = firstItem;                          
+    
+    // Is new object already in the list?
+    while (  nextInformee != NULL ) 
+    {
+        if ( nextInformee->whatObject == newInformee->whatObject ) 
+        {
+            // object is present; just exit
+            goto unlock_and_exit;
         }
         nextInformee = nextInList(nextInformee);
     }
-    newInformee->nextInList = firstItem;               // add it to list
+
+    // add it to the front of the list
+    newInformee->nextInList = firstItem;
     firstItem = newInformee;
-    length += 1;
+    length++;
+
+unlock_and_exit:
+    IORecursiveLockUnlock(listLock);
+    return IOPMNoErr;
+}
+
+
+//*********************************************************************************
+// removeFromList
+//
+// Find the item in the list, unlink it, and free it.
+//*********************************************************************************
+
+IOReturn IOPMinformeeList::removeFromList ( IOService * theItem )
+{
+    IOPMinformee * item = firstItem;
+    IOPMinformee * temp;
+    IORecursiveLock    *listLock = getSharedRecursiveLock();
+
+    if ( NULL == item ) 
+        return IOPMNoErr;
+    if(!listLock) 
+        return kIOReturnError;
+
+    IORecursiveLockLock( listLock );
+    
+    if ( item->whatObject == theItem ) 
+    {
+        firstItem = item->nextInList;
+        length--;
+        item->release();
+        goto unlock_and_exit;
+    }
+    
+    while ( item->nextInList != NULL ) 
+    {
+        if ( item->nextInList->whatObject == theItem ) 
+        {
+            temp = item->nextInList;
+            item->nextInList = temp->nextInList;
+            length--;
+            temp->release();
+            goto unlock_and_exit;
+        }
+        item = item->nextInList;
+    }
+
+unlock_and_exit:
+    IORecursiveLockUnlock(listLock);
     return IOPMNoErr;
 }
 
@@ -113,38 +230,6 @@ IOPMinformee * IOPMinformeeList::findItem ( IOService * driverOrChild )
 }
 
 
-//*********************************************************************************
-// removeFromList
-//
-// Find the item in the list, unlink it, and free it.
-//*********************************************************************************
-
-IOReturn IOPMinformeeList::removeFromList ( IOService * theItem )
-{
-    IOPMinformee * item = firstItem;
-    IOPMinformee * temp;
-
-    if ( item != NULL ) {
-        if ( item->whatObject == theItem ) {
-            firstItem = item->nextInList;
-            length--;
-            item->release();
-            return IOPMNoErr;
-        }
-        while ( item->nextInList != NULL ) {
-            if ( item->nextInList->whatObject == theItem ) {
-                temp = item->nextInList;
-                item->nextInList = temp->nextInList;
-                length--;
-                temp->release();
-                return IOPMNoErr;
-            }
-            item = item->nextInList;
-        }
-    }
-    return IOPMNoErr;
-}
-
 
 //*********************************************************************************
 // free