Skip to content

make_event_watcher requires the event handle have EVENT_MODIFY_STATE #482

Open
@jonwis

Description

Consider this:

struct event_and_watcher {
    wil::unique_event eventName;
    wil::unique_event_watcher watcher;
};
event_and_watcher make_event_watcher(wchar_t const* name, void (*pfn)()) {
    event_and_watcher retval;
    if (retval.eventName.try_open(name, SYNCHRONIZE)) {
        retval.watcher = wil::make_event_watcher(retval.eventName.get(), pfn);
    }
    return retval;
}
auto g_w = make_event_watcher(L"AnotherEventName", [] { ReactToEvent(); });

When the event is signaled and the TP wait callback is invoked here:

wil/include/wil/resource.h

Lines 3915 to 3924 in 6f60a1b

static void CALLBACK wait_callback(PTP_CALLBACK_INSTANCE, void* context, TP_WAIT* pThreadPoolWait, TP_WAIT_RESULT)
{
auto pThis = static_cast<details::event_watcher_state*>(context);
// Manual events must be re-set to avoid missing the last notification.
pThis->m_event.ResetEvent();
// Call the client before re-arming to ensure that multiple callbacks don't
// run concurrently.
pThis->m_callback();
SetThreadpoolWait(pThreadPoolWait, pThis->m_event.get(), nullptr); // valid params ensure success
}

... the ResetEvent fails with a failfast:

wil/include/wil/resource.h

Lines 2502 to 2505 in 6f60a1b

inline void __stdcall ResetEvent(HANDLE h) WI_NOEXCEPT
{
__FAIL_FAST_ASSERT_WIN32_BOOL_FALSE__(::ResetEvent(h));
}

... because I don't have Reset rights, only Synchronize.

Consider a policy flag to make that Reset optional.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    feature-requestNew feature or requestimprovementSomething that would improve the repo in some way

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions