Cancelling scheduled work/io/timer items in WIN32

2019-08-14 12:10发布

问题:

I've been playing around with Windows' (new?) thread pool API. I've been following through with the example in the Using the Thread Pool Functions and I've been taking a good hard look at the API on MSDN. There's something I don't get about cleanup groups.

When invoking the SetThreadpoolCallbackCleanupGroup(), the third parameter is described as

The cleanup callback to be called if the cleanup group is canceled before the associated object is released. The function is called when you call CloseThreadpoolCleanupGroupMembers().

If my understanding is correct, the means that you can cancel pending work/io/timer items and ask it to invoke the cleanup callback function on each of these objects instead of the originally queue work/io/timer item's callback. This sounds cool, and I'd like to use it.

Unfortunately, the PTP_CLEANUP_GROUP_CANCEL_CALLBACK type used for the callback in question is not documented on MSDN and the example in question does not use this feature.

Taking the law into my own hands, I've traced back the definition to WinNT.h and found the following.

typedef VOID (NTAPI *PTP_CLEANUP_GROUP_CANCEL_CALLBACK)(
    __inout_opt PVOID ObjectContext,
    __inout_opt PVOID CleanupContext
    );

Removing the cruft on this funny looking declaration gets you:

typedef void ( __stdcall * PTP_CLEANUP_GROUP_CANCEL_CALLBACK )
    ( void* ObjectContext, void* CleanupContext );

Question: If you would have to take an educated guess, what do you think ObjectContext and CleanupContext refer to?

My 1st guess is that CleanupContext is what you specify at the moment you initiate cleanup: thus the 3rd parameter to CloseThreadpoolCleanupGroupMembers(). I'm pretty confident this guess is correct because the API calls are so directly related.

My 2nd guess is that ObjectContext is what you specify at the moment you submit the work/io/timer item: this the 2nd parameter to CreateThreadpoolWork() et al. I'm totally unsure that this is the case.

Can someone confim that these guesses are correct? Has anyone used this feature before?

回答1:

The optional cleanup callback you specify using the SetThreadpoolCallbackCleanupGroup function is called for each object that is associated with the same callback environment that has not already been closed by the time CloseThreadpoolCleanupGroupMembers is called. The callback’s first parameter, the object context, is the value of the void* parameter you specify when using the TrySubmitThreadpoolCallback, CreateThreadpoolWork, etc. functions. The callback’s second parameter, the cleanup context, is the value of the void* parameter you specify when using the CloseThreadpoolCleanupGroupMembers function.

The important thing to remember is that whether the cleanup callback is called for a particular object is not dependent on whether or not that object has outstanding callbacks. It is only called for objects that have not yet been closed. In other words it’s entirely possible that the object’s callback is called and then the cleanup callback is called for that same object.

If for example you create a work object using the CreateThreadpoolWork function and fail to call the CloseThreadpoolWork function prior to calling CloseThreadpoolCleanupGroupMembers then the cleanup callback will be called for that object even if the object’s callback has already executed. Failing to call CloseThreadpoolWork is not a bug as CloseThreadpoolCleanupGroupMembers will close any objects associated with the cleanup group.

Another twist to watch out for is when using the TrySubmitThreadpoolCallback function. This is a simpler version of CreateThreadpoolWork in that you don’t have to think about creating, submitting, and closing the work object. The trick is that the thread pool with automatically close the work object once its callback has executed. This means that the cleanup callback will only be called for this object if its callback is still pending and you specify TRUE when calling CloseThreadpoolCleanupGroupMembers to cancel any pending callbacks.