KeCancelTimer

Does KeCancelTimer() set the timer to a signaled state? The documentation is not clear on this. It says it dequeues the timer. I assume it also signals the timer.

xxxxx@gmail.com wrote:

Does KeCancelTimer() set the timer to a signaled state? The documentation is not clear on this. It says it dequeues the timer. I assume it also signals the timer.

I guess I would not expect it to do so. If you cancel the timer, you
are saying “I no longer want this timer to do anything”. You are saying
you do NOT want the normal timer expiration activity to happen. If you
do need it, you need to do it after you cancel.

The ReactOS source isn’t always an accurate reflection of the NT source,
but the semantics are usually very close. The ReactOS implementation
does not signal the timer on cancel. It only gets signaled when it expires.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hmmm… that would leave a thread waiting on the timer object in a dubious
state. Not that this is the typical use case, but still something should
happen.

Mark Roddy

On Tue, Jul 18, 2017 at 3:42 PM, Tim Roberts <
xxxxx@lists.osr.com> wrote:

> xxxxx@gmail.com wrote:
> > Does KeCancelTimer() set the timer to a signaled state? The
> documentation is not clear on this. It says it dequeues the timer. I assume
> it also signals the timer.
>
> I guess I would not expect it to do so. If you cancel the timer, you
> are saying “I no longer want this timer to do anything”. You are saying
> you do NOT want the normal timer expiration activity to happen. If you
> do need it, you need to do it after you cancel.
>
> The ReactOS source isn’t always an accurate reflection of the NT source,
> but the semantics are usually very close. The ReactOS implementation
> does not signal the timer on cancel. It only gets signaled when it
> expires.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

Mark Roddy wrote:

Hmmm… that would leave a thread waiting on the timer object in a
dubious state. Not that this is the typical use case, but still
something should happen.

If you intend to cancel the timer, then you’d better have another way to
unblock that thread before you free the timer’s memory. In that
respect, it’s not that different from a KEVENT. If it’s possible for
the event to end its usefulness without having been signaled, then any
time you wait on the event, you’d better wait on something else, too.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

In UM, WAIT_ABANDONED covers this case, but in KM clearly not.

As you say, if you are going to deallocate the memory for the event structure, you need to ensure that the other thread(s) both are not waiting on it any more, and also can?t touch the pointer again. A simple signal during cancel cannot ensure this, so it is kind of irrelevant whether the signal is sent or not

Sent from Mailhttps: for Windows 10

From: Tim Robertsmailto:xxxxx
Sent: July 18, 2017 6:00 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] KeCancelTimer

Mark Roddy wrote:
>
> Hmmm… that would leave a thread waiting on the timer object in a
> dubious state. Not that this is the typical use case, but still
> something should happen.

If you intend to cancel the timer, then you’d better have another way to
unblock that thread before you free the timer’s memory. In that
respect, it’s not that different from a KEVENT. If it’s possible for
the event to end its usefulness without having been signaled, then any
time you wait on the event, you’d better wait on something else, too.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx></https:>

I am working on a device cache idea. My idea is to do a
KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
all semantics. So, I have a cache that will flush every n seconds if 1) the
timer has expired, and 2) the event indicating work is set. If both are not
true, then the wait continues until both are. Now, when I get an
IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
to cause both conditions to be true.

Alas, i’ll work on another mechanism. I’ve found very little use for wait
all semantics.

– Jamey

On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
xxxxx@lists.osr.com> wrote:

> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>
>
>
> As you say, if you are going to deallocate the memory for the event
> structure, you need to ensure that the other thread(s) both are not waiting
> on it any more, and also can’t touch the pointer again. A simple signal
> during cancel cannot ensure this, so it is kind of irrelevant whether the
> signal is sent or not
>
>
>
> Sent from Mail https: for
> Windows 10
>
>
>
> *From: *Tim Roberts
> *Sent: *July 18, 2017 6:00 PM
> *To: *Windows System Software Devs Interest List
> *Subject: *Re: [ntdev] KeCancelTimer
>
>
>
> Mark Roddy wrote:
> >
> > Hmmm… that would leave a thread waiting on the timer object in a
> > dubious state. Not that this is the typical use case, but still
> > something should happen.
>
> If you intend to cancel the timer, then you’d better have another way to
> unblock that thread before you free the timer’s memory. In that
> respect, it’s not that different from a KEVENT. If it’s possible for
> the event to end its usefulness without having been signaled, then any
> time you wait on the event, you’d better wait on something else, too.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></https:>

