Re[3]: Completion Port + KeInsertQueue + управление очередью
От: abdul.zycor  
Дата: 26.01.09 23:29
Оценка:
У меня снова вопрос по этой же теме.
Допустим такая ситуация, как я описал выше.
Да рабочие потоки после возврата управления из GetQueuedCompletionStatus делают что-то типа
                        if(GetQueuedCompletionStatus(ThreadPool->CompletionPort, &NumberOfBytes, (PULONG_PTR)&WorkItem, (LPOVERLAPPED *)&Overlapped, INFINITE)) {
                        //проверка флага окончания работы рабочего потока
            if ( InterlockedCompareExchange(&ThreadPool->fDestroyCalled, 1, 1) ) {
                status = ERROR_SUCCESS;
                break;
            }

т.е. на данные WorkItem они забивают и прекрастно завершаются досрочно, прекращая выбирать данные из очереди, но очередь не пуста ведь остается.

Но ставим в очередь мы данные, выделяется ведь память нами именно для переменной object, в которой скажем описается запрос какие данные для него там есть.
                if ( !PostQueuedCompletionStatus(ThreadPool->CompletionPort, 0, (ULONG_PTR)object, NULL) ) {
            status = CALL(GetLastError)();
            break;    
        }


Т.е. вопрос звучит так — кто будет освобождать эту память, если скажем процесс не будет завершаться, это была так сказать реинициализация?
Самое простое это вести список где будет содержаться указатели на участки выделенной нами памяти, а по досрочному завершению освобождать это дело, но это ведь велосипед какой-то.
Я вижу два варианта:
1. Делать свою реализацию очереди, в качестве которой и используется Completion Port
2. Применять пулы памяти, например как в библиотеке APR (http://apr.apache.org/docs/apr/1.3/group__apr__pools.html)
т.е. память для object выделяется из пула, при реинициализации модуля/класса пул дестроиться, при дестрое пула, освобождается память пула

Короче прошу помощи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.