Skip to content

Commit

Permalink
Merge pull request #44 from fluent-plugins-nursery/wait-signal-event-…
Browse files Browse the repository at this point in the history
…correctly

Raise an exception if an event signal notifies a failure state on EvtSubscribe
  • Loading branch information
ashie authored Mar 6, 2024
2 parents 7d3e490 + af6efe9 commit 82d567c
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ruby: [ '2.4', '2.5', '2.6', '2.7', '3.0' ]
ruby: [ '3.0', '3.1', '3.2' ]
os:
- ubuntu-latest
name: Ruby ${{ matrix.ruby }} building fat gem testing on ${{ matrix.os }}
Expand Down
2 changes: 2 additions & 0 deletions ext/winevt/winevt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ VALUE rb_cSubscribe;
VALUE rb_eWinevtQueryError;
VALUE rb_eChannelNotFoundError;
VALUE rb_eRemoteHandlerError;
VALUE rb_eSubscribeHandlerError;

static ID id_call;

Expand All @@ -20,6 +21,7 @@ Init_winevt(void)
rb_eWinevtQueryError = rb_define_class_under(rb_cQuery, "Error", rb_eStandardError);
rb_eChannelNotFoundError = rb_define_class_under(rb_cEventLog, "ChannelNotFoundError", rb_eStandardError);
rb_eRemoteHandlerError = rb_define_class_under(rb_cSubscribe, "RemoteHandlerError", rb_eRuntimeError);
rb_eSubscribeHandlerError = rb_define_class_under(rb_cSubscribe, "SubscribeHandlerError", rb_eRuntimeError);

Init_winevt_channel(rb_cEventLog);
Init_winevt_bookmark(rb_cEventLog);
Expand Down
1 change: 1 addition & 0 deletions ext/winevt/winevt_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ extern VALUE rb_cSubscribe;
extern VALUE rb_eWinevtQueryError;
extern VALUE rb_eChannelNotFoundError;
extern VALUE rb_eRemoteHandlerError;
extern VALUE rb_eSubscribeHandlerError;
extern VALUE rb_cLocale;
extern VALUE rb_cSession;

Expand Down
23 changes: 22 additions & 1 deletion ext/winevt/winevt_subscribe.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self)
struct WinevtSession* winevtSession;
struct WinevtSubscribe* winevtSubscribe;

hSignalEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
hSignalEvent = CreateEvent(NULL, TRUE, TRUE, NULL);

TypedData_Get_Struct(
self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe);
Expand Down Expand Up @@ -341,6 +341,8 @@ rb_winevt_subscribe_next(VALUE self)
EVT_HANDLE hEvents[SUBSCRIBE_ARRAY_SIZE];
ULONG count = 0;
DWORD status = ERROR_SUCCESS;
DWORD dwWait = 0;

struct WinevtSubscribe* winevtSubscribe;

TypedData_Get_Struct(
Expand All @@ -355,6 +357,23 @@ rb_winevt_subscribe_next(VALUE self)
return Qfalse;
}

/* If a signalEvent notifies whether a state of processed event(s)
* is existing or not.
* For checking for a result of WaitForSingleObject,
* we need to raise SubscribeHandlerError exception when
* WAIT_FAILED is detected for further investigations.
* Note that we don't need to wait explicitly here.
* Because this function is inside of each enumerator.
* So, WaitForSingleObject should return immediately and should be
* processed with the latter each loops if there is no more items.
* Just intended to check that there is no errors here. */
dwWait = WaitForSingleObject(winevtSubscribe->signalEvent, 0);
if (dwWait == WAIT_FAILED) {
raise_system_error(rb_eSubscribeHandlerError, GetLastError());
} else if (dwWait != WAIT_OBJECT_0) {
return Qfalse;
}

if (!EvtNext(winevtSubscribe->subscription,
SUBSCRIBE_ARRAY_SIZE,
hEvents,
Expand All @@ -368,6 +387,8 @@ rb_winevt_subscribe_next(VALUE self)
if (ERROR_NO_MORE_ITEMS != status) {
return Qfalse;
}

ResetEvent(winevtSubscribe->signalEvent);
}

if (status == ERROR_SUCCESS) {
Expand Down

0 comments on commit 82d567c

Please sign in to comment.