I was looking into the pthreads-win32 library. When I try to
"pthread_cancel" a thread that is blocked indefinitely in a DeviceIoControl
call to a kernel mode device driver, pthread_cancel returns, but the
subsequent pthread_join that I am doing blocks forever. I tried changing the
cancel type to asynchronous, didn't help.
Then I tried to cancel a thread that is blocked in a Sleep(INFINITE) with
the same result. It looks like a thread that is blocked in any way cannot be
cancelled in pthreads-win32. Is this an implementation specific behavior
with pthread-win32 or will the same thing happen under Linux, when a thread
is blocked in an ioctl to a kernel module?
Any insight?
Timur.
Win32 doesn't have a notion of cancelation. Any kind of cancelation scheme
implemented in Win32 is going to be ``shallow'', in that it will only work for
waitable things in the pthread library, where it can be specially arranged to
unblock the thread.
>Then I tried to cancel a thread that is blocked in a Sleep(INFINITE) with
>the same result.
That's because Sleep is a Win32 function that your pthreads library
knows nothing about. Perhaps pthreads-win32 implements a cancellable
nanosleep(). Failing that, you should be able to implement something using
pthread_cond_timedwait.
>It looks like a thread that is blocked in any way cannot be
>cancelled in pthreads-win32. Is this an implementation specific behavior
>with pthread-win32 or will the same thing happen under Linux, when a thread
>is blocked in an ioctl to a kernel module?
Linux is better about cancelation though not perfect. Many library functions
which could be cancelation points are not. Luckily, cancelation is based
on signals, so functions that can be safely broken with signals can, in
principle, be asynchronously canceled.
If the ioctl is interruptible, you should be able to break it with async
cancelation. Cancelation on LinuxThreads is done using a dedicated signal
(except when certain internal pthread waits are canceled; then it's done using
the normal restart signal, as of glibc 2.1.3 and later).
So what will happen if you asynchronously cancel a thread that is doing
the ioctl is simply that it will get a signal, and a hidden signal handler
within the LinuxThreads library will perform the thread cleanup.
If cancelation is deferred rather than asynchronous, then the same signal
handler will simply record the cancelation request and return.
If the ioctl performs uninterruptible sleep, then there is no way to
forcibly get the thread out of it, since it won't respond to signals.