Ignore:
Timestamp:
Dec 7, 2001, 3:13:39 PM (24 years ago)
Author:
sandervl
Message:

overlapped io, com, thread & process updates

File:
1 edited

Legend:

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

    r7564 r7567  
    1 /* $Id: overlappedio.cpp,v 1.6 2001-12-07 11:28:11 sandervl Exp $ */
     1/* $Id: overlappedio.cpp,v 1.7 2001-12-07 14:13:38 sandervl Exp $ */
    22
    33/*
     
    3636    }
    3737
    38     pending[ASYNC_INDEX_READ] = pending[ASYNC_INDEX_WRITE] = pending [ASYNC_INDEX_POLL] = NULL;
     38    pending[ASYNC_INDEX_READ] = pending[ASYNC_INDEX_WRITE]  = NULL;
     39    pending [ASYNC_INDEX_POLL] = pending [ASYNC_INDEX_BUSY] = NULL;
    3940
    4041    this->lpReadHandler       = lpReadHandler;
     
    165166    LPOVERLAPPED     lpOverlapped;
    166167    HANDLE hEvents[2];
     168    HANDLE hEventsWait[2];
     169    HANDLE hHandle;
    167170    DWORD  ret, dwTimeOut, dwResult;
    168171    int    index;
     
    196199            break;
    197200        }
    198         if(ret == WAIT_FAILED) {
    199             dprintf(("!WARNING!: WaitForMultipleObjects -> WAIT_FAILED!"));
    200             break;
    201         }
    202201        //if hEventExit has been signalled, then we are told to exit
    203202        if(ret == (WAIT_OBJECT_0+1)) {
     
    215214        lpRequest       = pending[index];
    216215        pending[index]  = lpRequest->next;
    217         lpRequest->next = NULL;
     216
     217        //add to in process list
     218        lpRequest->next = pending[ASYNC_INDEX_BUSY];
     219        pending[ASYNC_INDEX_BUSY] = lpRequest;
    218220        ::LeaveCriticalSection(&critsect);
    219221
    220222        lpOverlapped = lpRequest->lpOverlapped;;
     223        hHandle      = lpRequest->hHandle;
    221224
    222225        switch(dwOperation) {
    223226        case ASYNCIO_READ:
    224227        case ASYNCIO_READWRITE:
    225             lpReadHandler(lpRequest, &dwResult, NULL);
     228            lpRequest->dwLastError = lpReadHandler(lpRequest, &dwResult, NULL);
    226229            lpOverlapped->Internal     = lpRequest->dwLastError;
    227230            lpOverlapped->InternalHigh = dwResult;
     
    229232                *lpRequest->lpdwResult = dwResult;
    230233            }
     234            if(lpRequest->dwAsyncType == ASYNCIO_READ) {
     235                 dprintf(("ASYNCIO_READ %x finished; result %x, last error %d", lpOverlapped, dwResult, lpRequest->dwLastError));
     236            }
     237            else dprintf(("ASYNCIO_WRITE %x finished; result %x, last error %d", lpOverlapped, dwResult, lpRequest->dwLastError));
    231238            //wake up user thread
    232239            ::SetEvent(lpOverlapped->hEvent);
    233             delete lpRequest;
    234240            break;
    235241
    236242        case ASYNCIO_WRITE:
    237             lpWriteHandler(lpRequest, &dwResult, NULL);
     243            lpRequest->dwLastError = lpWriteHandler(lpRequest, &dwResult, NULL);
    238244            lpOverlapped->Internal     = lpRequest->dwLastError;
    239245            lpOverlapped->InternalHigh = dwResult;
     
    241247                *lpRequest->lpdwResult = dwResult;
    242248            }
     249            dprintf(("ASYNCIO_WRITE %x finished; result %x, last error %d", lpOverlapped, dwResult, lpRequest->dwLastError));
    243250            //wake up user thread
    244251            ::SetEvent(lpOverlapped->hEvent);
    245             delete lpRequest;
    246252            break;
    247253
    248254        case ASYNCIO_POLL:
     255            hEventsWait[0] = lpRequest->hEventCancel;
     256            hEventsWait[1] = hEventExit;
     257            ret = WAIT_TIMEOUT;
    249258            while(TRUE)
    250259            {
    251260                dwTimeOut = 0;
    252                 if(lpPollHandler(lpRequest, &dwResult, &dwTimeOut) == TRUE) {
     261                lpRequest->dwLastError = lpPollHandler(lpRequest, &dwResult, &dwTimeOut);
     262                if(lpRequest->dwLastError != ERROR_IO_PENDING) {
    253263                    break;
    254264                }
     
    258268                    break;
    259269                }
    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;
     270                //sleep a while to avoid wasting too many cpu cycles; we are woken up when a timeout occurs,
     271                //when the operation is cancelled or when the process exits
     272                ret = WaitForMultipleObjects(2, hEventsWait, FALSE, dwTimeOut);
     273                if(ret != WAIT_TIMEOUT) {
     274                    dprintf(("ASYNCIO_POLL: WaitForSingleObject didn't time out, abort (ret = %x)", ret));
     275                    break;
     276                }
     277            }
     278            //Don't access the overlapped & result memory when CancelIo was used to cancel the operation
     279            if(ret == WAIT_TIMEOUT)
     280            {
     281                dprintf(("ASYNCIO_POLL %x: result %x, last error %d", lpOverlapped, dwResult, lpRequest->dwLastError));
     282                lpOverlapped->Internal     = lpRequest->dwLastError;
     283                lpOverlapped->InternalHigh = dwResult;
     284                if(lpRequest->lpdwResult) {
     285                    *lpRequest->lpdwResult = dwResult;
     286                }
     287                //wake up user thread
     288                ::SetEvent(lpOverlapped->hEvent);
     289            }
    270290            break;
    271291        }
     292        //remove from in-process list and delete async request object
     293        findAndRemoveRequest(ASYNC_INDEX_BUSY, hHandle);
     294        delete lpRequest;
    272295    }
    273296    return 0;
     
    397420//******************************************************************************
    398421BOOL OverlappedIOHandler::WaitForEvent(HANDLE        hHandle,
     422                                       DWORD         dwEventMask,
    399423                                       LPDWORD       lpfdwEvtMask,
    400424                                       LPOVERLAPPED  lpOverlapped,
     
    424448    lpRequest->dwUserData          = dwUserData;
    425449    lpRequest->dwTimeOut           = dwTimeOut;
     450    lpRequest->dwEventMask         = dwEventMask;
    426451    lpRequest->next                = NULL;
    427452
     
    459484        while(TRUE) {
    460485            lpRequest = findAndRemoveRequest(i, hHandle);
     486
    461487            if(lpRequest) {
    462                  delete lpRequest;
     488                 ::SetEvent(lpRequest->hEventCancel);   //cancel pending operation
     489                 if(i != ASYNC_INDEX_BUSY) {//thread that handles the request will delete it
     490                    delete lpRequest;
     491                 }
    463492            }
    464493            else break;
     
    518547//******************************************************************************
    519548//******************************************************************************
     549
Note: See TracChangeset for help on using the changeset viewer.