[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

WriteFile and CloseHandle seem to hang until further input

Posted on 2004-08-11
17
Medium Priority
?
3,644 Views
Last Modified: 2008-01-09
So ... let's start :)

I have some USB device which reports as HID compliant Device. I can turn and push this device.

My program is written in C#, but it looks like the program lies with some of the API functions.

I can push and rotate this device and via ReadFile I can get the data (what has been done / rotated / pushed).

BUT:
I should also be able to write to that device (therefore 1 (maybe 2) bytes are sent to the device).
The Problem:
When I call WriteFile with the handle at first my whole program seems to hang (I watched it in the debugger and it looks like WriteFile doesn't do anything). When I now rotate (or push)  the device (so that some data should be sent from the device to my PC) the data reaches me and WriteFiles continues (and ends with success).

The same applies for CloseHandle

I call CloseHandle -> Everything hangs -> I move the device -> CloseHandle continues and succeeds (no error)


I do the reading in a separate Thread - so could this be the problem?

Can anyone out there maybe help me ?
 
0
Comment
Question by:somnatic
  • 9
  • 4
  • 2
  • +2
17 Comments
 
LVL 5

Expert Comment

by:lemmeC
ID: 11771846
The thread for reading seems to be having a higher priority. Try using the same priority for the ReadFile and WriteFile threads.
0
 
LVL 5

Expert Comment

by:lemmeC
ID: 11772022
Or the WriteFile Thread could be waiting for some data set in the ReadFile Thread.
0
 
LVL 4

Author Comment

by:somnatic
ID: 11772115
hmm .. how can i set the priority in C# ?
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 4

Author Comment

by:somnatic
ID: 11772199
ok . .found it out by myself ..

but that didn't help ...
I tried BelowNormal and Lowest, but nothing changed ..


Till now I think that:
* The thread which reads, has already called ReadFile(...)
* The thread which writes, calls WriteFile()
Now WriteFile has to wait until ReadFile has finished ...
then WriteFile is executed


any ideas ?
0
 
LVL 7

Expert Comment

by:aib_42
ID: 11772273
If the reading thread is reading constantly, WriteFile might be blocking until the last ReadFile issued is completed, yes. I suggest you use the asynchronous I/O read function, ReadFileEx() to do your reading. While waiting for ReadFileEx's completion, the reading thread can check to see if the writer thread is issuing a WriteFile function call, and if it is, cancel its read attempt via CancelIO, to allow the write to go through.
0
 
LVL 4

Author Comment

by:somnatic
ID: 11772469
@ aib_42

that sounds like a possible solution .. do you have any code for this ?

i tried to cancel the ReadFile with CancelIo before, but nothing happened ...
0
 
LVL 4

Author Comment

by:somnatic
ID: 11772553
ok .. another one ...

I tried to build that OVERLAPPED structure in C# ...

Appearently I did at least something right:

            [StructLayout(LayoutKind.Sequential)]
                  private unsafe struct OVERLAPPED
            {
                  public int Internal;
                  public int InternalHigh;
                  public int Offset;
                  public int OffsetHigh;
                  public int Handle;
            }


but when I issue this structure (overlap = new OVERLAPPED) to
ReadFile(HidHandle, BufBytes, InputReportByteLength, ref BytesRead, ref overlap)

it says it can't convert from ....OVERLAPPED to int*

shouldn't ref give out the pointer ?
0
 
LVL 4

Author Comment

by:somnatic
ID: 11772632
forget that last one ...

caps suck ;)
0
 
LVL 22

Expert Comment

by:grg99
ID: 11774429
You're on the right track.  Use overlapped I/O, or pass your write data to a thread that does the actual write.
0
 
LVL 4

Author Comment

by:somnatic
ID: 11780766
hmm .. what do you mean by the second part ?

why would I use another thread if I can't stop ReadFile to wait for input ?
0
 
LVL 7

Expert Comment

by:aib_42
ID: 11780919
You may want to try switching to ReadFileEx() since "it is designed solely for asynchronous operation", quoting from the SDK reference :).

