c - WriteFile med IO Completion Port Issue

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har denne kode, der grundlæggende skriver til en fil 5 gange ved hjælp af IO-afslutningsporte. Som du har gættet, virker det ikke rigtig godt. Spørgsmålet er, at jeg forventer 'hej' at blive skrevet til filen 5 gange, men det ender altid med at skrive kun en 'hej'. Jeg er forvirret, fordi programmet udskriver 'skrev 5 byte' 5 gange, så jeg antager, at skrivningerne fuldender ok.


Kan nogen se et problem med dette?


#include <windows.h>
#include <stdio.h>

#define IOCP\_NOMORE 3
#define IOCP\_WRITE 1

HANDLE hWriteIoCp;

typedef struct \_OVERLAPIOINFO {
    OVERLAPPED overlapped;
    HANDLE hFile;
} OVERLAPIOINFO;

HANDLE CreateNewCompletionPort()
{
    return CreateIoCompletionPort(INVALID\_HANDLE\_VALUE, NULL, 0, 0);
}

BOOL AssociateFileCompletionPort(HANDLE hIoPort, HANDLE hFile, DWORD completionKey)
{
    HANDLE h = CreateIoCompletionPort(hFile, hIoPort, completionKey, 0);
    return h == hIoPort;
}

DWORD WINAPI SaveFileWorkerThread(void *empty)
{
    ULONG\_PTR completionKey;
    BOOL completionStatus;
    DWORD bytesTransferred;
    DWORD err;
    OVERLAPPED *overlap;
    OVERLAPIOINFO *info;

    for (;;)
    {
        completionStatus = GetQueuedCompletionStatus(hWriteIoCp, &bytesTransferred, &completionKey, &overlap, INFINITE);
        err = GetLastError();

        if (completionStatus) 
        {
            switch(completionKey)
            {
            case IOCP\_WRITE:
                fprintf(stderr, "wrote \%d bytes
", bytesTransferred);
                break;

            case IOCP\_NOMORE:
                fprintf(stderr, "done!");
                info = (OVERLAPIOINFO *) overlap;
                CloseHandle(info->hFile);
                free(info);
                break;

            }
        } 
        else 
        {
            if (overlap != NULL) 
                fprintf(stderr, "overlap not null");
            else 
                if (err != WAIT\_TIMEOUT)
                    fprintf(stderr, "timeout");
        }
    }

}

int main()
{
    HANDLE hSaveFile;
    OVERLAPIOINFO *saveFileOverlap;
    char buf[] = "hello";

    hWriteIoCp = CreateNewCompletionPort();
    CreateThread(NULL, 0, SaveFileWorkerThread, NULL, 0, NULL);

    if ((hSaveFile = CreateFileA("C:\received.txt", GENERIC\_READ | GENERIC\_WRITE, 0, NULL, 
        CREATE\_ALWAYS, FILE\_FLAG\_OVERLAPPED, NULL)) == INVALID\_HANDLE\_VALUE)
        fprintf(stderr, "unable to create file
");

    saveFileOverlap = (OVERLAPIOINFO *) malloc(sizeof(*saveFileOverlap));
    memset(&(saveFileOverlap->overlapped), 0, sizeof(saveFileOverlap->overlapped));
    saveFileOverlap->hFile = hSaveFile;
    AssociateFileCompletionPort(hWriteIoCp, saveFileOverlap->hFile, IOCP\_WRITE);

    for (int i = 0; i < 5; i++)
        if (!WriteFile(saveFileOverlap->hFile, buf, strlen(buf), NULL, &(saveFileOverlap->overlapped)))
            if (GetLastError() != ERROR\_IO\_PENDING)
                fprintf(stderr, "error writing file
");

    PostQueuedCompletionStatus(hWriteIoCp, 0, IOCP\_NOMORE, &(saveFileOverlap->overlapped));

    system("pause");
}

Bedste reference


du skriver 5 gange til filen, men altid til position 0 - du skal indstille forskydningen som en del af parameteren lpOVERLAPPED. [3]