Связывание устройства с портом завершения ввода-вывода
октября 12 2009 by admin in Обязательный материалКогда вы создаете порт завершения ввода-вывода, ядро на самом деле создает пять отдельных структур данных .
Первая структура данных — список устройств, указывающий на одно или несколько устройств, связанных с данным портом. Устройство связывается с портом при вызове CreateloCompletionPort. Здесь я снова создал собственную функцию, AssociateDeviceWithCompletionPort, скрывающую вызов CreateloCompletionPort:
BOOL AssociateDeviceWithCompletionPort(
HANDLE hCompPort, HANDLE hDevice, DWORD dwCompKey) {
HANDLE h = CreateIoCompletionPort(hDevice, hCompPort, dwCompKey, 0);
return(h == hCompPort);
>
AssociateDeviceWithCompletionPon добавляет запись в список устройств порта завершения. Ей передается описатель порта завершения (возвращенного функцией CreateNewCompletionPort), описатель устройства (устройством может быть файл, сокет, почтовый ящик, канал и т. д.) и ключ завершения (это значение используете только вы — ОС все равно, что вы передаете этим параметром). Каждый раз, когда вы связываете устройство с портом, система добавляет эту информацию в список устройств порта завершения.
Я советую вам мысленно разделять две роли CreateloCompletionPort. Использование такой сложной функции достоинств не имеет: уму непостижимо, зачем сразу и создавать порт завершения ввода-вывода, и связывать с ним устройство. Например, в приведенном ниже коде открывается файл и создается новый порт завершения, связывая его с этим файлом. Все запросы ввода-вывода для этого файла будут завершаться с кодом завершения CK_FILE, и порт позволяет использовать два параллельных потока.
«define CK.FILE 1
HANDLE hfile = CreateFile(..,);
HANDLE hCompPort = CreateIoCompletionPort(hfile, NULL, CK.FILE, 2);
Вторая структура данных — очередь завершения ввода-вывода. По завершении запроса асинхронного ввода-вывода система проверяет, имеется ли устройство, связанное с портом завершения, и, если да, добавляет запись завершенного запроса ввода-вывода в конец очереди завершения ввода-вывода данного порта. Каждая запись в очереди указывает число переданных байтов, ключ завершения, установленный при связывании устройства с портом, указатель на структуру OVERLAPPED запроса ввода-вывода и код ошибки. О том, как записи удаляются из очереди, я расскажу чуть позже.