Subversion Repositories Kolibri OS

Rev

Rev 9715 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9715 Rev 9932
1
Дата последней правки 26/07/2013.
1
Дата последней правки 26/07/2013.
2
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
2
Подсистема событий ядра может понадобиться при написании драйверов и сервисов, работающих в режиме ядра.
3
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
3
Она не имеет отношения к подсистеме событий пользовательского интерфейса.
4
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
4
С точки зрения ядра событие - объект ядра и принадлежит создавшему его потоку.
5
 
5
 
6
struc EVENT
6
struc EVENT
7
{
7
{
8
   .magic       dd ?    ; 'EVNT'
8
   .magic       dd ?    ; 'EVNT'
9
   .destroy     dd ?    ; internal destructor
9
   .destroy     dd ?    ; internal destructor
10
   .fd          dd ?    ; next object in list
10
   .fd          dd ?    ; next object in list
11
   .bk          dd ?    ; prev object in list
11
   .bk          dd ?    ; prev object in list
12
   .pid         dd ?    ; owner id. идентификатор владельца (потока)
12
   .pid         dd ?    ; owner id. идентификатор владельца (потока)
13
   .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
13
   .id          dd ?    ; event uid. уникальный идентификатор события (просто номерок)
14
   .state       dd ?    ; internal flags; см. далее.
14
   .state       dd ?    ; internal flags; см. далее.
15
   .code        dd ?    ; старший байт класс события, ; следующий байт приоритет 
15
   .code        dd ?    ; старший байт класс события, ; следующий байт приоритет 
16
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
16
                        ; (будет использоваться только внутри ядра, при чтении всегда 0),
17
                        ; Чем больше численное значение двойного слова тем важнее событие.
17
                        ; Чем больше численное значение двойного слова тем важнее событие.
18
                        ; два младших байта код события. 
18
                        ; два младших байта код события. 
19
                rd 5    ; .data - точная структура этого поля не определена и зависит
19
                rd 5    ; .data - точная структура этого поля не определена и зависит
20
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
20
                        ; от поля .code. (Здесь можно передавать какие-то свои данные,
21
                        ; при необходимости :)
21
                        ; при необходимости :)
22
   .size     =  $ - .magic
22
   .size     =  $ - .magic
23
   .codesize =  $ - .code
23
   .codesize =  $ - .code
24
}
24
}
25
 
25
 
26
События реального времени получили класс 0хFF. Пока определёны только:
26
События реального времени получили класс 0хFF. Пока определёны только:
27
EVENT.code= 				;(Используется в звуковой подсистеме).
27
EVENT.code= 				;(Используется в звуковой подсистеме).
28
        RT_INP_EMPTY      = 0xFF000001
28
        RT_INP_EMPTY      = 0xFF000001
29
        RT_OUT_EMPTY      = 0xFF000002
29
        RT_OUT_EMPTY      = 0xFF000002
30
        RT_INP_FULL       = 0xFF000003
30
        RT_INP_FULL       = 0xFF000003
31
        RT_OUT_FULL       = 0xFF000004
31
        RT_OUT_FULL       = 0xFF000004
32
 
32
 
33
 
33
 
34
Флаги поля EVENT.state определены в gui/event.inc.
34
Флаги поля EVENT.state определены в gui/event.inc.
35
	EVENT_SIGNALED   = 0x20000000 ;бит 29  событие активно/неактивно;
35
	EVENT_SIGNALED   = 0x20000000 ;бит 29  событие активно/неактивно;
36
	EVENT_WATCHED    = 0x10000000 ;бит 28, поток-владелец ожидает активации события;
36
	EVENT_WATCHED    = 0x10000000 ;бит 28, поток-владелец ожидает активации события;
37
	MANUAL_RESET     = 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
37
	MANUAL_RESET     = 0x40000000 ;бит 30, не деактивировать событие автоматически по получении;
38
	MANUAL_DESTROY   = 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
38
	MANUAL_DESTROY   = 0x80000000 ;бит 31, не возвращать событие в список свободных по получении.
