]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOSharedDataQueue.cpp
xnu-3247.1.106.tar.gz
[apple/xnu.git] / iokit / Kernel / IOSharedDataQueue.cpp
index 5eb1c35ed3eb6870ae22d3ab404f514af6df4877..71daaa6b449ae17a5ee5c881ae8c96b706a7a240 100644 (file)
@@ -75,42 +75,50 @@ Boolean IOSharedDataQueue::initWithCapacity(UInt32 size)
 {
     IODataQueueAppendix *   appendix;
     vm_size_t               allocSize;
-    
+
     if (!super::init()) {
         return false;
     }
-    
+
     _reserved = (ExpansionData *)IOMalloc(sizeof(struct ExpansionData));
     if (!_reserved) {
         return false;
     }
-    
+
     if (size > UINT32_MAX - DATA_QUEUE_MEMORY_HEADER_SIZE - DATA_QUEUE_MEMORY_APPENDIX_SIZE) {
         return false;
     }
     
     allocSize = round_page(size + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE);
-    
+
     if (allocSize < size) {
         return false;
     }
-    
+
     dataQueue = (IODataQueueMemory *)IOMallocAligned(allocSize, PAGE_SIZE);
     if (dataQueue == 0) {
         return false;
     }
+    bzero(dataQueue, allocSize);
 
     dataQueue->queueSize    = size;
-    dataQueue->head         = 0;
-    dataQueue->tail         = 0;
-    
+//  dataQueue->head         = 0;
+//  dataQueue->tail         = 0;
+
     if (!setQueueSize(size)) {
         return false;
     }
     
     appendix            = (IODataQueueAppendix *)((UInt8 *)dataQueue + size + DATA_QUEUE_MEMORY_HEADER_SIZE);
     appendix->version   = 0;
-    notifyMsg           = &(appendix->msgh);
+
+    if (!notifyMsg) {
+        notifyMsg = IOMalloc(sizeof(mach_msg_header_t));
+        if (!notifyMsg)
+            return false;
+    }
+    bzero(notifyMsg, sizeof(mach_msg_header_t));
+
     setNotificationPort(MACH_PORT_NULL);
 
     return true;
@@ -121,12 +129,16 @@ void IOSharedDataQueue::free()
     if (dataQueue) {
         IOFreeAligned(dataQueue, round_page(getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE + DATA_QUEUE_MEMORY_APPENDIX_SIZE));
         dataQueue = NULL;
+        if (notifyMsg) {
+            IOFree(notifyMsg, sizeof(mach_msg_header_t));
+            notifyMsg = NULL;
+        }
     }
 
     if (_reserved) {
         IOFree (_reserved, sizeof(struct ExpansionData));
         _reserved = NULL;
-    }
+    } 
     
     super::free();
 }
@@ -148,22 +160,22 @@ IODataQueueEntry * IOSharedDataQueue::peek()
     IODataQueueEntry *entry = 0;
 
     if (dataQueue && (dataQueue->head != dataQueue->tail)) {
-        IODataQueueEntry *  head               = 0;
+        IODataQueueEntry *  head        = 0;
         UInt32              headSize    = 0;
         UInt32              headOffset  = dataQueue->head;
         UInt32              queueSize   = getQueueSize();
-
+        
         if (headOffset >= queueSize) {
             return NULL;
         }
         
-        head           = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
-        headSize       = head->size;
+        head         = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
+        headSize     = head->size;
         
-               // Check if there's enough room before the end of the queue for a header.
+        // Check if there's enough room before the end of the queue for a header.
         // If there is room, check if there's enough room to hold the header and
         // the data.
-
+        
         if ((headOffset > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) ||
             (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > queueSize) ||
             (headOffset + DATA_QUEUE_ENTRY_HEADER_SIZE > UINT32_MAX - headSize) ||
@@ -192,7 +204,7 @@ Boolean IOSharedDataQueue::enqueue(void * data, UInt32 dataSize)
         return false;
     }
     // Check for underflow of (getQueueSize() - tail)
-    if (getQueueSize() < tail) {
+    if (getQueueSize() < tail || getQueueSize() < head) {
         return false;
     }
     
@@ -276,17 +288,17 @@ Boolean IOSharedDataQueue::dequeue(void *data, UInt32 *dataSize)
 
     if (dataQueue) {
         if (dataQueue->head != dataQueue->tail) {
-            IODataQueueEntry *  head           = 0;
+            IODataQueueEntry *  head        = 0;
             UInt32              headSize    = 0;
             UInt32              headOffset  = dataQueue->head;
             UInt32              queueSize   = getQueueSize();
-
+            
             if (headOffset > queueSize) {
                 return false;
             }
             
-            head               = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
-            headSize   = head->size;
+            head         = (IODataQueueEntry *)((char *)dataQueue->queue + headOffset);
+            headSize     = head->size;
             
             // we wrapped around to beginning, so read from there
             // either there was not even room for the header
@@ -316,7 +328,7 @@ Boolean IOSharedDataQueue::dequeue(void *data, UInt32 *dataSize)
                 newHeadOffset   = headOffset + entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE;
             }
         }
-
+        
         if (entry) {
             if (data) {
                 if (dataSize) {