Difference between revisions of "Kernel Event/ru"

From KolibriOS wiki
Jump to navigation Jump to search
(Created page with "Дата последней правки 26/07/2013. Подсистема событий ядра может понадобиться при написании драйвер...")
 
Line 1: Line 1:
Дата последней правки 26/07/2013.
 
 
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
 
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
 
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
 
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
 
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
 
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
  
struc EVENT
+
struc EVENT
{
+
{
  .magic      dd ?    ; 'EVNT'
+
    .magic      dd ?    ; 'EVNT'
  .destroy    dd ?    ; internal destructor
+
    .destroy    dd ?    ; internal destructor
  .fd          dd ?    ; next object in list
+
    .fd          dd ?    ; next object in list
  .bk          dd ?    ; prev object in list
+
    .bk          dd ?    ; prev object in list
  .pid        dd ?    ; owner id. идентификатор владельца (потока)
+
    .pid        dd ?    ; owner id. идентификатор владельца (потока)
  .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
+
    .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
  .state      dd ?    ; internal flags; см. далее.
+
    .state      dd ?    ; internal flags; см. далее.
  .code        dd ?    ; старший байт класс события, ; следующий байт приоритет  
+
    .code        dd ?    ; старший байт класс события, ; следующий байт приоритет  
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
+
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
                        ; Чем больше численное значение двойного слова тем важнее событие.
+
                        ; Чем больше численное значение двойного слова тем важнее событие.
                        ; два младших байта код события.  
+
                        ; два младших байта код события.  
                rd 5    ; .data - точная структура этого поля не определена и зависит
+
                rd 5    ; .data - точная структура этого поля не определена и зависит
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
+
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
                        ; при необходимости :)
+
                        ; при необходимости :)
  .size    =  $ - .magic
+
    .size    =  $ - .magic
  .codesize =  $ - .code
+
    .codesize =  $ - .code
}
+
}
  
 
События реального времени получили класс 0хFF. Пока определёны только:
 
События реального времени получили класс 0хFF. Пока определёны только:
 
EVENT.code= ;(Используется в звуковой подсистеме).
 
EVENT.code= ;(Используется в звуковой подсистеме).
        RT_INP_EMPTY      equ 0xFF000001
+
:RT_INP_EMPTY      equ 0xFF000001
        RT_OUT_EMPTY      equ 0xFF000002
+
:RT_OUT_EMPTY      equ 0xFF000002
        RT_INP_FULL      equ 0xFF000003
+
:RT_INP_FULL      equ 0xFF000003
        RT_OUT_FULL      equ 0xFF000004
+
:RT_OUT_FULL      equ 0xFF000004
  
  
 
Флаги поля EVENT.state определены в gui/event.inc.
 
Флаги поля EVENT.state определены в gui/event.inc.
EVENT_SIGNALED  equ 0x20000000 ;Бит 29  событие активно/неактивно;
+
:EVENT_SIGNALED  equ 0x20000000 ;Бит 29  событие активно/неактивно;
EVENT_WATCHED    equ 0x10000000 ;бит 28, поток-владелец ожидает активации события;
+
:EVENT_WATCHED    equ 0x10000000 ;бит 28, поток-владелец ожидает активации события;
MANUAL_RESET    equ 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
+
:MANUAL_RESET    equ 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
MANUAL_DESTROY  equ 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
+
:MANUAL_DESTROY  equ 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
  
 
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
 
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
 
и выглядит так:
 
и выглядит так:
  
struct  APPOBJ                  ; common object header
+
struct  APPOBJ                  ; common object header
        magic          dd ?    ;
+
        magic          dd ?    ;
        destroy        dd ?    ; internal destructor
+
        destroy        dd ?    ; internal destructor
        fd              dd ?    ; next object in list
+
        fd              dd ?    ; next object in list
        bk              dd ?    ; prev object in list
+
        bk              dd ?    ; prev object in list
        pid            dd ?    ; owner id
+
        pid            dd ?    ; owner id
ends
+
ends
 
+
struct  EVENT          APPOBJ
+
struct  EVENT          APPOBJ
        id              dd ?  ;event uid
+
        id              dd ?  ;event uid
        state          dd ?  ;internal flags
+
        state          dd ?  ;internal flags
        code            dd ?
+
        code            dd ?
                        rd 5  ; .data
+
                        rd 5  ; .data
ends
+
ends
  
 
Код находится в gui/event.inc.
 
Код находится в gui/event.inc.
Line 93: Line 92:
 
(для драйверов и т.п.; вызываются в режиме ядра)
 
