From - Wed Sep 24 08:01:10 1997 Path: news.mitre.org!blanket.mitre.org!philabs!newsjunkie.ans.net!newsfeeds.ans.net!portc02.blue.aol.com!pitt.edu!dsinc!spool.mu.edu!uwm.edu!vixen.cso.uiuc.edu!news-peer.sprintlink.net!news.sprintlink.net!Sprint!europa.clark.net!209.44.64.7!news3.spinne.com!news.spinne.com!Supernews60!supernews.com!news.he.net!newshub.cts.com!newsfeed.cts.com!cmkrnl!jeh From: jeh@cmkrnl.com (Jamie Hanrahan) Newsgroups: comp.os.ms-windows.programmer.nt.kernel-mode Subject: Re: IoStartPacket Message-ID: <1997Sep23.130424.8217@cmkrnl> Date: 23 Sep 97 13:04:24 PST References: <01bcc84c$aa201430$822bb2cc@cruss> Organization: Kernel Mode Systems, San Diego, CA Lines: 55 In article <01bcc84c$aa201430$822bb2cc@cruss>, "Christine Russ" writes: > I have found something very scary. I am debugging a multi threaded > application. In one thread I issue DMA requests that originate in my > device driver as IRP_MJ_READ requests. All IRP_MJ_READ requests are > processed through the device object queue with IoStartPacket and > IoStartNextPacket. I have another thread issuing IRP_MJ_DEVICE_CONTROL > requests which do not go through IoStartPacket/IoStartNextPacket. I am > finding with the multithreaded application, my StartIo routine is never > getting called. I get to the point of calling IoStartPacket, and that is > it, I don't get any further. I looked up IoStartPacket in the DDK and it > says "If the driver is already busy processing a request for the target > device object, then the packet is queued in the device queue. Otherwise, > this routine calls the driver's StartIo routine with the specified IRP." > > Does this mean if the driver is busy processing any other Irp, including > one that does not use IoStartPacket? No, not at all. If you call IoStartPacket and the StartIo routine is not called immediately thereafter, it is because the Busy bit in the DriverObject->DeviceQueue structure is set. Which means that some other IO was previously started via IoStartPacket and a corresponding IoStartNextPacket has not been called yet. There is no other reason for IoStartPacket to not call the StartIo routine. Ever. However, there is another level of "single-threading" that is implemented more or less behind your back, and that is in the file object. If the file object is not opened for async IO (in other words if you do NOT specify FILE_FLAG_OVERLAPPED on the CreateFile), the NT kernel IO routines will enforce a one-IO-at-a-time restriction through the file object. Now if you're not doing overlapped IO, the only way you can ATTEMPT more than one IO through the file object is with multiple threads, so here's how it works: Thread A has an IO in progress through a file object. This fact is noted in the file object itself. Thread B issues another IO through the same file object. The NT kernel IO routine (NtReadFile or similar) checks the file object, finds an IO is already in progress through it and that the file object was NOT opened for overlapped IO, and simply puts thread B into a wait on the file object! Thread B then waits until Thread A's IO is done (as Thread A is doing). When Thread A's IO is done, both threads get made Ready, one of them wins due to priority or accidents of timing, and gets to start the next IO. So, if you want multiple threads to have IOs pending to the same device, you must either (a) use FILE_FLAG_OVERLAPPED on the CreateFile, or (b) create *multiple* file objects by doing CreateFile multiple times to the same device. --- Jamie Hanrahan, Kernel Mode Systems, San Diego CA Internet: jeh@cmkrnl.com (JH645) CompuServe: 74140,2055 drivers, internals, networks, applications, and training for VMS and Windows NT NT driver FAQ, links, and other information: http://www.cmkrnl.com/ If you post a reply in news, please don't e-mail it too.