39
 
39
 
40
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
40
На момент ревизии 3732 (и далее по тексту то же) определение находится в \kernel\trunk\const.inc
41
и выглядит так:
41
и выглядит так:
42
 
42
 
43
struct  APPOBJ                  ; common object header
43
struct  APPOBJ                  ; common object header
44
        magic           dd ?    ;
44
        magic           dd ?    ;
45
        destroy         dd ?    ; internal destructor
45
        destroy         dd ?    ; internal destructor
46
        fd              dd ?    ; next object in list
46
        fd              dd ?    ; next object in list
47
        bk              dd ?    ; prev object in list
47
        bk              dd ?    ; prev object in list
48
        pid             dd ?    ; owner id
48
        pid             dd ?    ; owner id
49
ends
49
ends
50
 
50
 
51
struct  EVENT           APPOBJ
51
struct  EVENT           APPOBJ
52
        id              dd ?   ;event uid
52
        id              dd ?   ;event uid
53
        state           dd ?   ;internal flags
53
        state           dd ?   ;internal flags
54
        code            dd ?
54
        code            dd ?
55
                        rd 5   ; .data
55
                        rd 5   ; .data
56
ends
56
ends
57
 
57
 
58
Код находится в gui/event.inc.
58
Код находится в gui/event.inc.
59
Сами события как обьекты существуют в памяти ядра в виде двусвязного списка (см. поля .bk и .fd).
59
Сами события как обьекты существуют в памяти ядра в виде двусвязного списка (см. поля .bk и .fd).
60
При инициализации ядро резервирует память и создает 512 таких обьектов, помещая их в список FreeEvents
60
При инициализации ядро резервирует память и создает 512 таких обьектов, помещая их в список FreeEvents
61
(свободных событий). При нехватке событий (все заняты, а нужно ещё) ядро создает ещё 512 свободных
61
(свободных событий). При нехватке событий (все заняты, а нужно ещё) ядро создает ещё 512 свободных
62
и т.д. Каждый поток имеет свои (двусвязные) списки (в которые может быть помещено событие):
62
и т.д. Каждый поток имеет свои (двусвязные) списки (в которые может быть помещено событие):
63
ObjList - список объектов ядра, ассоциированных с этим потоком; 
63
ObjList - список объектов ядра, ассоциированных с этим потоком; 
64
EventList - список событий ядра для потока.
64
EventList - список событий ядра для потока.
65
Сами события, физически, при перемещении между списками и смене очередности в списке не перемещаются
65
Сами события, физически, при перемещении между списками и смене очередности в списке не перемещаются
66
и не копируются. Это происходит только благодаря модификации полей .fd и .bk. Принцип работы списков,
66
и не копируются. Это происходит только благодаря модификации полей .fd и .bk. Принцип работы списков,
67
как очередей - FIFO. Использутся неблокирующая отправка и блокирующее получение. Адресация - прямая
67
как очередей - FIFO. Использутся неблокирующая отправка и блокирующее получение. Адресация - прямая
68
(у события всегда есть поток-владелец), по идентификатору потока. 
68
(у события всегда есть поток-владелец), по идентификатору потока. 
69
 
69
 
70
Жизненый цикл событий определяется флагами при создании. По умолчанию ядро использует значения 
70
Жизненый цикл событий определяется флагами при создании. По умолчанию ядро использует значения 
71
MANUAL_RESET = 0 и MANUAL_DESTROY = 0. Такое событие является "одноразовым", и автоматически освобождается 
71
MANUAL_RESET = 0 и MANUAL_DESTROY = 0. Такое событие является "одноразовым", и автоматически освобождается 
72
ядром, возвращаясь в список свободных событий после получения.
72
ядром, возвращаясь в список свободных событий после получения.
73
Событие с флагом MANUAL_DESTROY = 1 после получения переходит в неактивное состояние, но остаётся в списке 
73
Событие с флагом MANUAL_DESTROY = 1 после получения переходит в неактивное состояние, но остаётся в списке 
74
объектов потока и может использоваться снова. Событие с флагами MANUAL_DESTROY = 1 и MANUAL_RESET = 1 
74
объектов потока и может использоваться снова. Событие с флагами MANUAL_DESTROY = 1 и MANUAL_RESET = 1 
75
остаётся активным после получения и может быть сброшено вызовом ClearEvent.
75
остаётся активным после получения и может быть сброшено вызовом ClearEvent.
76
 
76
 
77
Пример (вариант) жизненного цикла события из звуковой подсистемы:
77
Пример (вариант) жизненного цикла события из звуковой подсистемы:
78
Для зукового буфера (их может быть несколько) драйвер создает событие в списке ObjList с помощью
78
Для зукового буфера (их может быть несколько) драйвер создает событие в списке ObjList с помощью
79
CreateEvent и флагом MANUAL_DESTROY. Далее драйвер вызывает WaitEvent для этого события (ожидает флага
79
CreateEvent и флагом MANUAL_DESTROY. Далее драйвер вызывает WaitEvent для этого события (ожидает флага
80
EVENT_SIGNALED в событии) и блокируется, в ожидании запроса на пополнение буфера. Запрос отправляется
80
EVENT_SIGNALED в событии) и блокируется, в ожидании запроса на пополнение буфера. Запрос отправляется
81
с помощью RaiseEvent из другого потока. Отправка (RaiseEvent) и получение (WaitEvent) циклически 
81
с помощью RaiseEvent из другого потока. Отправка (RaiseEvent) и получение (WaitEvent) циклически 
82
повторяются при опустошении буфера. При остановке воспроизведения драйвер деактивирует событие с помощью
82
повторяются при опустошении буфера. При остановке воспроизведения драйвер деактивирует событие с помощью
83
ClearEvent.
83
ClearEvent.
84
 
84
 
85
Вообще говоря, структура события приведена здесь только лишь для понимания принципов работы подсистемы.
85
Вообще говоря, структура события приведена здесь только лишь для понимания принципов работы подсистемы.
86
Самостоятельная работа с полями не приветствуется, ввиду возможных в будущем проблем с совместимостью.
86
Самостоятельная работа с полями не приветствуется, ввиду возможных в будущем проблем с совместимостью.
87
Работа должна производится только через API (функции подсистемы), с доступом только к тем полям, доступ к
87
Работа должна производится только через API (функции подсистемы), с доступом только к тем полям, доступ к
88
которым предоставляет функция. При этом пару "указатель на событие" и "уникальный идентификатор события"
88
которым предоставляет функция. При этом пару "указатель на событие" и "уникальный идентификатор события"
89
следует рассматривать как один 64-х битный уникальный идентификатор. (Если вы вызвали CreateEvent, напимер,
89
следует рассматривать как один 64-х битный уникальный идентификатор. (Если вы вызвали CreateEvent, напимер,
90
его нужно запомнить где-нибудь [если это нужно] для дальнейшей работы с событием).
90
его нужно запомнить где-нибудь [если это нужно] для дальнейшей работы с событием).
91
 
91
 
92
Функции для работы с событиями экспортитуемые ядром:
92
Функции для работы с событиями экспортитуемые ядром:
93
(для драйверов и т.п.; вызываются в режиме ядра)
93
(для драйверов и т.п.; вызываются в режиме ядра)
94
 
94
 
95
        CreateEvent
95
        CreateEvent
96
        RaiseEvent
96
        RaiseEvent
97
        ClearEvent
97
        ClearEvent
98
        SendEvent
98
        SendEvent
99
        DestroyEvent
99
        DestroyEvent
100
        WaitEvent
100
        WaitEvent
101
        WaitEventTimeout
101
        WaitEventTimeout
102
        GetEvent
102
        GetEvent
103
        Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
103
        Для пользовательских приложений Ф68.14 (GetEvent с обёрткой)
104
 
104
 