(для драйверов и т.п.; вызываются в режиме ядра)
  
        CreateEvent
+
:CreateEvent
        RaiseEvent
+
:RaiseEvent
        ClearEvent
+
:ClearEvent
        SendEvent
+
:SendEvent
        DestroyEvent
+
:DestroyEvent
        WaitEvent
+
:WaitEvent
        WaitEventTimeout
+
:WaitEventTimeout
        GetEvent
+
:GetEvent
        Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
+
:Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
  
 
---------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------
 
===CreateEvent:===
 
===CreateEvent:===
        Создаёт новое событие в очереди ObjList текущего потока.  
+
:Создаёт новое событие в очереди ObjList текущего потока.  
        Устанавливает:
+
:Устанавливает:
                EVENT.destroy  <= внутренний деструктор по умолчанию;
+
::EVENT.destroy  <= внутренний деструктор по умолчанию;
                EVENT.pid      <= текущий Process id;
+
::EVENT.pid      <= текущий Process id;
                EVENT.id        <= уникальный идентификатор;
+
::EVENT.id        <= уникальный идентификатор;
                EVENT.state    <= ecx - флаги;
+
::EVENT.state    <= ecx - флаги;
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
+
::EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
        Возвращает:
+
:Возвращает:
                eax - указатель на событие или 0 при ошибке.
+
::eax - указатель на событие или 0 при ошибке.
                edx - Event.id.
+
::edx - Event.id.
        Портит: eax,ebx,edx,ecx,esi,edi     
+
:Портит: eax,ebx,edx,ecx,esi,edi     
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===RaiseEvent:===
 
===RaiseEvent:===
        Активирует уже существующее событие (может принадлежать другому потоку) установкой  
+
:Активирует уже существующее событие (может принадлежать другому потоку) установкой флага EVENT_SIGNALED.
        флага EVENT_SIGNALED. Если необходимо, -  устанавливает данные EVENT.code.
+
:Если необходимо, -  устанавливает данные EVENT.code.
        Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает.  
+
:Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает.  
        Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
+
:Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
                {EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
+
::{EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
        Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации
+
:Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации события.
        события.
+
:Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
        Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
+
:Принимает:
        Принимает:
+
::eax    - указатель на событие;
                eax    - указатель на событие;
+
::ebx    - id, уникальный идентификатор события;
                ebx    - id, уникальный идентификатор события;
+
::edx    - флаги для операции (формат EVENT.state);
                edx    - флаги для операции (формат EVENT.state);
+
::EVENT.code  <= [esi], (если esi=0, то не копирует), размер 6*dword;
                EVENT.code  <= [esi], (если esi=0, то не копирует), размер 6*dword;
+
:Возвращает: ?
        Возвращает: ?
+
:Портит: eax,ebx,edx,ecx,esi,edi .
        Портит: eax,ebx,edx,ecx,esi,edi .
 
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===ClearEvent:===
 
===ClearEvent:===
        Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
+
:Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
        Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),
+
:Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),ничего не делает.
        ничего не делает.
+
:Принимает:
        Принимает:
+
::eax    - указатель на событие;
                eax    - указатель на событие;
+
::ebx    - id, уникальный идентификатор события.
                ebx    - id, уникальный идентификатор события.
+
:Возвращает: ?
        Возвращает: ?
+
:Портит: eax,ebx,ecx,edi .
        Портит: eax,ebx,ecx,edi .
 
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===SendEvent:===
 
===SendEvent:===
        Создаёт новое событие в списке событий целевого потока. Устанавливает в событии
+
:Создаёт новое событие в списке событий целевого потока. Устанавливает в событии флаг EVENT_SIGNALED.
        флаг EVENT_SIGNALED.
+
:Принимает:
        Принимает:
+
::EVENT.pid      <= eax    - pid, идентификатор целевого потока;
                EVENT.pid      <= eax    - pid, идентификатор целевого потока;
+
::EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
+
:Возвращает:
        Возвращает:
+
::eax - указатель на событие или 0 при ошибке.
                eax - указатель на событие или 0 при ошибке.
+
::edx - Event.id. уникальный идентификатор.
                edx - Event.id. уникальный идентификатор.
+
:Портит: eax,ebx,ecx,esi,edi .
        Портит: eax,ebx,ecx,esi,edi .
 
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===DestroyEvent:===
 
===DestroyEvent:===
        Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
+
:Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
        Событие может принадлежать другому потоку.
+
:Событие может принадлежать другому потоку.
        Принимает:
+
:Принимает:
                eax    - указатель на событие;
+
::eax    - указатель на событие;
                ebx    - id, уникальный идентификатор события.