I have some synchronization ideas in mind, but I'm too sleepy to get my head together right now. If you still need advice by tomorrow (by when I will be at work ;) I can hopefully spit out some suggestions. Unfortunately, I have no source code at hand. (But I can give you a nice list of hacks and workarounds I had to try for a project, if you ever want to hate Win32 IPC.)

By the way, CancelIO has to be called from the thread which called the R/W operation (which also means that there is no way to block a synchronous operation). You would need the reading thread to check if there are any write requests and cancel its own read if so.
0
 
LVL 7

Expert Comment

by:aib_42
ID: 11780935
Typos, grammar mistakes, sleepiness, 9:25am. Please excuse the orc.
0
 
LVL 4

Author Comment

by:somnatic
ID: 11781071
oh I excuse everything as long as it helps ;)

I tries ReadFileEx but couldn't get the thing with that Overlapped Structure right (too dumb probably).

concerning CancelIO ... did you have to say that ... ? that was exactely what I didn't want to hear ;)
0
 
LVL 4

Author Comment

by:somnatic
ID: 11781073
ahem .. and .. are u saying that there is no way at all to "cancel" that ReadFile operation ?

(i don't care if it's a beautiful way or not ;) )
0
 
LVL 7

Assisted Solution

by:aib_42
aib_42 earned 750 total points
ID: 11793328
Destroying the thread might help.. :)

I'm saying that there is not way to cancel a _synchronous_ ReadFile operation, since the thread doing the read will have to wait for ReadFile's completion before calling CancelIO, at which point there is not much point in calling it :).

Since you have to use overlapped structures anyway with an _asynchronous_ ReadFile operation, you might as well go ahead and use ReadFileEx, at least it can automatically call a function when it is done.

As for the OVERLAPPED structure (I am too dumb for it too), hmm, how about all fields zero? Doesn't look like you will be needing and of them.
0
 
LVL 19

Accepted Solution

by:
drichards earned 750 total points
ID: 11801202
Overlapped IO is not really that hard once you've done it a few times.  Here's a basic read function you can run in a thread.  It's pieced together from some serial port code:
-------------------------------------
    OVERLAPPED olap;
    unsigned char buffer[1024];
    long result;
    DWORD wait = 1000;
    DWORD numRead, error;
    BOOL inProgress;
    HANDLE hPort;

    hPort = ::CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
    olap.Offset = 0;
    olap.OffsetHigh = 0;
    olap.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);

    inPorgress = FALSE;
    while ( 1 ) // Loop until exit condition is met
    {
        if ( !inProgress ) // check if a read is in progress already
        {
            result = -1;
            // No read in progress, so start one
            if ( ::ReadFile(hPort, buffer, 1024, &numRead, &olap) )
            {
                // Overlapped read returned immediately with data
                if ( numRead > 0 )
                {
                    result = buffer[0];
                }
            }
            else
            {
                // Check if operation pending or error
                error = GetLastError();
                if ( error == ERROR_IO_PENDING )
                {
                    inProgress = TRUE;
                }
                else
                {
                    // Handle error
                }
            }
        }

        if ( result == -1 ) // If no immediate result...
        {
            // Wait for 'wait' milliseconds (1 second in this example)
            if (WaitForSingleObject(olap.hEvent, wait) == WAIT_OBJECT_0)
            {
                // Didn't time out, so get the data and reset the event
                GetOverlappedResult(hPort, &olap, &numRead, FALSE);
                if ( numRead > 0 )
                {
                    result = buffer[0];
                }
                ResetEvent(olap.hEvent);
                inProgress = FALSE;
            }
        }

        if ( result != -1 )
        {
            // Process data here
        }

        // Check exit condition - I usually pass an event to the thread...
        // if ( WaitForSingleObject(hExitEvent, 0) == WAIT_OBJECT_0 ) break;
    }
------------------------------------------

0
 
LVL 4

Author Comment

by:somnatic
ID: 11807211
ooook .. now this looks like it could work ..

Thanks to all who answered in this Thread
I'll split the points to the two people who helped me most ...

Thank you all ...
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.
Suggested Courses
Course of the Month17 days, 14 hours left to enroll

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question