Canceling a timer is not the same thing as deallocating memory for the
timer. There is KeInitializeTimer(), KeSetTimer(), and KeCancelTimer().
KeCancelTimer() is not semantically a destructor. Can you call KeSetTimer()
with another value while it is being waited on? Maybe this is the solution;
set the timer to 0?

On Tue, Jul 18, 2017 at 8:30 PM Jamey Kirby wrote:

> I am working on a device cache idea. My idea is to do a
> KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
> all semantics. So, I have a cache that will flush every n seconds if 1) the
> timer has expired, and 2) the event indicating work is set. If both are not
> true, then the wait continues until both are. Now, when I get an
> IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
> to cause both conditions to be true.
>
> Alas, i’ll work on another mechanism. I’ve found very little use for wait
> all semantics.
>
>
> – Jamey
>
>
> On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
> xxxxx@lists.osr.com> wrote:
>
>> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>>
>>
>>
>> As you say, if you are going to deallocate the memory for the event
>> structure, you need to ensure that the other thread(s) both are not waiting
>> on it any more, and also can’t touch the pointer again. A simple signal
>> during cancel cannot ensure this, so it is kind of irrelevant whether the
>> signal is sent or not
>>
>>
>>
>> Sent from Mail https: for
>> Windows 10
>>
>>
>>
>> *From: *Tim Roberts
>> *Sent: *July 18, 2017 6:00 PM
>> *To: *Windows System Software Devs Interest List
>> *Subject: *Re: [ntdev] KeCancelTimer
>>
>>
>>
>> Mark Roddy wrote:
>> >
>> > Hmmm… that would leave a thread waiting on the timer object in a
>> > dubious state. Not that this is the typical use case, but still
>> > something should happen.
>>
>> If you intend to cancel the timer, then you’d better have another way to
>> unblock that thread before you free the timer’s memory. In that
>> respect, it’s not that different from a KEVENT. If it’s possible for
>> the event to end its usefulness without having been signaled, then any
>> time you wait on the event, you’d better wait on something else, too.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
></http:></http:></https:>

This seems awful easy to test. Put a thread on a wait on the timer and then
cancel the timer. Evaluate the results.

Mark Roddy

On Wed, Jul 19, 2017 at 12:21 AM, Jamey Kirby <
xxxxx@lists.osr.com> wrote:

> Canceling a timer is not the same thing as deallocating memory for the
> timer. There is KeInitializeTimer(), KeSetTimer(), and KeCancelTimer().
> KeCancelTimer() is not semantically a destructor. Can you call KeSetTimer()
> with another value while it is being waited on? Maybe this is the solution;
> set the timer to 0?
>
>
>
> On Tue, Jul 18, 2017 at 8:30 PM Jamey Kirby wrote:
>
>> I am working on a device cache idea. My idea is to do a
>> KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
>> all semantics. So, I have a cache that will flush every n seconds if 1) the
>> timer has expired, and 2) the event indicating work is set. If both are not
>> true, then the wait continues until both are. Now, when I get an
>> IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
>> to cause both conditions to be true.
>>
>> Alas, i’ll work on another mechanism. I’ve found very little use for wait
>> all semantics.
>>
>>
>> – Jamey
>>
>>
>> On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
>> xxxxx@lists.osr.com> wrote:
>>
>>> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>>>
>>>
>>>
>>> As you say, if you are going to deallocate the memory for the event
>>> structure, you need to ensure that the other thread(s) both are not waiting
>>> on it any more, and also can’t touch the pointer again. A simple signal
>>> during cancel cannot ensure this, so it is kind of irrelevant whether the
>>> signal is sent or not
>>>
>>>
>>>
>>> Sent from Mail https: for
>>> Windows 10
>>>
>>>
>>>
>>> *From: *Tim Roberts
>>> *Sent: *July 18, 2017 6:00 PM
>>> *To: *Windows System Software Devs Interest List
>>> *Subject: *Re: [ntdev] KeCancelTimer
>>>
>>>
>>>
>>> Mark Roddy wrote:
>>> >
>>> > Hmmm… that would leave a thread waiting on the timer object in a
>>> > dubious state. Not that this is the typical use case, but still
>>> > something should happen.
>>>
>>> If you intend to cancel the timer, then you’d better have another way to
>>> unblock that thread before you free the timer’s memory. In that
>>> respect, it’s not that different from a KEVENT. If it’s possible for
>>> the event to end its usefulness without having been signaled, then any
>>> time you wait on the event, you’d better wait on something else, too.
>>>
>>> –
>>> Tim Roberts, xxxxx@probo.com
>>> Providenza & Boekelheide, Inc.
>>>
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> Visit the list online at: http:>>> showlists.cfm?list=ntdev>
>>>
>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>> software drivers!
>>> Details at http:
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at <
>>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>>
>>>
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> Visit the list online at: http:>>> showlists.cfm?list=ntdev>
>>>
>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>> software drivers!
>>> Details at http:
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at <
>>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>>
>> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at
></http:></http:></http:></http:></https:>

