vendredi 18 février 2022

Error code 1236 from GetQueuedCompletionStatus function

I get error code 1236 from GetQueuedCompletionStatus() function, I tried to debug with vs but still cant figure it out. Any help would be greatly appreciated. Let me know if you may need anymore information. I create new thread whenever create room request sent to server. This is my workerThread:

unsigned __stdcall serverWorkerThread(void* completionPortID) {
    HANDLE completionPort = (HANDLE)completionPortID;
    DWORD transferredBytes, flag = 0;
    LPPER_HANDLE_DATA perHandleData;
    LPPER_IO_DATA perIoData;
    LPUSER user;
    while (1) {
        if (GetQueuedCompletionStatus(completionPort, &transferredBytes, (PULONG_PTR)&perHandleData, (LPOVERLAPPED*)&perIoData, INFINITE) == 0) {
            if (GetLastError() != 64) {
                printf("Error %d: GetQueuedCompletionStatus() failed\n", GetLastError());
            }
            else {
                user = (LPUSER)perIoData;
                disconnect(user);
            }
            return 0;
        }
        user = (LPUSER)perIoData;
        if (transferredBytes == 0) {
            disconnect(user);
            continue;
        }
        if (perIoData->operation == RECEIVE) {
            perIoData->recvBytes += transferredBytes;
        }
        else {
            perIoData->sendBytes -= transferredBytes;
            strcpy_s(perIoData->sendBuff, BUFF_SIZE, perIoData->sendBuff + transferredBytes);
        }
        int len;
        if (perIoData->sendBytes > 0) {
            sendMess(user);
        }
        else if ((len = checkEndMessage(perIoData->recvBuff, perIoData->recvBytes)) != -1) {
            string message(perIoData->recvBuff, perIoData->recvBuff + len - 2);
            string result = handleRequest(user, message);
            perIoData->recvBytes -= len;
            strcpy_s(perIoData->recvBuff, BUFF_SIZE, perIoData->recvBuff + len);
            strcpy_s(perIoData->sendBuff, BUFF_SIZE, result.c_str());
            strcat_s(perIoData->sendBuff, BUFF_SIZE, DELIMITER);
            perIoData->sendBytes = result.size() + 2;
            sendMess(user);
        }
        else {
            recvMess(user);
        }
    }
}

This is my room thread:

unsigned __stdcall examThread(void* ptrRoom) {
    LPROOM room = (LPROOM)ptrRoom;
    string question = "EXAM " + room->exam->question;
    std::chrono::system_clock::time_point startTime;
    getTime(room->startTime, startTime);
    std::this_thread::sleep_until(startTime);
    EnterCriticalSection(&criticalSection);
    room->status = ON_GOING;
    LeaveCriticalSection(&criticalSection);
    for (USER* user : room->contestant) {
        strcpy_s(user->perIoData.sendBuff, BUFF_SIZE, "STARTTEST ");
        strcat_s(user->perIoData.sendBuff, BUFF_SIZE, question.c_str());
        strcat_s(user->perIoData.sendBuff, BUFF_SIZE, "\r\n");
        sendMess(user);
    }
    std::this_thread::sleep_for(std::chrono::minutes(room->duration));
    EnterCriticalSection(&criticalSection);
    room->status = FINISH;
    LeaveCriticalSection(&criticalSection);
    std::this_thread::sleep_for(std::chrono::hours(1));
    EnterCriticalSection(&criticalSection);
    listRoom.erase(std::find(listRoom.begin(), listRoom.end(), room));
    LeaveCriticalSection(&criticalSection);
    delete room;
    return 0;
}

After sendMess(user), I return error code 1236 from GetQueuedCompletionStatus. This is my struct:

typedef struct PER_IO_DATA {
    WSAOVERLAPPED overlapped;
    WSABUF wBuff;
    char recvBuff[BUFF_SIZE];
    char sendBuff[BUFF_SIZE];
    int operation;
    int recvBytes;
    int sendBytes;
    PER_IO_DATA() {
        ZeroMemory(&overlapped, sizeof(WSAOVERLAPPED));
        ZeroMemory(recvBuff, BUFF_SIZE);
        ZeroMemory(sendBuff, BUFF_SIZE);
        sendBytes = 0;
        recvBytes = 0;
    }
} *LPPER_IO_DATA;

typedef struct USER {
    PER_IO_DATA perIoData;
    PER_HANDLE_DATA perHandleData;
    string name;
    int status;
    LPROOM inRoom;
    USER() {
        status = CONNECTED;
    }
} *LPUSER; 

sendMess function:

void sendMess(LPUSER user) {
    LPPER_HANDLE_DATA perHanleData = &(user->perHandleData);
    LPPER_IO_DATA perIoData = &(user->perIoData);
    DWORD transferredBytes, flag = 0;
    perIoData->operation = SEND;
    perIoData->wBuff.buf = perIoData->sendBuff;
    perIoData->wBuff.len = perIoData->sendBytes;
    if (WSASend(perHanleData->socket, &(perIoData->wBuff), 1, &transferredBytes, flag, &(perIoData->overlapped), 0) == SOCKET_ERROR) {
        if (WSAGetLastError() != WSA_IO_PENDING) {
            printf("Error %d: WSASend() 1 failed", WSAGetLastError());
        }
    }
}

Aucun commentaire:

Enregistrer un commentaire