We help IT Professionals succeed at work.

WaitForMultipleObjects - 2 timeouts?

thready
thready asked
on
Hi Experts,

I have the need for 2 separate timeouts as events coming back from WaitForMultipleObjects.  The normal timeout with WAIT_TIMEOUT is done.. How can I add a 2nd timeout event?  Perhaps a handle with some timer function that sets the event after a certain amount of time?

Thanks!
Mike
Comment
Watch Question

jkr
Top Expert 2012
Commented:
A loop could do that, e.g.

DWORD adwTimeouts[] = {2000, 1000};
HANDLE ahWaitHandles = { handle1, handle2};

for (int i = 0; i <= 1; ++i) {

  if (WAIT_TIMEOUT != WaitForMultipleObjects(2,ahWaitHandles,FALSE,adwTimeouts[i])) {
    // not a timeout, do something
  }
}

Open in new window

Author

Commented:
I don't think so- if timeout 2 is smaller, then it suffers... If I have one timeout of 10 seconds and the other is 30, I want the event to happen every 10 seconds and every 30 seconds...
jkr
Top Expert 2012

Commented:
Do the timeouts depend on which event fired? If so, you could use the event indicator that is returned to select the next timeout.

Alternatively, you could 'WaitForSingleObject()' in two separate threads...

Author

Commented:
Yeap... I guess that's the best I can do with this.  Not giving up yet though... :-)
Top Expert 2012
Commented:
So, what about distinguishing the events, e.g.

DWORD dwResult;
DWORD dwTimeout = 30000;
HANDLE ahWaitHandles = { handle1, handle2};

for (;;;) {

  if (WAIT_TIMEOUT != (dwResult = WaitForMultipleObjects(2,ahWaitHandles,FALSE,dwTimeout))) {
    // not a timeout, do something
    switch(dwResult - WAIT_OBJECT_0) {

      case 0: dwTimeout = 30000;  // 'handle1' fired
      break;

      case 0: dwTimeout = 20000;  // 'handle2' fired
      break;
    }
  }
}
                                          

Open in new window

jkr
Top Expert 2012
Commented:
As for the 'two thread solution' - think of it as

struct ThreadParam {
   HANDLE hObj;
  DWORD dwTimeout;
};

LONG WaitHandleThread(LPVOID pv) {

  ThreadParam* ptp = (ThreadParam*) pv;

  WaitForSingleObject(ptp->hObj, ptp->dwTimeout);

  return0;
}

void WaitFor2Timeouts() {

  ThreadParam par1;
  par1.hObj = handle1;
  par1.dwTimeout = 20000;

  ThreadParam par2;
  par1.hObj = handle2;
  par1.dwTimeout = 30000;

  DWORD dwTID1, dwTID2;

  HANDLE hThr1 = CreateThread(NULL, 0, WaitHandleThread, (LPVOID) &par1, 0, &dwTID1);
  HANDLE hThr2 = CreateThread(NULL, 0, WaitHandleThread, (LPVOID) &par1, 0, &dwTID2);

  HANDLE ahWait[] = { hThr1, hThr2};

  WaitForMultipleObjects(2, ahWait, TRUE, INFINITE); // change that to 'FALSE' if that mathches more what you need
}

Open in new window

Author

Commented:
Thanks!  I'll be doing a hybrid of the "best solution".  There's one of the timeouts that is so unimportant and will be guaranteed to run less often than the other, so I'll just check if it's "time for that event too"... kinda thing...     :-)