Sure. I’ll probably try it today.

On Wed, Jul 19, 2017 at 8:14 AM Mark Roddy <
xxxxx@lists.osr.com> wrote:

> This seems awful easy to test. Put a thread on a wait on the timer and
> then cancel the timer. Evaluate the results.
>
> Mark Roddy
>
> On Wed, Jul 19, 2017 at 12:21 AM, Jamey Kirby <
> xxxxx@lists.osr.com> wrote:
>
>> Canceling a timer is not the same thing as deallocating memory for the
>> timer. There is KeInitializeTimer(), KeSetTimer(), and KeCancelTimer().
>> KeCancelTimer() is not semantically a destructor. Can you call KeSetTimer()
>> with another value while it is being waited on? Maybe this is the solution;
>> set the timer to 0?
>>
>>
>>
>> On Tue, Jul 18, 2017 at 8:30 PM Jamey Kirby
>> wrote:
>>
>>> I am working on a device cache idea. My idea is to do a
>>> KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
>>> all semantics. So, I have a cache that will flush every n seconds if 1) the
>>> timer has expired, and 2) the event indicating work is set. If both are not
>>> true, then the wait continues until both are. Now, when I get an
>>> IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
>>> to cause both conditions to be true.
>>>
>>> Alas, i’ll work on another mechanism. I’ve found very little use for
>>> wait all semantics.
>>>
>>>
>>> – Jamey
>>>
>>>
>>> On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
>>> xxxxx@lists.osr.com> wrote:
>>>
>>>> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>>>>
>>>>
>>>>
>>>> As you say, if you are going to deallocate the memory for the event
>>>> structure, you need to ensure that the other thread(s) both are not waiting
>>>> on it any more, and also can’t touch the pointer again. A simple signal
>>>> during cancel cannot ensure this, so it is kind of irrelevant whether the
>>>> signal is sent or not
>>>>
>>>>
>>>>
>>>> Sent from Mail https: for
>>>> Windows 10
>>>>
>>>>
>>>>
>>>> *From: *Tim Roberts
>>>> *Sent: *July 18, 2017 6:00 PM
>>>> *To: *Windows System Software Devs Interest List
>>>> *Subject: *Re: [ntdev] KeCancelTimer
>>>>
>>>>
>>>>
>>>> Mark Roddy wrote:
>>>> >
>>>> > Hmmm… that would leave a thread waiting on the timer object in a
>>>> > dubious state. Not that this is the typical use case, but still
>>>> > something should happen.
>>>>
>>>> If you intend to cancel the timer, then you’d better have another way to
>>>> unblock that thread before you free the timer’s memory. In that
>>>> respect, it’s not that different from a KEVENT. If it’s possible for
>>>> the event to end its usefulness without having been signaled, then any
>>>> time you wait on the event, you’d better wait on something else, too.
>>>>
>>>> –
>>>> Tim Roberts, xxxxx@probo.com
>>>> Providenza & Boekelheide, Inc.
>>>>
>>>>
>>>> —
>>>> NTDEV is sponsored by OSR
>>>>
>>>> Visit the list online at: <
>>>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>>>
>>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>>> software drivers!
>>>> Details at http:
>>>>
>>>> To unsubscribe, visit the List Server section of OSR Online at <
>>>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>>>
>>>>
>>>>
>>>> —
>>>> NTDEV is sponsored by OSR
>>>>
>>>> Visit the list online at: <
>>>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>>>
>>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>>> software drivers!
>>>> Details at http:
>>>>
>>>> To unsubscribe, visit the List Server section of OSR Online at <
>>>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>>>
>>> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY
>> seminars on crash dump analysis, WDF, Windows internals and software
>> drivers! Details at To unsubscribe, visit the List Server section of OSR
>> Online at
>>
>
> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at</http:></http:></https:>

Jamey Kirby wrote:

Canceling a timer is not the same thing as deallocating memory for the
timer. There is KeInitializeTimer(), KeSetTimer(), and
KeCancelTimer(). KeCancelTimer() is not semantically a destructor. Can
you call KeSetTimer() with another value while it is being waited on?
Maybe this is the solution; set the timer to 0?

Maybe. The doc says calling KeSetTimer on an active timer cancels,
unsignals, and resubmits it.

However, this whole thing seems like it is fraught with really ugly race
conditions.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

>However, this whole thing seems like it is fraught with really ugly race

conditions.

I agree. I’ve been looking for a valid reason to use wait all semantics;
more of a brain exercise. I figured I’d see how it might play out in my
device cache. However, wait all semantics seem to be a waste of time. It is
hard to imagine how to avoid the race condition. I think it would be unsafe
to use unless you set a KeWaitXxx() timeout that would periodically break
the wait to look for some other terminator; but then that’s your time out;
right? No need for a timer object :slight_smile:

It’s moot at this point. I’ll waste time somewhere else. I looked over
ReactOS too. I now know how the timer objects work, and I still haven’t
found a valid use for wait all semantics. Maybe it would be useful as a
join when using a kernel thread pool.

On Wed, Jul 19, 2017 at 1:02 PM Tim Roberts <
xxxxx@lists.osr.com> wrote:

> Jamey Kirby wrote:
> >
> > Canceling a timer is not the same thing as deallocating memory for the
> > timer. There is KeInitializeTimer(), KeSetTimer(), and
> > KeCancelTimer(). KeCancelTimer() is not semantically a destructor. Can
> > you call KeSetTimer() with another value while it is being waited on?
> > Maybe this is the solution; set the timer to 0?
>
> Maybe. The doc says calling KeSetTimer on an active timer cancels,
> unsignals, and resubmits it.
>
> However, this whole thing seems like it is fraught with really ugly race
> conditions.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

In my experience, wait all is only useful with shutdown / cleanup code. Even there, the fact that there is a maximum number of wait objects means that practically a loop is needed for anything except simple cases

For your particular case, I would suggest that you plan for your timer to run every n seconds and then check for work directly instead of checking an event. The event part creates an inherent performance penalty even if the semantics you describe would work. I am assuming that the ?work? involves some kind of shared data structure that will contain it and therefore can be readily checked

Sent from Mailhttps: for Windows 10

From: Jamey Kirbymailto:xxxxx
Sent: July 18, 2017 8:31 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] KeCancelTimer

I am working on a device cache idea. My idea is to do a KeWaitForMultipleObjects() that wait on an event and a timer, and use wait all semantics. So, I have a cache that will flush every n seconds if 1) the timer has expired, and 2) the event indicating work is set. If both are not true, then the wait continues until both are. Now, when I get an IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer to cause both conditions to be true.

Alas, i’ll work on another mechanism. I’ve found very little use for wait all semantics.

– Jamey

On Tue, Jul 18, 2017 at 7:42 PM Marion Bond > > wrote:
In UM, WAIT_ABANDONED covers this case, but in KM clearly not.

As you say, if you are going to deallocate the memory for the event structure, you need to ensure that the other thread(s) both are not waiting on it any more, and also can?t touch the pointer again. A simple signal during cancel cannot ensure this, so it is kind of irrelevant whether the signal is sent or not

Sent from Mailhttps: for Windows 10

From: Tim Robertsmailto:xxxxx
Sent: July 18, 2017 6:00 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] KeCancelTimer

Mark Roddy wrote:
>
> Hmmm… that would leave a thread waiting on the timer object in a
> dubious state. Not that this is the typical use case, but still
> something should happen.

If you intend to cancel the timer, then you’d better have another way to
unblock that thread before you free the timer’s memory. In that
respect, it’s not that different from a KEVENT. If it’s possible for
the event to end its usefulness without having been signaled, then any
time you wait on the event, you’d better wait on something else, too.


Tim Roberts, xxxxx@probo.commailto:xxxxx
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:
— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at</http:></http:></http:></http:></http:></http:></mailto:xxxxx></mailto:xxxxx></mailto:xxxxx></https:></mailto:xxxxx></mailto:xxxxx></https:>

Yep

On Wed, Jul 19, 2017 at 6:53 PM Marion Bond <
xxxxx@lists.osr.com> wrote:

> In my experience, wait all is only useful with shutdown / cleanup code.
> Even there, the fact that there is a maximum number of wait objects means
> that practically a loop is needed for anything except simple cases
>
>
>
> For your particular case, I would suggest that you plan for your timer to
> run every n seconds and then check for work directly instead of checking an
> event. The event part creates an inherent performance penalty even if the
> semantics you describe would work. I am assuming that the ‘work’ involves
> some kind of shared data structure that will contain it and therefore can
> be readily checked
>
>
>
> Sent from Mail https: for
> Windows 10
>
>
>
> *From: *Jamey Kirby
> *Sent: *July 18, 2017 8:31 PM
>
>
> *To: *Windows System Software Devs Interest List
> *Subject: *Re: [ntdev] KeCancelTimer
>
>
>
> I am working on a device cache idea. My idea is to do a
> KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
> all semantics. So, I have a cache that will flush every n seconds if 1) the
> timer has expired, and 2) the event indicating work is set. If both are not
> true, then the wait continues until both are. Now, when I get an
> IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
> to cause both conditions to be true.
>
>
>
> Alas, i’ll work on another mechanism. I’ve found very little use for wait
> all semantics.
>
>
>
> – Jamey
>
>
>
>
>
> On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
> xxxxx@lists.osr.com> wrote:
>
> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>
>
>
> As you say, if you are going to deallocate the memory for the event
> structure, you need to ensure that the other thread(s) both are not waiting
> on it any more, and also can’t touch the pointer again. A simple signal
> during cancel cannot ensure this, so it is kind of irrelevant whether the
> signal is sent or not
>
>
>
> Sent from Mail https: for
> Windows 10
>
>
>
> *From: *Tim Roberts
> *Sent: *July 18, 2017 6:00 PM
> *To: *Windows System Software Devs Interest List
> *Subject: *Re: [ntdev] KeCancelTimer
>
>
>
> Mark Roddy wrote:
> >
> > Hmmm… that would leave a thread waiting on the timer object in a
> > dubious state. Not that this is the typical use case, but still
> > something should happen.
>
> If you intend to cancel the timer, then you’d better have another way to
> unblock that thread before you free the timer’s memory. In that
> respect, it’s not that different from a KEVENT. If it’s possible for
> the event to end its usefulness without having been signaled, then any
> time you wait on the event, you’d better wait on something else, too.
>
> –
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
>
> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at
>
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></http:></https:></https:>

The WRK on Github reveals the answer (from timerobj.c):

This would have been good to add to the WDK documentation.

On Wed, Jul 19, 2017 at 6:56 PM Jamey Kirby wrote:

> Yep
>
> On Wed, Jul 19, 2017 at 6:53 PM Marion Bond <
> xxxxx@lists.osr.com> wrote:
>
>> In my experience, wait all is only useful with shutdown / cleanup code.
>> Even there, the fact that there is a maximum number of wait objects means
>> that practically a loop is needed for anything except simple cases
>>
>>
>>
>> For your particular case, I would suggest that you plan for your timer to
>> run every n seconds and then check for work directly instead of checking an
>> event. The event part creates an inherent performance penalty even if the
>> semantics you describe would work. I am assuming that the ‘work’ involves
>> some kind of shared data structure that will contain it and therefore can
>> be readily checked
>>
>>
>>
>> Sent from Mail https: for
>> Windows 10
>>
>>
>>
>> *From: *Jamey Kirby
>> *Sent: *July 18, 2017 8:31 PM
>>
>>
>> *To: *Windows System Software Devs Interest List
>> *Subject: *Re: [ntdev] KeCancelTimer
>>
>>
>>
>> I am working on a device cache idea. My idea is to do a
>> KeWaitForMultipleObjects() that wait on an event and a timer, and use wait
>> all semantics. So, I have a cache that will flush every n seconds if 1) the
>> timer has expired, and 2) the event indicating work is set. If both are not
>> true, then the wait continues until both are. Now, when I get an
>> IRP_MJ_FLUSH request, i’d like to set the event, and then cancel the timer
>> to cause both conditions to be true.
>>
>>
>>
>> Alas, i’ll work on another mechanism. I’ve found very little use for wait
>> all semantics.
>>
>>
>>
>> – Jamey
>>
>>
>>
>>
>>
>> On Tue, Jul 18, 2017 at 7:42 PM Marion Bond <
>> xxxxx@lists.osr.com> wrote:
>>
>> In UM, WAIT_ABANDONED covers this case, but in KM clearly not.
>>
>>
>>
>> As you say, if you are going to deallocate the memory for the event
>> structure, you need to ensure that the other thread(s) both are not waiting
>> on it any more, and also can’t touch the pointer again. A simple signal
>> during cancel cannot ensure this, so it is kind of irrelevant whether the
>> signal is sent or not
>>
>>
>>
>> Sent from Mail https: for
>> Windows 10
>>
>>
>>
>> *From: *Tim Roberts
>> *Sent: *July 18, 2017 6:00 PM
>> *To: *Windows System Software Devs Interest List
>> *Subject: *Re: [ntdev] KeCancelTimer
>>
>>
>>
>> Mark Roddy wrote:
>> >
>> > Hmmm… that would leave a thread waiting on the timer object in a
>> > dubious state. Not that this is the typical use case, but still
>> > something should happen.
>>
>> If you intend to cancel the timer, then you’d better have another way to
>> unblock that thread before you free the timer’s memory. In that
>> respect, it’s not that different from a KEVENT. If it’s possible for
>> the event to end its usefulness without having been signaled, then any
>> time you wait on the event, you’d better wait on something else, too.
>>
>> –
>> Tim Roberts, xxxxx@probo.com
>> Providenza & Boekelheide, Inc.
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
>> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
>> on crash dump analysis, WDF, Windows internals and software drivers!
>> Details at To unsubscribe, visit the List Server section of OSR Online at
>>
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list online at: <
>> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
></http:></http:></http:></https:></https:>

