KeWaitForSingleObject

Тема в разделе "WASM.WIN32", создана пользователем cresta, 17 фев 2006.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Запускаю в цикле некоторое количество раз поток ThreadProc. С условием прекращения ожидания окончания работы потока по истечение некоторого времени.
    Код (Text):
    1.  
    2. void ThreadProc( PVOID lParam){
    3.    
    4.     ...
    5.     ...
    6.     PsTerminateSystemThread (STATUS_SUCCESS);
    7. }
    8. //---------------------------------------------------------
    9.  
    10.     if (STATUS_SUCCESS == PsCreateSystemThread (&hThread, THREAD_ALL_ACCESS, &oAttr,
    11.                                             NtCurrentProcess(), NULL, ThreadProc, &lParam)){
    12.         ObReferenceObjectByHandle (hThread, THREAD_ALL_ACCESS, NULL, KernelMode, &pkThread, NULL);
    13.         ZwClose (hThread);
    14.         Timeout.HighPart = -1;
    15.         Timeout.LowPart = 100000;
    16.         if (STATUS_SUCCESS  == KeWaitForSingleObject (pkThread, Executive, KernelMode, FALSE, &Timeout)){
    17.             result = TRUE;
    18.             DbgPrint("Success");
    19.         }
    20.     }
    21.  


    Собственно потоки стартуют, отрабатывают, но часть потоков не завершается, и программа, запустившая поток, зависает.

    Насколько правильно тут используется KeWaitForSingleObject? Или причина зависания не в KeWaitForSingleObject?
     
  2. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    Как-то для меня немного странно инициализируется Timeout... Может, он на самом деле сильно большой получается при такой инициализации?

    Я обычно пишу

    LARGE_INTEGER TimeOut;

    TimeOut.QuadPart = -50; \\5 MicroSec
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Инициализирую по аналогии с тем, как делается для таймера. Может надо другие величины? Сейчас попробую с QuardPart (надо перегрузиться, а то не отцепиться никак от драйвера :)
     
  4. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    У меня такая же хрень бывала:) Хоть не БСОД:)

    Если я не ошибаюсь, такая херня(когда весится запускающее драйвер приложение, но не система) у меня получалась когда я пытался ждать в DispatchClose routine окончания потока. Кажется, если я писал типа while(!pDE->ThreadTerminated);, то висла вся система, а если использовал событие, то висла только вызывающая программа. Теперь я юзаю while(!pDE->ThreadTerminated); "текник" в DriverUnload routine и все нормально работает.
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Частично проблема решается с QuadPart = -100000.

    Вызывающая прога перестает виснуть после DeviceIoControl, но драйвер остается в невменяемом состоянии - ни остановить, ни другие коды ему послать. Только перезагрузка :dntknw:

    Пробовал ZwTerminateThread для зависших потоков - тут другой капкан: необходимо линковать ntdll к драйверу во избежание unresolved external, а с прилинкованой ntdll драйвер не стартует вообще :dntknw:
     
  6. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    ...Если ты используешь PsTerminateSystemThread, то, как я понимаю, поток ядерный, следовательно, его никак нельзя насильно остановить.



    Вот фрагмент из w2kdriverbook по этому поводу:



    When a driver unloads, it must ensure that any system thread it may have created has terminated. System threads must terminate themselves, using PsTerminateSystemThread, described in Table 14.2. Unlike Win32 user-mode threads, there is no way to forcibly terminate a system thread. This means that some kind of signaling mechanism needs to be set up to let a thread know it should exit. As discussed later in this chapter, Event objects provide a convenient mechanism for this.



    Короче: так или иначе Ты должен дождаться когда все треды поконячат собой. И поэтому конечный таймаут тут никак не может решить проблему. По-моему, это в самих тредах дело...
     
  7. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    В доке чётко написано, про то, что для относительного таймаута он должен быть отрицательным. В аттаче хидер, юзать примерно так:
    Код (Text):
    1. Timeout.QuadPart = -SECONDS_ONE;




    ZwTerminateThread не поможет, т.к. ядерные потоки сами себя завершают. В доке, кажется, чётко сказано.



    Линковаться с ntdll, как и с любой другой юзермодной библиотекой - забей!



    [​IMG] _684132569__TimeIntervals.rar
     
  8. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Значит, надо переносить код в юзер.

    Спасибо всем.
     
  9. ubil

    ubil New Member

    Публикаций:
    0
    Регистрация:
    7 ноя 2004
    Сообщения:
    203
    Адрес:
    ODESSA:)
    Вот те и на... Получается, если писА:)л Timeout.QuadPart = -50 - это не 5 микросекунд что ли??? А, не, гоню... Там значок *, а не какая-нибудь запятая, как мне показалось:)

    в DDK еще более просто написано:

    Timeout

    Pointer to a time-out value that specifies the absolute or relative time at which the wait is to be completed (optional). A negative value specifies an interval relative to the current time. The value should be expressed in units of 100 nanoseconds. Absolute expiration times track any changes in the system time; relative expiration times are not affected by system time changes.