Ignore:
Timestamp:
Dec 6, 2001, 4:57:52 PM (24 years ago)
Author:
sandervl
Message:

overlapped io updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/overlappedio.cpp

    r7552 r7560  
    1 /* $Id: overlappedio.cpp,v 1.4 2001-12-05 19:24:37 sandervl Exp $ */
     1/* $Id: overlappedio.cpp,v 1.5 2001-12-06 15:57:52 sandervl Exp $ */
    22
    33/*
     
    163163{
    164164    LPASYNCIOREQUEST lpRequest;
     165    LPOVERLAPPED     lpOverlapped;
    165166    HANDLE hEvents[2];
    166     DWORD  ret;
     167    DWORD  ret, dwTimeOut, dwResult;
    167168    int    index;
    168169
     
    217218        ::LeaveCriticalSection(&critsect);
    218219
     220        lpOverlapped = lpRequest->lpOverlapped;;
     221
    219222        switch(dwOperation) {
    220223        case ASYNCIO_READ:
    221224        case ASYNCIO_READWRITE:
    222             lpReadHandler(lpRequest);
     225            lpReadHandler(lpRequest, &dwResult, NULL);
     226            lpOverlapped->Internal     = lpRequest->dwLastError;
     227            lpOverlapped->InternalHigh = dwResult;
     228            if(lpRequest->lpdwResult) {
     229                *lpRequest->lpdwResult = dwResult;
     230            }
     231            //wake up user thread
     232            ::SetEvent(lpOverlapped->hEvent);
     233            delete lpRequest;
    223234            break;
    224235
    225236        case ASYNCIO_WRITE:
    226             lpWriteHandler(lpRequest);
     237            lpWriteHandler(lpRequest, &dwResult, NULL);
     238            lpOverlapped->Internal     = lpRequest->dwLastError;
     239            lpOverlapped->InternalHigh = dwResult;
     240            if(lpRequest->lpdwResult) {
     241                *lpRequest->lpdwResult = dwResult;
     242            }
     243            //wake up user thread
     244            ::SetEvent(lpOverlapped->hEvent);
     245            delete lpRequest;
    227246            break;
    228247
    229248        case ASYNCIO_POLL:
    230             lpPollHandler(lpRequest);
     249            while(TRUE)
     250            {
     251                dwTimeOut = 0;
     252                if(lpPollHandler(lpRequest, &dwResult, &dwTimeOut) == TRUE) {
     253                    break;
     254                }
     255                if(dwTimeOut == 0) {
     256                    dprintf(("!ERROR!: lpPollHandler returned timeout 0!!"));
     257                    DebugInt3();
     258                    break;
     259                }
     260                Sleep(dwTimeOut);
     261            }
     262            lpOverlapped->Internal     = lpRequest->dwLastError;
     263            lpOverlapped->InternalHigh = dwResult;
     264            if(lpRequest->lpdwResult) {
     265                *lpRequest->lpdwResult = dwResult;
     266            }
     267            //wake up user thread
     268            ::SetEvent(lpOverlapped->hEvent);
     269            delete lpRequest;
    231270            break;
    232271        }
     
    236275//******************************************************************************
    237276//******************************************************************************
    238 BOOL OverlappedIOHandler::WriteFile(HANDLE        hOS2Handle,
     277BOOL OverlappedIOHandler::WriteFile(HANDLE        hHandle,
    239278                                    LPCVOID       lpBuffer,
    240279                                    DWORD         nNumberOfBytesToWrite,
     
    246285    LPASYNCIOREQUEST lpRequest, current;
    247286    int              index;
     287
     288    if(!lpOverlapped || lpOverlapped->hEvent == 0) {
     289        ::SetLastError(ERROR_INVALID_PARAMETER);
     290        return FALSE;
     291    }
    248292 
    249293    lpRequest = new ASYNCIOREQUEST;
     
    253297    }
    254298    lpRequest->dwAsyncType         = ASYNCIO_WRITE;
    255     lpRequest->hOS2Handle          = hOS2Handle;
     299    lpRequest->hHandle             = hHandle;
    256300    lpRequest->lpBuffer            = lpBuffer;
    257301    lpRequest->nNumberOfBytes      = nNumberOfBytesToWrite;
    258     lpRequest->lpResult            = lpNumberOfBytesWritten;
     302    lpRequest->lpdwResult          = lpNumberOfBytesWritten;
    259303    lpRequest->lpOverlapped        = lpOverlapped;
    260304    lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     
    278322    ::LeaveCriticalSection(&critsect);
    279323
     324    lpOverlapped->Internal     = STATUS_PENDING;
     325    lpOverlapped->InternalHigh = 0;
     326    lpOverlapped->Offset       = 0;
     327    lpOverlapped->OffsetHigh   = 0;
     328    //reset overlapped semaphore to non-signalled
     329    ::ResetEvent(lpOverlapped->hEvent);
     330
    280331    //wake up async thread
    281332    ::SetEvent((dwAsyncType == ASYNCIO_READWRITE) ? hEventRead : hEventWrite);
     
    286337//******************************************************************************
    287338//******************************************************************************
    288 BOOL OverlappedIOHandler::ReadFile(HANDLE        hOS2Handle,
     339BOOL OverlappedIOHandler::ReadFile(HANDLE        hHandle,
    289340                                   LPCVOID       lpBuffer,
    290341                                   DWORD         nNumberOfBytesToRead,
     
    295346{
    296347    LPASYNCIOREQUEST lpRequest, current;
     348
     349    if(!lpOverlapped || lpOverlapped->hEvent == 0) {
     350        ::SetLastError(ERROR_INVALID_PARAMETER);
     351        return FALSE;
     352    }
    297353 
    298354    lpRequest = new ASYNCIOREQUEST;
     
    302358    }
    303359    lpRequest->dwAsyncType         = ASYNCIO_READ;
    304     lpRequest->hOS2Handle          = hOS2Handle;
     360    lpRequest->hHandle             = hHandle;
    305361    lpRequest->lpBuffer            = lpBuffer;
    306362    lpRequest->nNumberOfBytes      = nNumberOfBytesToRead;
    307     lpRequest->lpResult            = lpNumberOfBytesRead;
     363    lpRequest->lpdwResult          = lpNumberOfBytesRead;
    308364    lpRequest->lpOverlapped        = lpOverlapped;
    309365    lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     
    322378    ::LeaveCriticalSection(&critsect);
    323379
     380    lpOverlapped->Internal     = STATUS_PENDING;
     381    lpOverlapped->InternalHigh = 0;
     382    lpOverlapped->Offset       = 0;
     383    lpOverlapped->OffsetHigh   = 0;
     384    //reset overlapped semaphore to non-signalled
     385    ::ResetEvent(lpOverlapped->hEvent);
     386
    324387    //wake up async thread
    325388    ::SetEvent(hEventRead);
     
    329392//******************************************************************************
    330393//******************************************************************************
    331 BOOL OverlappedIOHandler::CancelIo(HANDLE hOS2Handle)
    332 {
     394BOOL OverlappedIOHandler::WaitForEvent(HANDLE        hHandle,
     395                                       LPDWORD       lpfdwEvtMask,
     396                                       LPOVERLAPPED  lpOverlapped,
     397                                       LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
     398                                       DWORD         dwUserData)
     399{
     400    LPASYNCIOREQUEST lpRequest, current;
     401
     402    if(!lpOverlapped || lpOverlapped->hEvent == 0) {
     403        ::SetLastError(ERROR_INVALID_PARAMETER);
     404        return FALSE;
     405    }
     406 
     407    lpRequest = new ASYNCIOREQUEST;
     408    if(lpRequest == NULL) {
     409        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     410        return FALSE;
     411    }
     412    lpRequest->dwAsyncType         = ASYNCIO_POLL;
     413    lpRequest->hHandle             = hHandle;
     414    lpRequest->lpBuffer            = NULL;
     415    lpRequest->nNumberOfBytes      = 0;
     416    lpRequest->lpdwResult          = lpfdwEvtMask;
     417    lpRequest->lpOverlapped        = lpOverlapped;
     418    lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     419    lpRequest->dwUserData          = dwUserData;
     420    lpRequest->next                = NULL;
     421
     422    ::EnterCriticalSection(&critsect);
     423    if(pending[ASYNC_INDEX_POLL]) {
     424         current = pending[ASYNC_INDEX_READ];
     425         while(current->next) {
     426             current = current->next;
     427         }
     428         current->next = lpRequest;
     429    }
     430    else pending[ASYNC_INDEX_POLL] = lpRequest;
     431    ::LeaveCriticalSection(&critsect);
     432
     433    lpOverlapped->Internal     = STATUS_PENDING;
     434    lpOverlapped->InternalHigh = 0;
     435    lpOverlapped->Offset       = 0;
     436    lpOverlapped->OffsetHigh   = 0;
     437    //reset overlapped semaphore to non-signalled
     438    ::ResetEvent(lpOverlapped->hEvent);
     439
     440    //wake up async thread
     441    ::SetEvent(hEventPoll);
     442    ::SetLastError(ERROR_IO_PENDING);
    333443    return FALSE;
    334444}
    335445//******************************************************************************
    336446//******************************************************************************
    337 BOOL OverlappedIOHandler::GetOverlappedResult(HANDLE        hOS2Handle,
    338                                               LPOVERLAPPED  lpoOverlapped,
     447BOOL OverlappedIOHandler::CancelIo(HANDLE hHandle)
     448{
     449    LPASYNCIOREQUEST lpRequest;
     450
     451    for(int i=ASYNC_INDEX_READ;i<NR_ASYNC_OPERATIONS;i++)
     452    {
     453        while(TRUE) {
     454            lpRequest = findAndRemoveRequest(i, hHandle);
     455            if(lpRequest) {
     456                 delete lpRequest;
     457            }
     458            else break;
     459        }
     460    }
     461    //TODO: return error if there were no pending requests???
     462    ::SetLastError(ERROR_SUCCESS);
     463    return TRUE;
     464}
     465//******************************************************************************
     466//******************************************************************************
     467BOOL OverlappedIOHandler::GetOverlappedResult(HANDLE        hHandle,
     468                                              LPOVERLAPPED  lpOverlapped,
    339469                                              LPDWORD       lpcbTransfer,
    340470                                              DWORD         dwTimeout)
    341471{
    342     return FALSE;
    343 }
    344 //******************************************************************************
    345 //******************************************************************************
     472    DWORD ret;
     473
     474    ret = ::WaitForSingleObject(lpOverlapped->hEvent, dwTimeout);
     475
     476    if(lpcbTransfer)
     477        *lpcbTransfer = lpOverlapped->InternalHigh;
     478
     479    ::SetLastError(lpOverlapped->Internal);
     480
     481    return (ret == WAIT_OBJECT_0);
     482}
     483//******************************************************************************
     484//******************************************************************************
     485LPASYNCIOREQUEST OverlappedIOHandler::findAndRemoveRequest(int index, HANDLE hHandle)
     486{
     487    LPASYNCIOREQUEST lpRequest, lpFound = NULL;
     488
     489    ::EnterCriticalSection(&critsect);
     490    if(pending[index])
     491    {
     492        if(pending[index]->hHandle != hHandle)
     493        {
     494            lpRequest = pending[index];
     495            while(lpRequest->next) {
     496                if(lpRequest->next->hHandle == hHandle) {
     497                        lpFound = lpRequest->next;
     498                        lpRequest->next = lpFound->next;
     499                        break;
     500                }
     501                lpRequest = lpRequest->next;
     502            }
     503        }
     504        else {
     505            lpFound = pending[index];
     506            pending[index] = lpFound->next;
     507        }
     508    }
     509    ::LeaveCriticalSection(&critsect);
     510    return lpFound;
     511}
     512//******************************************************************************
     513//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.