+
::ebx    - id, уникальный идентификатор события.
        Возвращает:
+
:Возвращает:
                eax    - 0 при ошибке, не 0 при успехе.
+
::eax    - 0 при ошибке, не 0 при успехе.
        Портит: eax,ebx,ecx .
+
:Портит: eax,ebx,ecx .
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===WaitEvent:===
 
===WaitEvent:===
        Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
+
:Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
        вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
+
:вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
        RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
+
:RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
+
:Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
+
:Если в полученном событии НЕ установлен MANUAL_RESET, то:
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
+
::{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
                При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
+
::При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
                а при активном - перемещается в список ObjList текущего слота.}
+
::а при активном - перемещается в список ObjList текущего слота.}
        Принимает:
+
:Принимает:
                eax    - указатель на событие;
+
::eax    - указатель на событие;
                ebx    - id, уникальный идентификатор события.
+
::ebx    - id, уникальный идентификатор события.
        Возвращает: ?
+
:Возвращает: ?
        Портит: eax,ebx,edx,ecx,esi,edi .
+
:Портит: eax,ebx,edx,ecx,esi,edi .
 
---------------------------------------------------------------------------------------------                 
 
---------------------------------------------------------------------------------------------                 
 
===WaitEventTimeout:===
 
===WaitEventTimeout:===
        Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
+
:Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
        вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
+
:вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
        RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
+
:RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
+
:Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
+
:Если в полученном событии НЕ установлен MANUAL_RESET, то:
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
+
::{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
                При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
+
::При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
                а при активном - перемещается в список ObjList текущего слота.}
+
::а при активном - перемещается в список ObjList текущего слота.}
        Принимает:
+
:Принимает:
                eax    - указатель на событие;
+
::eax    - указатель на событие;
                ebx    - id, уникальный идентификатор события.
+
::ebx    - id, уникальный идентификатор события.
                ecx    - время ожидания в тиках системного таймера.
+
::ecx    - время ожидания в тиках системного таймера.
        Возвращает:
+
:Возвращает:
                eax    - 0 - таймаут, если событие не активировалось, или
+
::eax    - 0 - таймаут, если событие не активировалось, или
                          не 0, если было активировано.
+
::::не 0, если было активировано.
        Портит: eax,ebx,edx,ecx,esi,edi .
+
:Портит: eax,ebx,edx,ecx,esi,edi .
 
---------------------------------------------------------------------------------------------         
 
---------------------------------------------------------------------------------------------         
 
===GetEvent:===
 
===GetEvent:===
        Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
+
:Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
        путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
+
:путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
        по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
+
:по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
+
:Если в полученном событии НЕ установлен MANUAL_RESET, то:
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
+
::{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
                При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
+
::При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
                а при активном - перемещается в список ObjList текущего слота.}
+
::а при активном - перемещается в список ObjList текущего слота.}
        Принимает:
+
:Принимает:
                edi    - указатель на буфер, куда копировать данные.
+
::edi    - указатель на буфер, куда копировать данные.
        Возвращает:
+
:Возвращает:
                буфер, содержащий следующую информацию:
+
::буфер, содержащий следующую информацию:
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
+
::+0: (EVENT.code) dword: идентификатор последующих данных сигнала
                +4: (EVENT.data, поле формально не определено) данные принятого  
+
::+4: (EVENT.data, поле формально не определено) данные принятого  
                сигнала (5*dword), формат которых определяется первым dword-ом.     
+
::сигнала (5*dword), формат которых определяется первым dword-ом.     
        Портит: eax,ebx,edx,ecx,esi,edi .
+
:Портит: eax,ebx,edx,ecx,esi,edi .
 
--------------------------------------------------------------------------------------------
 
--------------------------------------------------------------------------------------------
===Ф 68.14 для приложений:===
+
===Ф 68.14 для приложений (это тот же GetEvent, но с обёрткой.): ===
        (это тот же GetEvent, но с обёрткой.)
+
:Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
        Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
+
:замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
        замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
+
:копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
        копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
+
:Принимает:
        Принимает:
+
::eax    - 68 - номер функции
                eax    - 68 - номер функции
+
::ebx    - 14 - номер подфункции
                ebx    - 14 - номер подфункции
+
::ecx    - указатель на буфер для информации (размер 6*dword)
                ecx    - указатель на буфер для информации (размер 6*dword)
+
:Возвращает:
        Возвращает:
+
::буфер, на который указывает ecx, содержит следующую информацию:
                буфер, на который указывает ecx, содержит следующую информацию:
+
::+0: (EVENT.code) dword: идентификатор последующих данных сигнала
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
+
::+4: (EVENT.data, поле формально не определено) данные принятого  
                +4: (EVENT.data, поле формально не определено) данные принятого  
+
::сигнала (5*dword), формат которых определяется первым dword-ом.
                сигнала (5*dword), формат которых определяется первым dword-ом.
+
:Портит:
        Портит:
+
::eax .
                eax .
 
 
---------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------
 +
 +
[[Category:Кодинг]]
 +
[[Category:Системная документация]]

Revision as of 21:49, 7 August 2013

Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра. Она не имеет отношения к подсистеме событий пользовательского интерфейса. С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.

struc EVENT
{
   .magic       dd ?    ; 'EVNT'
   .destroy     dd ?    ; internal destructor
   .fd          dd ?    ; next object in list
   .bk          dd ?    ; prev object in list
   .pid         dd ?    ; owner id. идентификатор владельца (потока)
   .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
   .state       dd ?    ; internal flags; см. далее.
   .code        dd ?    ; старший байт класс события, ; следующий байт приоритет 
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
                        ; Чем больше численное значение двойного слова тем важнее событие.
                        ; два младших байта код события. 
                rd 5    ; .data - точная структура этого поля не определена и зависит
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
                        ; при необходимости :)
   .size     =  $ - .magic
   .codesize =  $ - .code
}

События реального времени получили класс 0хFF. Пока определёны только: EVENT.code= ;(Используется в звуковой подсистеме).

RT_INP_EMPTY equ 0xFF000001
RT_OUT_EMPTY equ 0xFF000002
RT_INP_FULL equ 0xFF000003
RT_OUT_FULL equ 0xFF000004


Флаги поля EVENT.state определены в gui/event.inc.

EVENT_SIGNALED equ 0x20000000 ;Бит 29 событие активно/неактивно;
EVENT_WATCHED equ 0x10000000 ;бит 28, поток-владелец ожидает активации события;
MANUAL_RESET equ 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
MANUAL_DESTROY equ 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.

На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc и выглядит так:

struct  APPOBJ                  ; common object header
        magic           dd ?    ;
        destroy         dd ?    ; internal destructor
        fd              dd ?    ; next object in list
        bk              dd ?    ; prev object in list
        pid             dd ?    ; owner id
ends

struct  EVENT           APPOBJ
        id              dd ?   ;event uid
        state           dd ?   ;internal flags
        code            dd ?
                        rd 5   ; .data
ends

Код находится в gui/event.inc. Сами события как обьекты существуют в памяти ядра в виде двусвязного списка (см. поля .bk и .fd). При инициализации ядро резервирует память и создает 512 таких обьектов, помещая их в список FreeEvents (свободных событий). При нехватке событий (все заняты, а нужно ещё) ядро создает ещё 512 свободных и т.д. Каждый поток имеет свои (двусвязные) списки (в которые может быть помещено событие): ObjList - список объектов ядра, ассоциированных с этим потоком; EventList - список событий ядра для потока. Сами события, физически, при перемещении между списками и смене очередности в списке не перемещаются и не копируются. Это происходит только благодаря модификации полей .fd и .bk. Принцип работы списков, как очередей - FIFO. Использутся неблокирующая отправка и блокирующее получение. Адресация - прямая (у события всегда есть поток-владелец), по идентификатору потока.

Жизненый цикл событий определяется флагами при создании. По умолчанию ядро использует значения MANUAL_RESET = 0 и MANUAL_DESTROY = 0. Такое событие является "одноразовым", и автоматически освобождается ядром, возвращаясь в список свободных событий после получения. Событие с флагом MANUAL_DESTROY = 1 после получения переходит в неактивное состояние, но остаётся в списке объектов потока и может использоваться снова. Событие с флагами MANUAL_DESTROY =1 и MANUAL_RESET = 1 остаётся активным после получения и может быть сброшено вызовом ClearEvent.

Пример (вариант) жизненного цикла события из звуковой подсистемы: Для зукового буфера (их может быть несколько) драйвер создает событие в списке ObjList с помощью CreateEvent и флагом MANUAL_DESTROY. Далее драйвер вызывает WaitEvent для этого события (ожидает флага EVENT_SIGNALED в событии) и блокируется, в ожидании запроса на пополнение буфера. Запрос отправляется с помощью RaiseEvent из другого потока. Отправка (RaiseEvent) и получение (WaitEvent) циклически повторяются при опустошении буфера. При остановке воспроизведения драйвер деактивирует событие с помощью ClearEvent.

