Синхрониция потоков

Тема в разделе "WASM.WIN32", создана пользователем JNTT, 1 авг 2005.

  1. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    Помогите, пожалуйста, разобраться.

    Нужно синхронизировать работу дочернего и главного потоков, для этого использую эвенты, и две WaitForSingleObject. Одна из этих функций стоит в обработчике «URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER» запроса(выполняется на уровне dispatch). Трассируя в SoftIce’е обнаружил, что при обработке первого запроса она, как и положено ждет сигнального состояния, но когда ожидание проходит и начинается обработка следующего запроса, на ней при 0 состоянии эвента, почему-то возникает BSOD.
     
  2. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    На DISPATCH_LEVEL нельзя ждать.

    Вот цитата из DDK:



    Callers of KeWaitForSingleObject must be running at IRQL <= DISPATCH_LEVEL. Usually, the caller must be running at IRQL = PASSIVE_LEVEL and in a nonarbitrary thread context. A call while running at IRQL = DISPATCH_LEVEL is valid if and only if the caller specifies a Timeout of zero. That is, a driver must not wait for a nonzero interval at IRQL = DISPATCH_LEVEL.

     
  3. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    " is valid if and only if the caller specifies a Timeout of zero."

    У меня тоже стоит 0. К тому же при первом вызове она ждет как положенно.
     
  4. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    А чего тогда ждем?



    В общем, по описанию проблемы ничего не понять, нужно увидеть код.
     
  5. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    "А чего тогда ждем?"

    Event. Стоит в первоим парамметре KeWaitForSingleObject'а



    "нужно увидеть код"

    Написанный на C++ пойдет?
     
  6. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    Я не понимаю, зачем его ждать при нулевом таймауте.





    А почему бы он не подошел?
     
  7. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    "Я не понимаю, зачем его ждать при нулевом таймауте."

    В книге Солдатова "Прогарммирование драйверов" говорится, что значении Timeout = NULL - это "



    при безусловном (неограниченном)ожидании". Правда здесь под воросом, что,интересно, значит



    "безусловном".



    В главном потоке:

    case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:

    {

    PUCHAR BufferString;



    struct _URB_BULK_OR_INTERRUPT_TRANSFER *pBulkOrInterruptTransfer = (struct



    _URB_BULK_OR_INTERRUPT_TRANSFER *) pUrb;

    //На эту ф-ию можно не обращать вниммания.

    BufferTransfer(devext,

    (PUCHAR) pBulkOrInterruptTransfer->TransferBuffer,

    pBulkOrInterruptTransfer->TransferBufferMDL,

    (ULONG)pBulkOrInterruptTransfer->TransferBufferLength);



    //Запускаю дочерний поток

    KeSetEvent(devext->Event2,IO_NO_INCREMENT,FALSE);



    //Жду пока выполнится цикл в другом потоке.





    KeWaitForSingleObject(devext->Event1,Executive,KernelMode,FALSE,(PLARG E_INTEGER)NULL);



    }

    break;



    В дочернем:



    while(1)

    {



    KeWaitForSingleObject(((PDEVICE_EXTENSION)arg)->Event2,Executive,Kerne lMode,FALSE,0);







    if(((PDEVICE_EXTENSION)arg)->BUFFER ==-1) {

    KeSetEvent((((PDEVICE_EXTENSION)arg)->Event1),IO_NO_INCREMENT,FALSE) ;

    PsTerminateSystemThread(0);

    }

    else WriteLog(((PDEVICE_EXTENSION)arg)->BUFFER,-1);



    //Запускаю главный поток

    KeSetEvent((((PDEVICE_EXTENSION)arg)->Event1),IO_NO_INCREMENT,FALSE) ;



    }





    Тип эвонтов - Synchronization.



    Смысл в том, что нужно чтобы они работали поочередно т.е запускали\останавливали друг друга.
     
  8. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    Это значит, что ожидание может завершиться только когда наступит ожидаемое событие.



    Но Timeout = NULL и нулевой таймаут это совсем разные вещи, первый означает бесконечное ожидание, а второй - нулевой интервал таймаута.



    И если делаешь KeSetEvent, то что у тебя сбрасывает евент? Тогда нужно после ожидания делать KeClearEvent или KeSetEvent заменить на KePulseEvent (не рекомендую).
     
  9. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    <font color="gray][ JNTT</font><!--color--><font color="gray]: В книге Солдатова "Прогарммирование драйверов" говорится, что значении Timeout = NULL - это при безусловном (неограниченном)ожидании". Правда здесь под воросом, что,интересно, значит "безусловном". ]</font><!--color-->



    Добавлю...



    Есть три варианта использования параметра Timeout:

    1. NULL - бесконечное ожидание.

    2. Timeout.QuadPart = -X - ждем X интервалов по 100нс или можно определить абсолютное время.

    3. Timeout.QuadPart = 0 - это и есть нулевой таймаут. Никакого ожидания при этом не происходит. Используется для проверки состояния ожидаемого объекта. Это единственный случай, когда IRQL м.б. = DISPATCH_LEVEL.



    Под "условным" ожиданием Солдатов, видимо, понимает ожидание в тревожном состоянии. Параметр Alertable = TRUE.
     
  10. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    И если делаешь KeSetEvent, то что у тебя сбрасывает евент?

    При типе эвонтов "Synchronization" эту работу проделывет KeWaitxxx.



    "1. NULL - бесконечное ожидание.

    3. Timeout.QuadPart = 0"

    А я совсем и забыл, что парамметр типа PLARGE_INTEGER... )



    "можно определить абсолютное время."

    Что это такое абсолютное время?
     
  11. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Системное
     
  12. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    Извини, не обратил внимания.





    Это значит время, которое функция будет ожидать события.

    Если таймаут истек, то возвращается STATUS_TIMEOUT.



    Все равно на dispatch это тебе ничем не поможет.
     
  13. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    "Все равно на dispatch это тебе ничем не поможет."

    Пожалуй, докой DDK и парой BSOD'ов я в этом хорошо убедился.)



    Если на уровне dispatch нельзя перейти в ожидание, то как же тогда быть? Гонять KeWaitxxx в цикле и проверять возвращаемое значение? Помоему тупо.(
     
  14. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    Если тебе по установке эвента нужно выполнять какие-либо действия, то цепляйся к рабочему потоку (IoAllocateWorkItem/IoQueueWorkItem) и там можешь ждать сколько угодно. Можно поставить APC какому-нибудь другому потоку. Но если тебе обязательно нужно задержать поток на dispatch, то имхо придется обломиться.
     
  15. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    интересно зачем они вообще сделали работу Wait ф-ий при IRQL = DISPATCH_LEVEL, толку от них все равно мало.
     
  16. JNTT

    JNTT New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    17
    Адрес:
    Russia
    А какое мах значение может принять счетчик семафора?