105
---------------------------------------------------------------------------------------------
105
---------------------------------------------------------------------------------------------
106
CreateEvent:
106
CreateEvent:
107
        Создаёт новое событие в очереди ObjList текущего потока. 
107
        Создаёт новое событие в очереди ObjList текущего потока. 
108
        Устанавливает:
108
        Устанавливает:
109
                EVENT.destroy   <= внутренний деструктор по умолчанию;
109
                EVENT.destroy   <= внутренний деструктор по умолчанию;
110
                EVENT.pid       <= текущий Process id;
110
                EVENT.pid       <= текущий Process id;
111
                EVENT.id        <= уникальный идентификатор;
111
                EVENT.id        <= уникальный идентификатор;
112
                EVENT.state     <= ecx - флаги;
112
                EVENT.state     <= ecx - флаги;
113
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
113
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
114
        Возвращает:
114
        Возвращает:
115
                eax - указатель на событие или 0 при ошибке.
115
                eax - указатель на событие или 0 при ошибке.
116
                edx - Event.id.
116
                edx - Event.id.
117
        Портит: eax,ebx,edx,ecx,esi,edi     
117
        Портит: eax,ebx,edx,ecx,esi,edi     
118
---------------------------------------------------------------------------------------------        
118
---------------------------------------------------------------------------------------------        
119
RaiseEvent:
119
RaiseEvent:
120
        Активирует уже существующее событие (может принадлежать другому потоку) установкой 
120
        Активирует уже существующее событие (может принадлежать другому потоку) установкой 
121
        флага EVENT_SIGNALED. Если необходимо, -  устанавливает данные EVENT.code.
121
        флага EVENT_SIGNALED. Если необходимо, -  устанавливает данные EVENT.code.
122
        Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает. 
122
        Если флаг EVENT_SIGNALED в самом событии уже активен - больше ничего не делает. 
123
        Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
123
        Если EVENT_SIGNALED не установлен в самом событии, то он будет установлен, кроме случая
124
                {EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
124
                {EVENT_WATCHED в edx=1 и EVENT_WATCHED в событии=0}.
125
        Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации
125
        Т.е. при установке EVENT_WATCHED в edx, проверяется, ожидает ли поток-владелец активации
126
        события.
126
        события.
127
        Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
127
        Кроме EVENT_SIGNALED в событии никакие другие флаги не модифицируются.
128
        Принимает:
128
        Принимает:
129
                eax     - указатель на событие;
129
                eax     - указатель на событие;
130
                ebx     - id, уникальный идентификатор события;
130
                ebx     - id, уникальный идентификатор события;
131
                edx     - флаги для операции (формат EVENT.state);
131
                edx     - флаги для операции (формат EVENT.state);
132
                EVENT.code  <= [esi], (если esi=0, то не копирует), размер 6*dword;
132
                EVENT.code  <= [esi], (если esi=0, то не копирует), размер 6*dword;
133
        Возвращает: ?
133
        Возвращает: ?
134
        Портит: eax,ebx,edx,ecx,esi,edi .
134
        Портит: eax,ebx,edx,ecx,esi,edi .
135
---------------------------------------------------------------------------------------------        
135
---------------------------------------------------------------------------------------------        
136
ClearEvent:
136
ClearEvent:
137
        Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
137
        Перемещает событие в список ObjList потока-владельца. (Возможно оно там и находилось.)
138
        Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),
138
        Сбрасывает флаги EVENT_SIGNALED, EVENT_WATCHED. С остальными полями (.code, .id),
139
        ничего не делает.
139
        ничего не делает.
140
        Принимает:
140
        Принимает:
141
                eax     - указатель на событие;
141
                eax     - указатель на событие;
142
                ebx     - id, уникальный идентификатор события.
142
                ebx     - id, уникальный идентификатор события.
143
        Возвращает: ?
143
        Возвращает: ?
144
        Портит: eax,ebx,ecx,edi .
144
        Портит: eax,ebx,ecx,edi .