Вообще говоря, структура события приведена здесь только лишь для понимания принципов работы подсистемы. Самостоятельная работа с полями не приветствуется, ввиду возможных в будущем проблем с совместимостью. Работа должна производится только через API (функции подсистемы), с доступом только к тем полям, доступ к которым предоставляет функция. При этом пару "указатель на событие" и "уникальный идентификатор события" следует рассматривать как один 64-х битный уникальный идентификатор. (Если вы вызвали CreateEvent, напимер, его нужно запомнить где-нибудь [если это нужно] для дальнейшей работы с событием).

Функции для работы с событиями экспортитуемые ядром:

(для драйверов и т.п.; вызываются в режиме ядра)

CreateEvent
RaiseEvent
ClearEvent
SendEvent
DestroyEvent
WaitEvent
WaitEventTimeout
GetEvent
Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)

CreateEvent:

Создаёт новое событие в очереди ObjList текущего потока.
Устанавливает:
EVENT.destroy <= внутренний деструктор по умолчанию;
EVENT.pid <= текущий Process id;
EVENT.id <= уникальный идентификатор;
EVENT.state <= ecx - флаги;
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
Возвращает:
eax - указатель на событие или 0 при ошибке.
edx - Event.id.
Портит: eax,ebx,edx,ecx,esi,edi

RaiseEvent:

Активирует уже существующее событие (может принадлежать другому потоку) установкой флага EVENT_SIGNALED.
Если необходимо, - устанавливает данные EVENT.code.
Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает.
Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
{EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации события.
Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
Принимает:
eax - указатель на событие;
ebx - id, уникальный идентификатор события;
edx - флаги для операции (формат EVENT.state);
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
Возвращает: ?
Портит: eax,ebx,edx,ecx,esi,edi .

ClearEvent:

Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),ничего не делает.
Принимает:
eax - указатель на событие;
ebx - id, уникальный идентификатор события.
Возвращает: ?
Портит: eax,ebx,ecx,edi .

SendEvent:

Создаёт новое событие в списке событий целевого потока. Устанавливает в событии флаг EVENT_SIGNALED.
Принимает:
EVENT.pid <= eax - pid, идентификатор целевого потока;
EVENT.code <= [esi], (если esi=0, то не копирует), размер 6*dword;
Возвращает:
eax - указатель на событие или 0 при ошибке.
edx - Event.id. уникальный идентификатор.
Портит: eax,ebx,ecx,esi,edi .

DestroyEvent:

Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
Событие может принадлежать другому потоку.
Принимает:
eax - указатель на событие;
ebx - id, уникальный идентификатор события.
Возвращает:
eax - 0 при ошибке, не 0 при успехе.
Портит: eax,ebx,ecx .

WaitEvent:

Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
Если в полученном событии НЕ установлен MANUAL_RESET, то:
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
а при активном - перемещается в список ObjList текущего слота.}
Принимает:
eax - указатель на событие;
ebx - id, уникальный идентификатор события.
Возвращает: ?
Портит: eax,ebx,edx,ecx,esi,edi .

WaitEventTimeout:

Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
RaiseEvent. Ожидающий поток замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5.
Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
Если в полученном событии НЕ установлен MANUAL_RESET, то:
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
а при активном - перемещается в список ObjList текущего слота.}
Принимает:
eax - указатель на событие;
ebx - id, уникальный идентификатор события.
ecx - время ожидания в тиках системного таймера.
Возвращает:
eax - 0 - таймаут, если событие не активировалось, или
не 0, если было активировано.
Портит: eax,ebx,edx,ecx,esi,edi .

GetEvent:

Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
Если в полученном событии НЕ установлен MANUAL_RESET, то:
{EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
При неактивном MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
а при активном - перемещается в список ObjList текущего слота.}
Принимает:
edi - указатель на буфер, куда копировать данные.
Возвращает:
буфер, содержащий следующую информацию:
+0: (EVENT.code) dword: идентификатор последующих данных сигнала
+4: (EVENT.data, поле формально не определено) данные принятого
сигнала (5*dword), формат которых определяется первым dword-ом.
Портит: eax,ebx,edx,ecx,esi,edi .

Ф 68.14 для приложений (это тот же GetEvent, но с обёрткой.):

Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
замораживается путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
Принимает:
eax - 68 - номер функции
ebx - 14 - номер подфункции
ecx - указатель на буфер для информации (размер 6*dword)
Возвращает:
буфер, на который указывает ecx, содержит следующую информацию:
+0: (EVENT.code) dword: идентификатор последующих данных сигнала
+4: (EVENT.data, поле формально не определено) данные принятого
сигнала (5*dword), формат которых определяется первым dword-ом.
Портит:
eax .