> So, I have a cache that will flush every n seconds if 1) the timer has expired,

and 2) the event indicating work is set. If both are not true, then the wait continues until both are.

If I got it right, you want to deal with 2 separate scenarios

  1. “Implicit” flush that is done under the conditions that, first, cache is dirty, and, second, timeout has expired

  2. “Explicit” flush that you perform in response IRP_MJ_FLUSH request. This one has to be done straight away, regardless of the timer expiry

I think the only possible way to avoid race conditions here is to introduce two separate code paths that are synchronised my means of a spinlock. You should not set an event in case of the explicit flush - instead,you just change the state of a global variable that is guarded by a spinlock just in case the blocking thread wakes up,and proceed with the flush. What happens after wait condition has been satisfied should depend on the state of above mentioned variable,i.e. a thread may proceed with the flush or reset the events and go blocking again.

It seems (at least to me) the only right way to go - otherwise, you will always be subjected to rather nasty race conditions…

Anton Bassov

What about using KeWaitForMultipleObjects for Any of the Flush, Timer,
Event.

Then if it’s the Flush you do the Flush and start again;
If it’s the Event or the Timer then you can KeWaitForMultipleObjects for
both the (Timer or Event) and the Flush

Well guess it’s quite convoluted…

On Fri, 21 Jul 2017 at 15:27, xxxxx@hotmail.com
wrote:

> > So, I have a cache that will flush every n seconds if 1) the timer has
> expired,
> > and 2) the event indicating work is set. If both are not true, then the
> wait continues until both are.
>
>
>
> If I got it right, you want to deal with 2 separate scenarios
>
>
> 1. “Implicit” flush that is done under the conditions that, first, cache
> is dirty, and, second, timeout has expired
>
> 2. “Explicit” flush that you perform in response IRP_MJ_FLUSH request.
> This one has to be done straight away, regardless of the timer expiry
>
>
>
> I think the only possible way to avoid race conditions here is to
> introduce two separate code paths that are synchronised my means of a
> spinlock. You should not set an event in case of the explicit flush -
> instead,you just change the state of a global variable that is guarded by a
> spinlock just in case the blocking thread wakes up,and proceed with the
> flush. What happens after wait condition has been satisfied should depend
> on the state of above mentioned variable,i.e. a thread may proceed with
> the flush or reset the events and go blocking again.
>
>
> It seems (at least to me) the only right way to go - otherwise, you will
> always be subjected to rather nasty race conditions…
>
>
>
> Anton Bassov
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

Consider what happens if you get an “explicit” flush request while the “implicit” one is still in progress (or vice versa). To make it even more interesting, you may theoretically get an “explicit” flush request on more than one thread. This is why you need some global variable(s) that is(are) guarded by a synch construct like spinlock. Otherwise you just cannot eliminate the theoretical possibility of race conditions…

Anton Bassov

Time just passes, and there is nothing you can do about this, right ?

So once a timer is initialized, it will eventually expire, no matter how long it takes. And the only way to prevent a timer from expiring and being signaled is to cancel it. You have your answer.

Note that you can check the state of an object with a call to KeWaitForSingleObject with the specified object and a timeout value set to zero. Provided that you perform a kernel mode and non-alertable wait, the object is signaled if and only if the routine returns STATUS_SUCCESS.