145
---------------------------------------------------------------------------------------------        
145
---------------------------------------------------------------------------------------------        
146
SendEvent:
146
SendEvent:
147
        Создаёт новое событие в списке событий целевого потока. Устанавливает в событии
147
        Создаёт новое событие в списке событий целевого потока. Устанавливает в событии
148
        флаг EVENT_SIGNALED.
148
        флаг EVENT_SIGNALED.
149
        Принимает:
149
        Принимает:
150
                EVENT.pid       <= eax     - pid, идентификатор целевого потока;
150
                EVENT.pid       <= eax     - pid, идентификатор целевого потока;
151
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
151
                EVENT.code      <= [esi], (если esi=0, то не копирует), размер 6*dword;
152
        Возвращает:
152
        Возвращает:
153
                eax - указатель на событие или 0 при ошибке.
153
                eax - указатель на событие или 0 при ошибке.
154
                edx - Event.id. уникальный идентификатор.
154
                edx - Event.id. уникальный идентификатор.
155
        Портит: eax,ebx,ecx,esi,edi .
155
        Портит: eax,ebx,ecx,esi,edi .
156
---------------------------------------------------------------------------------------------        
156
---------------------------------------------------------------------------------------------        
157
DestroyEvent:
157
DestroyEvent:
158
        Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
158
        Переносит EVENT в список FreeEvents, чистит поля .magic,.destroy,.pid,.id.
159
        Событие может принадлежать другому потоку.
159
        Событие может принадлежать другому потоку.
160
        Принимает:
160
        Принимает:
161
                eax     - указатель на событие;
161
                eax     - указатель на событие;
162
                ebx     - id, уникальный идентификатор события.
162
                ebx     - id, уникальный идентификатор события.
163
        Возвращает:
163
        Возвращает:
164
                eax     - 0 при ошибке, не 0 при успехе.
164
                eax     - 0 при ошибке, не 0 при успехе.
165
        Портит: eax,ebx,ecx .
165
        Портит: eax,ebx,ecx .
166
---------------------------------------------------------------------------------------------        
166
---------------------------------------------------------------------------------------------        
167
WaitEvent:
167
WaitEvent:
168
        Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
168
        Бесконечно ожидает установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
169
        вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
169
        вызывающему WaitEvent потоку. Сигнализирующий поток устанавливат этот флаг через
170
        RaiseEvent. Ожидающий поток замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5.
170
        RaiseEvent. Ожидающий поток замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5.
171
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
171
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
172
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
172
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
173
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
173
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
174
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
174
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
175
                 а при активном - перемещается в список ObjList текущего слота.}
175
                 а при активном - перемещается в список ObjList текущего слота.}
176
        Принимает:
176
        Принимает:
177
                eax     - указатель на событие;
177
                eax     - указатель на событие;
178
                ebx     - id, уникальный идентификатор события.
178
                ebx     - id, уникальный идентификатор события.
179
        Возвращает: ?
179
        Возвращает: ?
180
        Портит: eax,ebx,edx,ecx,esi,edi .
180
        Портит: eax,ebx,edx,ecx,esi,edi .
181
---------------------------------------------------------------------------------------------                
181
---------------------------------------------------------------------------------------------                
182
WaitEventTimeout:
182
WaitEventTimeout:
183
        Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
183
        Ожидает с таймаутом установки флага EVENT_SIGNALED в конкретном событии, принадлежащем
184
        вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
184
        вызывающему WaitEventTimeout потоку. Сигнализирующий поток устанавливат этот флаг через
185
        RaiseEvent. Ожидающий поток замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5.
185
        RaiseEvent. Ожидающий поток замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5.
186
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
186
        Перед заморозкой устанавливается флаг EVENT_WATCHED в событии.
187
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
187
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
188
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
188
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
189
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
189
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
190
                 а при активном - перемещается в список ObjList текущего слота.}
190
                 а при активном - перемещается в список ObjList текущего слота.}
191
        Принимает:
191
        Принимает:
192
                eax     - указатель на событие;
192
                eax     - указатель на событие;
