Threads pause during DeviceIoControl()

Windows specific forum
User avatar
SnowyDog
User
User
Posts: 33
Joined: Tue Jun 10, 2014 8:18 pm

Threads pause during DeviceIoControl()

Post by SnowyDog »

My GUI application works with SCSI devices using SCSI passthrough (SPTI) in non-overlapped mode, i.e. the call looks like this:

Code: Select all

; Make the call
	lResult=DeviceIoControl_(*SCSI\hDevice,         ; handle to the SPTI device
	                         #IOCTL_SCSI_PASS_THROUGH_DIRECT,			; [in] dwControlCode
	                         *SCSI\SPTDWS\SPTD,							; [in] pointer to the SPTD structure
	                         SizeOf(SCSI_PASS_THROUGH_DIRECT),			; [in] the size of the SPTD structure
	                         *SCSI\SPTDWS\SPTD,							; [out] pointer to the output SPTDWS structure (overwrites input SPTD)
	                         SizeOf(SCSI_PASS_THROUGH_DIRECT_WITH_SENSE),; the size of the SPTDWS structure (to include Sense buffer at specified offset)
	                         @lBytesRet,								 ; [out] pointer to a variable that received the size of data returned
	                         #Null)										 ; [N/A] not used for non-overlapped operations
The DeviceIoControl() call is made by the main thread and my application has a sub thread running to service the GUI at regular intervals. However, whenever the main thread is waiting for DeviceIoControl() to return, my GUI sub thread also pauses.

I'm working with relatively slow SCSI tape drives and some SCSI operations (like load / unload medium and rewind) can take 30s or more to complete, during which the main GUI often goes into the 'not responding' state, until the command completes, which I want to avoid.

I've tested having a sub thread to handle the SCSI operations but this makes no difference - the main and GUI sub threads in my application still pause until the DeviceIoControl() call made by the SCSI sub thread, returns.

Is this expected behaviour in Windows 10/11? Is there a better way to code this, other than modifying the SCSI CDB for IMMED=1 or using overlapped mode to reduce the time spent in DeviceIoControl() ? Thanks.
Axolotl
Addict
Addict
Posts: 802
Joined: Wed Dec 31, 2008 3:36 pm

Re: Threads pause during DeviceIoControl()

Post by Axolotl »

Without a usable code it is difficult to help....
Therefore some general hints from a non-professional.
No, I wouldn't expect this behavior from windows, but I would expect it from badly/incorrectly written programs. No offense.

Your main problem:
If a top-level window stops responding to messages for more than several seconds, the system considers the window to be not responding and replaces it with a ghost window that has the same z-order, location, size, and visual attributes. This allows the user to move it, resize it, or even close the application. However, these are the only actions available because the application is actually not responding.

My suggestion:
1. Do all the GUI stuff in one (the) main thread.
2. Put the blocking function calls to other (maybe with lower priority) threads.
3. If you use Mutexes or Semaphores you can run into the problem as well.
4. Look at some very good explanation on this forum about threads or Event Handling in general.

BTW: Sorry, for this helpless response, but my comments usually get the professionals to reply. Good luck..
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
User avatar
SnowyDog
User
User
Posts: 33
Joined: Tue Jun 10, 2014 8:18 pm

Re: Threads pause during DeviceIoControl()

Post by SnowyDog »

No, I wouldn't expect this behavior from windows, but I would expect it from badly/incorrectly written programs. No offense.
Thanks for your reply, and no offence taken. Without knowing for sure the cause, I cannot rule this out myself, hence my question.

I would provide example code, but firstly it is part of a much bigger modular program and secondly without the hardware it's impossible for someone else to test it.

I know of no other DeviceIoControl() calls that can take tens of seconds to return and at the same time do not require one to have an extremely slow responding piece of hardware attached. If you know of such a call, please let me know!

What I can say is that if I replace the DeviceIoControl() in my SCSI handler thread with a suitably long delay() statement or have it just loop for a long time, I do not see the same issue - i.e. the main and GUI threads continue uninterrupted.

So, with limited information to go on, this does appear to be related specifically to DeviceIoControl() calls causing the main and other sub-threads to halt, whenever the call takes a very long time to return.

I am playing with a few other ideas and may end up having to implement overlapped SCSI calls as that appears to be the way Microsoft recommend dealing with this kind of issue, but I can see that overlapped SCSI operations can potentially open up a whole new set of problems...
Axolotl
Addict
Addict
Posts: 802
Joined: Wed Dec 31, 2008 3:36 pm

Re: Threads pause during DeviceIoControl()

Post by Axolotl »

Have you tried ThreadPriority() on the SCSI handler thread?
Just because it worked doesn't mean it works.
PureBasic 6.04 (x86) and <latest stable version and current alpha/beta> (x64) on Windows 11 Home. Now started with Linux (VM: Ubuntu 22.04).
Post Reply