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; if (!setQueueSize(size)) { return false; } appendix = (IODataQueueAppendix *)((UInt8 *)dataQueue + size + DATA_QUEUE_MEMORY_HEADER_SIZE); appendix->version = 0; 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; }
void IOHIDEventQueue::start() { if ( _lock ) IOLockLock(_lock); if ( _state & kHIDQueueStarted ) goto START_END; if ( _currentEntrySize != _maxEntrySize ) { mach_port_t port = notifyMsg ? ((mach_msg_header_t *)notifyMsg)->msgh_remote_port : MACH_PORT_NULL; // Free the existing queue data if (dataQueue) { IOFreeAligned(dataQueue, round_page_32(getQueueSize() + DATA_QUEUE_MEMORY_HEADER_SIZE)); dataQueue = NULL; } if (_descriptor) { _descriptor->release(); _descriptor = 0; } // init the queue again. This will allocate the appropriate data. if ( !initWithEntries(_numEntries, _maxEntrySize) ) { goto START_END; } _currentEntrySize = _maxEntrySize; // RY: since we are initing the queue, we should reset the port as well if ( port ) setNotificationPort(port); } else if ( dataQueue ) { dataQueue->head = 0; dataQueue->tail = 0; } _state |= kHIDQueueStarted; START_END: if ( _lock ) IOLockUnlock(_lock); }