i want to accomplish:
download manager, simultane~ download of many files.
i dont want to go by 1 handle = 1 blocking thread because its a waste.
there is function WaitForMultipleObjects()
but i cant kill handle on timeout.
i have XX handles idle, and only 1 active (signaled in time < timeout).
Function have no way of flushing out idle handles because 1 is returning, and i cant put there more handles. Thats obvious DoS bug.
How do i avoid it?
I want WaitForMultipleObjects(), but returning in 2 cases:
handle signaled, or timeout passed for EACH handle. if signaled - handle it, if timeout - free space.
Help me please..
Waiting For Multiple Objects (win32)
Started by innerLOL, Dec 21 2009 12:36 PM
12 replies to this topic
#1
Posted 21 December 2009 - 12:36 PM
|
|
|
#2
Posted 23 December 2009 - 07:53 AM
#3
Posted 23 December 2009 - 02:08 PM
ok but it doesnt solve my problem, how do i kill handle wich is stuck?
#4
Posted 24 December 2009 - 09:14 AM
Quote
i have XX handles idle, and only 1 active (signaled in time < timeout).
Function have no way of flushing out idle handles because 1 is returning, and i cant put there more handles. Thats obvious DoS bug.
Function have no way of flushing out idle handles because 1 is returning, and i cant put there more handles. Thats obvious DoS bug.
sudo rm -rf /
#5
Posted 24 December 2009 - 02:07 PM
what are you proposing then?
i just want to avoid thread waiting for i/o completion doing nothing.
i just want to avoid thread waiting for i/o completion doing nothing.
#6
Posted 25 December 2009 - 08:16 AM
Oooh, I/O completion. That makes much more sense. Here's what you need to do: You're going need to do asynchronous file IO, using ReadFile and/or WriteFile and an OVERLAPPED structure. The OVERLAPPED structure is as follows:
For hEvent, you're going to want to call CreateEvent and set hEvent to the returned handle. Make sure the event starts in a non-signaled state and use a manual reset for file IO.
Because ReadFile and WriteFile will perform their operations asynchronously, you can call them repeatedly without having to wait for them to finish. After starting all the operations, call Sleep with your specified timeout period, then iterate through all your events and check to see which ones are signaled using the HasOverlappedIoCompleted macro. If any are still running (i.e. HasOverlappedIoCompleted returns false, kill the IO using CancelIo.
Here's a sample of what I mean.
typedef struct _OVERLAPPED
{
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union
{
struct
{
DWORD Offset;
DWORD OffsetHigh;
} ;
PVOID Pointer;
} ;
HANDLE hEvent;
}OVERLAPPED;
The Offset and OffsetHigh members tell Windows the byte position within the file / device that you want to read from or write to. Pointer must be zero.For hEvent, you're going to want to call CreateEvent and set hEvent to the returned handle. Make sure the event starts in a non-signaled state and use a manual reset for file IO.
Because ReadFile and WriteFile will perform their operations asynchronously, you can call them repeatedly without having to wait for them to finish. After starting all the operations, call Sleep with your specified timeout period, then iterate through all your events and check to see which ones are signaled using the HasOverlappedIoCompleted macro. If any are still running (i.e. HasOverlappedIoCompleted returns false, kill the IO using CancelIo.
Here's a sample of what I mean.
HANDLE hFiles[NUM_FILES];
HANDLE hIoEvents[NUM_FILES];
OVERLAPPED olOverlappedFiles[NUM_FILES];
BYTE bFileBuffers[NUM_FILES][BUFFER_SIZE];
DWORD dwBytesRead[NUM_FILES];
/*I'm assuming you've already opened all the files*/
memset(olOverlappedFiles, 0, sizeof(OVERLAPPED) * NUM_FILES);
olOverlappedFiles[0].Offset = /*blah*/;
olOverlappedFiles[0].OffsetHigh = /*whatever*/;
olOverlappedFiles[0].hEvent = CreateEvent(NULL, TRUE, FALSE, "ASYNCHIO_0");
.
.
.
for(int i = 0; i < NUM_FILES; ++i)
ReadFile(hFiles[i], bFilesBuffers[i], BUFFER_SIZE, &dwBytesRead[i], &olOverlappedFiles[i]);
Sleep(TIMEOUT_PERIOD);
for(int i = 0; i < NUM_FILES; ++i)
{
if(!HasOverlappedIoCompleted(&olOverlappedFiles[i]))
CancelIo(hFiles[i]);
CloseHandle(hEvents[i]);
CloseHandle(hFiles[i]);
}
Edited by dargueta, 25 December 2009 - 08:20 AM.
Added links
sudo rm -rf /
#7
Posted 26 December 2009 - 04:49 AM
well i think its a bad idea.
Why would i call Sleep? It will just slow down my app, i use Sleep only for debugging purposes, i dont think it was designed to do something else.
Perhaps WaitForMultipleObjects() with bWaitAll set to TRUE and my timeout.
After timeout passes, i loop with GetOverlappedResult()/GetLastError() to check wich are completed, and discard rest. If WFMO() dont return timeout, i wont have to loop because i know all descriptors are alive.
thx for help anyway
Why would i call Sleep? It will just slow down my app, i use Sleep only for debugging purposes, i dont think it was designed to do something else.
Perhaps WaitForMultipleObjects() with bWaitAll set to TRUE and my timeout.
After timeout passes, i loop with GetOverlappedResult()/GetLastError() to check wich are completed, and discard rest. If WFMO() dont return timeout, i wont have to loop because i know all descriptors are alive.
thx for help anyway
#8
Posted 26 December 2009 - 07:36 AM
Quote
Perhaps WaitForMultipleObjects() with bWaitAll set to TRUE and my timeout.
After timeout passes, i loop with GetOverlappedResult()/GetLastError() to check wich are completed, and discard rest. If WFMO() dont return timeout, i wont have to loop because i know all descriptors are alive.
After timeout passes, i loop with GetOverlappedResult()/GetLastError() to check wich are completed, and discard rest. If WFMO() dont return timeout, i wont have to loop because i know all descriptors are alive.
Just in case you didn't know, HasOverlappedIoCompleted is just a macro of GetOverlappedResult. The number of bytes written/read are stored in the InternalHigh field of your OVERLAPPED struct and the error code is in Internal, so really you won't need GetLastError (which won't give you sufficient information if more than one fails) or HasOverlappedIoCompleted. HasOverlappedIoCompleted won't get you the error code of individual IO operations, nor will GetLastError.
sudo rm -rf /
#9
Posted 27 December 2009 - 09:24 AM
this is also bad idea...
if 1 descriptor will be 'dead' everytime all other will wait full timeout.
afff........
know what? i ownt give any timeout.
bwaitall = false, and i will manually discard desciptors. this cant be automated, because readifle might wait few days before read data from pipe, for example.
my knowleadge has huge gaps, need to fix it.
if 1 descriptor will be 'dead' everytime all other will wait full timeout.
afff........
know what? i ownt give any timeout.
bwaitall = false, and i will manually discard desciptors. this cant be automated, because readifle might wait few days before read data from pipe, for example.
my knowleadge has huge gaps, need to fix it.
#10
Posted 28 December 2009 - 06:46 AM
You really don't like anything I have to say, do you?
Where'd you get that from? Care to cite?
Quote
because readifle might wait few days before read data from pipe, for example.
sudo rm -rf /
#11
Posted 28 December 2009 - 05:26 PM
now i know that there is no way not to say if io operation is still pending or died.
inside system everything return a value. io cant be pending forever, if handle was closed - i get error, if calceled - else error.
timeout apply only to sockets, have so_rcv/snd timeo, and i will test it to see if WFMO() fail or not.
if should as soon as 1 handle is destroyed.
inside system everything return a value. io cant be pending forever, if handle was closed - i get error, if calceled - else error.
timeout apply only to sockets, have so_rcv/snd timeo, and i will test it to see if WFMO() fail or not.
if should as soon as 1 handle is destroyed.
#12
Posted 05 January 2010 - 01:33 PM
1 more question, can i CloseHandle() without ensuring that pending io was canceled?
i know it will work, but is it documented way, or not?
i know it will work, but is it documented way, or not?


Sign In
Create Account


Back to top









