|
|
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
unsigned char writebuff[10][10000]; OVERLAPPED WriteOl[10]; HANDLE hFile; HANDLE StartTrailingWriteEvent; HANDLE EndedTrailingWrites;
DWORD QueueOtherWrites( LPVOID Trash ) {
DWORD k;
UNREFERENCED_PARAMETER(Trash);
WaitForSingleObject(StartTrailingWriteEvent,-1); printf("Wait Satisfied Sleeping for 3 seconds\n"); Sleep(3000);
for ( k = 5; k <= 9; k++ ) {
DWORD NumberWritten; BOOL WriteDone;
WriteDone = WriteFile( hFile, writebuff[k], 10000, &NumberWritten, &WriteOl[k] );
if (!WriteDone) {
DWORD LastError; LastError = GetLastError();
if (LastError != ERROR_IO_PENDING) {
printf("Status of failed write %d is: %d\n",k,LastError);
}
}
}
printf("Trailing Writes are all queued thread waits until all are done\n");
WaitForSingleObject(EndedTrailingWrites,-1);
return 1;
}
void main(int argc,char *argv[]) {
DCB MyDcb; char *MyPort = "COM1"; DWORD j; DWORD ThreadId; DWORD Errors; COMSTAT LocalStat;
if (argc > 1) {
MyPort = argv[1];
}
for ( j = 0; j <= 9; j++ ) { if (!(WriteOl[j].hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ))) {
printf("Could not create the write event %d.\n",j);
} else {
WriteOl[j].Internal = 0; WriteOl[j].InternalHigh = 0; WriteOl[j].Offset = 0; WriteOl[j].OffsetHigh = 0;
} }
if (!(StartTrailingWriteEvent = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create trailing write event\n"); goto cleanup;
}
if (!(EndedTrailingWrites = CreateEvent( NULL, TRUE, FALSE, NULL ))) {
printf("Could not create ending trailing write event\n"); goto cleanup;
}
if ((hFile = CreateFile( MyPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL )) != ((HANDLE)-1)) {
printf("We successfully opened the %s port.\n",MyPort);
//
// Create the thread that will wait for the
// trailing write event before it queues its reads.
//
if (!CreateThread( NULL, 0, QueueOtherWrites, NULL, 0, &ThreadId )) {
printf("Could not create the second thread.\n"); goto cleanup;
}
//
// We've successfully opened the file. Set the state of
// the comm device. First we get the old values and
// adjust to our own.
//
if (!GetCommState( hFile, &MyDcb )) {
printf("Couldn't get the comm state: %d\n",GetLastError()); exit(1);
}
MyDcb.BaudRate = 19200; MyDcb.ByteSize = 8; MyDcb.Parity = NOPARITY; MyDcb.StopBits = ONESTOPBIT;
if (SetCommState( hFile, &MyDcb )) {
DWORD k;
for ( k = 0; k <= 4; k++ ) {
DWORD NumberWritten; BOOL WriteDone;
WriteDone = WriteFile( hFile, writebuff[k], 10000, &NumberWritten, &WriteOl[k] );
if (!WriteDone) {
DWORD LastError; LastError = GetLastError();
if (LastError != ERROR_IO_PENDING) {
printf("Status of failed write %d is: %d\n",k,LastError); goto cleanup;
}
}
}
SetEvent(StartTrailingWriteEvent);
if (!FlushFileBuffers(hFile)) {
printf("Couldn't flush %d\n",GetLastError());
} else {
printf("Flushed\n");
}
//
// Insure that the first five writes are done.
//
for ( k = 0; k <= 4; k++ ) {
DWORD NumberTransferred;
if (!GetOverlappedResult( hFile, &WriteOl[k], &NumberTransferred, FALSE )) {
printf("Write %d was not complete!!\n",k);
} else {
if (NumberTransferred != 10000) {
printf("Write %d transferred only %d bytes\n",k,NumberTransferred);
}
}
}
//
// Wrap around until the count is zero.
//
LocalStat.cbOutQue = 1;
while (LocalStat.cbOutQue) {
if (!ClearCommError( hFile, &Errors, &LocalStat )) {
printf("Couldn't call ClearCommError: %d\n",GetLastError()); exit(1);
} if (Errors) { printf("For some odd reason we had errors: %x\n",Errors); } printf("Currently in output queue: %d\n",LocalStat.cbOutQue); Sleep(2000);
} //
// Wait for the last writes to complete.
//
for ( k = 9; k >= 5; k-- ) {
DWORD NumberTransferred;
if (!GetOverlappedResult( hFile, &WriteOl[k], &NumberTransferred, TRUE )) {
printf("Bad status from write %d status is %d\n",k,GetLastError());
} else {
if (NumberTransferred != 10000) {
printf("Write %d transferred only %d bytes\n",k,NumberTransferred);
}
}
}
SetEvent(EndedTrailingWrites);
} else {
printf("Couldn't set the comm state\n");
}
} else {
printf("Couldn't open the comm port\n");
}
cleanup:;
}
|