X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/143464d58d2bd6378e74eec636961ceb0d32fb91..c18c124eaa464aaaa5549e99e5a70fc9cbb50944:/iokit/Kernel/IOSharedDataQueue.cpp diff --git a/iokit/Kernel/IOSharedDataQueue.cpp b/iokit/Kernel/IOSharedDataQueue.cpp index 5eb1c35ed..71daaa6b4 100644 --- a/iokit/Kernel/IOSharedDataQueue.cpp +++ b/iokit/Kernel/IOSharedDataQueue.cpp @@ -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) {