193
                ebx     - id, уникальный идентификатор события.
193
                ebx     - id, уникальный идентификатор события.
194
                ecx     - время ожидания в тиках системного таймера.
194
                ecx     - время ожидания в тиках системного таймера.
195
        Возвращает:
195
        Возвращает:
196
                eax     - 0 - таймаут, если событие не активировалось, или
196
                eax     - 0 - таймаут, если событие не активировалось, или
197
                          не 0, если было активировано.
197
                          не 0, если было активировано.
198
        Портит: eax,ebx,edx,ecx,esi,edi .
198
        Портит: eax,ebx,edx,ecx,esi,edi .
199
---------------------------------------------------------------------------------------------        
199
---------------------------------------------------------------------------------------------        
200
GetEvent:
200
GetEvent:
201
        Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
201
        Бесконечно ожидает любое событие в очереди событий текущего потока. Поток замораживается
202
        путем перевода TASKDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
202
        путем перевода APPDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
203
        по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
203
        по получении копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
204
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
204
        Если в полученном событии НЕ установлен MANUAL_RESET, то:
205
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
205
                {EVENT_SIGNALED и EVENT_WATCHED по получении события сбрасываются.
206
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
206
                 При неактивном  MANUAL_DESTROY - событие уничтожается штатно (DestroyEvent),
207
                 а при активном - перемещается в список ObjList текущего слота.}
207
                 а при активном - перемещается в список ObjList текущего слота.}
208
        Принимает:
208
        Принимает:
209
                edi     - указатель на буфер, куда копировать данные.
209
                edi     - указатель на буфер, куда копировать данные.
210
        Возвращает:
210
        Возвращает:
211
                буфер, содержащий следующую информацию:
211
                буфер, содержащий следующую информацию:
212
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
212
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
213
                +4: (EVENT.data, поле формально не определено) данные принятого 
213
                +4: (EVENT.data, поле формально не определено) данные принятого 
214
                сигнала (5*dword), формат которых определяется первым dword-ом.     
214
                сигнала (5*dword), формат которых определяется первым dword-ом.     
215
        Портит: eax,ebx,edx,ecx,esi,edi .
215
        Портит: eax,ebx,edx,ecx,esi,edi .
216
--------------------------------------------------------------------------------------------
216
--------------------------------------------------------------------------------------------
217
Ф 68.14 для приложений:         ;это тот же GetEvent, но с обёрткой.
217
Ф 68.14 для приложений:         ;это тот же GetEvent, но с обёрткой.
218
        Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
218
        Бесконечно ожидает любое событие в очереди событий текущего потока. Ожидающий поток
219
        замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
219
        замораживается путем перевода APPDATA.state<=TSTATE_WAITING=5. Данные события (EVENT.code+5*dword)
220
        копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
220
        копируются в указанный буфер. Сбрасывает байт приоритета (см. выше) в буфере.
221
        Принимает:
221
        Принимает:
222
                eax     - 68 - номер функции
222
                eax     - 68 - номер функции
223
                ebx     - 14 - номер подфункции
223
                ebx     - 14 - номер подфункции
224
                ecx     - указатель на буфер для информации (размер 6*dword)
224
                ecx     - указатель на буфер для информации (размер 6*dword)
225
        Возвращает:
225
        Возвращает:
226
                буфер, на который указывает ecx, содержит следующую информацию:
226
                буфер, на который указывает ecx, содержит следующую информацию:
227
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
227
                +0: (EVENT.code) dword: идентификатор последующих данных сигнала
228
                +4: (EVENT.data, поле формально не определено) данные принятого 
228
                +4: (EVENT.data, поле формально не определено) данные принятого 
229
                сигнала (5*dword), формат которых определяется первым dword-ом.
229
                сигнала (5*dword), формат которых определяется первым dword-ом.
230
        Портит:
230
        Портит:
231
                eax .
231
                eax .
232
---------------------------------------------------------------------------------------------
232
---------------------------------------------------------------------------------------------
233
>
233
>
234
>
234
>