How to use SleepEx with alertable true AND an overall minimum sleep time?

半城伤御伤魂 提交于 2019-12-22 18:06:03

问题


I have the following use case: My current thread needs to do operation1, waits some amount of time to coordinate with others and afterwards needs to do operation2. In between the waiting, APCs might need to be processed by that thread because of file system events, which add another operation1 to some queue to be processed later after operation2 is finished by the current thread. Something simple like the following:

while (true)
{
  processOperation1;
  SleepEx(..., true);
  processOperation2;
}

The important thing is that between operation1 and operation2 at least the specified amount of time to SleepEx has to be elapsed! That doesn't need to be in one piece, the thread can instantly be used to process APCs and queue another operation1, it just shouldn't continue with operation2 unless the specified amount of time has elapsed.

From the docs:

If the parameter is TRUE and the thread that called this function is the same thread that called the extended I/O function (ReadFileEx or WriteFileEx), the function returns when either the time-out period has elapsed or when an I/O completion callback function occurs. If an I/O completion callback occurs, the I/O completion function is called. If an APC is queued to the thread (QueueUserAPC), the function returns when either the timer-out period has elapsed or when the APC function is called.

From my understanding that means that if SleepEx is called and an APC has been queued, that is directly executed by the current thread because it is capable to do so. But what happens afterwards with the code after SleepEx? Does the thread return to process operation2 because SleepEx returned control or does the thread gets back to sleep, staying in SleepEx until the specified amount of time is elapsed?

The first sentence in the docs is not speaking about returning from the function, but "resuming the thread":

Suspends the current thread until the specified condition is met. Execution resumes when one of the following occurs:

That could mean that the thread is resumed, processes APCs and afterwards stays in SleepEx, sleeping for whatever amount of time is needed.

If that's not the case and SleepEx is really left, does it tell how much time has elapsed? SleepEx doesn't seem to provide that value, but only some constant return value. This sounds like I would need to take time before and after SleepEx on my own and call that function again and again in a loop until the time I need really has elapsed? Is there already something out there like that, maybe as part of boost?

Thanks!


回答1:


You should call SleepEx in a loop and process the queued APCs until the needed timeout elapses.

Something like this.

for (DWORD dwStart = GetTickCount(); ; )
{
    DWORD dwElapsed = GetTickCount() - dwStart;
    DWORD dw = (dwTimeout > dwElapsed) ? (dwTimeout - dwElapsed) : 0;
    if (!SleepEx(dw, TRUE))
        break;
}


来源:https://stackoverflow.com/questions/46220843/how-to-use-sleepex-with-alertable-true-and-an-overall-minimum-sleep-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!