Abortion of pending IO system calls is necessary in order to be able to implement cancelation and interruption within a threading library. At present the unix version makes use of signals, however I have been unable to find a similar mechanism in Win32. Basically I am looking for an equivalen to pthread_kill() function which would post a "signal" to a thread's HANDLE object forcing that thread to unblock, at which point the library will do the rest. In fact I am open to any alternatives...
Yes, it seems that this is the only way to achieve what I am looking for. Unfortunately, since it is impossible to guarantee that the IO is always asynchronous outside the library (eg in client code) the idea has to be abandoned. If only it was possible to CancelIo from another thread, or better yet cancelation was part of native API. Oh well...
You might not like the anwer: you need to make all I/O asynchronous in that thread. Then you can have that thread use an event or any other syncronisation object to be notified from the other thread. If it needs to kill all outstanding I/O, it can call the CancelIO API for all the handles that it has outstanding IO requests for.
A similar way has been suggested by Ronald in this thread. Unfortunately I cannot guarantee (or rather enforce) that the client code is using asynch IO. Hence this is not the solution to the problem. With posix I can use signals to abort *any* system call, including the blocking ones. I was hoping that a similar solution could be found with Win32, alas, it appears there is none.
Thanks,
- NK
PS. the library I describe has already been implemented on both posix and win32, thus implementation is not an issue. I only seek an answer to my original question.
I figured it was an API that narechkwas creating thats why I suggested hooking. That way the user won't need to use your wrappers for all I/O operations. But if you are already wrapping the I/O then you don't need to hook.
Your API shouldn't support this... I don't know why *nix would. If you are going to abort the I/O then everything else in your user's app is going to screw up as a result of data corruption.
Right, I should have said it right from the start: I do not want to *kill* the thread, only to force it to abort executing pending IO calls (ie file reading/writing) which may block it. According to MSDN:
A thread cannot protect itself against TerminateThread, other than by controlling access to its handles [...]
Ergo TerminateThread won't work. Up until now I've been looking for a solution throughout even the most remote corners of the known galaxy, albeit with no success. If noone here can help, I take it the problem is unsoluble.
To clarify again: I want to notify a thread (possibly by causing a structured exception -- which I can handle) that it may no longer block in system calls. Is there a way to do this using native API calls
With native API calls, I doubt it... but we are on Microsoft's forum so I won't say I am sure at the risk of being refuted by the authors of the API.
Why do you want to kill pending I/O That will lead to data corruption. Can you elaborate
The only way I see it happening is by hooking every file I/O function you use and in the hook create another thread that just runs that function while the owner thread waits on an event (the event to halt any I/O) wich if it goes through terminates the new thread that is running the I/O function. So every time you call any I/O function the function itself runs in it's own unique thread waiting to be terminated. Not very elegant...
The esiest way to acomplish this with the Win-32 API is to switch from using blocking I/O to using asynchronus I/O with notification via Win-32 events, then block waiting for the event rather than inside the I/O routine.
So, in your I/O thread create your I/O handle (file, serial, socket), and create a Win-32 event (CreateEvent()) and associate it with your I/O handle so it will be notified when events of interest occur (e.g. WSAEventSelect() for a socket).
In the parent thread, create a manual reset event with CreateEvent() and pass the event handle to the I/O thread when you start it. Now, in the child I/O thread, instead of calling WaitForSingleEvent(), call WaitForMultipleEvents() and include the manual reset event as well as the event handle associated with I/O. You will be notified if your I/O operation completes or if the parent thread wants to interrupt (by setting the event). If the I/O thread finds the manual reset event caused the return from WaitForMultipleEvents() it can now exit gracefully (performing any necessary cleanup).
Multithreading
Le Sage
Cheers,
- NK
FDS
> Event API is of no use, since, if I understand it correctly, SetEvent() can't be used on a HANDLE belonging to a thread object.
I'm not sure what you mean here. You don't use SetEvent() on a thread handle you use it on an event handle created with CreateEvent().
Richard Dalley
Here's a link to the online documentation for CreateEvent
http://msdn.microsoft.com/library/default.asp url=/library/en-us/dllproc/base/createevent.asp
MatHobbs
Thanks Ronald,
- NK
Aji Jose
You might not like the anwer: you need to make all I/O asynchronous in that thread. Then you can have that thread use an event or any other syncronisation object to be notified from the other thread. If it needs to kill all outstanding I/O, it can call the CancelIO API for all the handles that it has outstanding IO requests for.
Ronald Laeremans
Visual C++ team
nlhowell
- NK
Philippe Quesnel
Thanks,
- NK
PS. the library I describe has already been implemented on both posix and win32, thus implementation is not an issue. I only seek an answer to my original question.
saravanan_Vv
What should not it support
"If you are going to abort the I/O then everything else in your user's app is going to screw up as a result of data corruption."
Not so. Thread cancelation is the opposite of thread termination. It allows a thread to release resources held and exit cleanly.
- NK
Jarred
Your API shouldn't support this... I don't know why *nix would. If you are going to abort the I/O then everything else in your user's app is going to screw up as a result of data corruption.
ConnollyG
A thread cannot protect itself against TerminateThread, other than by controlling access to its handles [...]
Ergo TerminateThread won't work. Up until now I've been looking for a solution throughout even the most remote corners of the known galaxy, albeit with no success. If noone here can help, I take it the problem is unsoluble.
To clarify again: I want to notify a thread (possibly by causing a structured exception -- which I can handle) that it may no longer block in system calls. Is there a way to do this using native API calls
Thanks,
- NK
phokaia
Shiznet
Why do you want to kill pending I/O That will lead to data corruption. Can you elaborate
The only way I see it happening is by hooking every file I/O function you use and in the hook create another thread that just runs that function while the owner thread waits on an event (the event to halt any I/O) wich if it goes through terminates the new thread that is running the I/O function. So every time you call any I/O function the function itself runs in it's own unique thread waiting to be terminated. Not very elegant...
Patrick Tseng
So, in your I/O thread create your I/O handle (file, serial, socket), and create a Win-32 event (CreateEvent()) and associate it with your I/O handle so it will be notified when events of interest occur (e.g. WSAEventSelect() for a socket).
In the parent thread, create a manual reset event with CreateEvent() and pass the event handle to the I/O thread when you start it. Now, in the child I/O thread, instead of calling WaitForSingleEvent(), call WaitForMultipleEvents() and include the manual reset event as well as the event handle associated with I/O. You will be notified if your I/O operation completes or if the parent thread wants to interrupt (by setting the event). If the I/O thread finds the manual reset event caused the return from WaitForMultipleEvents() it can now exit gracefully (performing any necessary cleanup).