Ignore:
Timestamp:
Dec 5, 2001, 8:24:37 PM (24 years ago)
Author:
sandervl
Message:

overlapped io updates

File:
1 edited

Legend:

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

    r7551 r7552  
    1 /* $Id: overlappedio.cpp,v 1.3 2001-12-05 18:06:57 sandervl Exp $ */
     1/* $Id: overlappedio.cpp,v 1.4 2001-12-05 19:24:37 sandervl Exp $ */
    22
    33/*
     
    3232    OverlappedIOError errcode = OutOfMemory;
    3333
    34     pending                  = NULL;
    35     this->lpReadHandler      = lpReadHandler;
    36     this->lpWriteHandler     = lpWriteHandler;
    37     this->lpPollHandler      = lpPollHandler;
     34    if(lpReadHandler == NULL || lpPollHandler == NULL) {
     35        throw(InvalidParameter);
     36    }
     37
     38    pending[ASYNC_INDEX_READ] = pending[ASYNC_INDEX_WRITE] = pending [ASYNC_INDEX_POLL] = NULL;
     39
     40    this->lpReadHandler       = lpReadHandler;
     41    this->lpWriteHandler      = lpWriteHandler;
     42    this->lpPollHandler       = lpPollHandler;
    3843
    3944    ::InitializeCriticalSection(&critsect);
    40     hEventPoll   = ::CreateEventA(NULL, TRUE, FALSE, NULL);
    41     hEventRead   = ::CreateEventA(NULL, TRUE, FALSE, NULL);
    42     hEventWrite  = ::CreateEventA(NULL, TRUE, FALSE, NULL);
     45    //poll, read & write event semaphores are auto-reset (one thread wakes up
     46    //after a SetEvent call)
     47    hEventPoll   = ::CreateEventA(NULL, FALSE, FALSE, NULL);
     48    hEventRead   = ::CreateEventA(NULL, FALSE, FALSE, NULL);
     49    hEventWrite  = ::CreateEventA(NULL, FALSE, FALSE, NULL);
     50
     51    //the exit event semaphore is manual reset, because signalling this event
     52    //must be able to wake up multiple threads
    4353    hEventExit   = ::CreateEventA(NULL, TRUE, FALSE, NULL);
    4454    if(!hEventPoll || !hEventRead || !hEventWrite || !hEventExit)
     
    5262    LPOVERLAPPED_THREAD_PARAM threadparam;
    5363
     64    dwAsyncType = (lpWriteHandler) ? ASYNCIO_READ : ASYNCIO_READWRITE;
    5465    threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM));
    5566    if(!threadparam) goto outofmem;
    56 
    57     threadparam->fEvent          = (lpWriteHandler) ? EVENT_READ : EVENT_READWRITE;
     67    threadparam->dwOperation     = dwAsyncType;
    5868    threadparam->lpOverlappedObj = this;
    5969    hThreadRead  = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId);
     70
    6071    if(lpWriteHandler) {
     72        dwAsyncType |= ASYNCIO_WRITE;
     73
    6174        threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM));
    6275        if(!threadparam) goto outofmem;
    63         threadparam->fEvent          = EVENT_WRITE;
     76        threadparam->dwOperation     = ASYNCIO_WRITE;
    6477        threadparam->lpOverlappedObj = this;
    6578        hThreadWrite = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId);
     
    6780
    6881    if(lpPollHandler) {
     82        dwAsyncType |= ASYNCIO_POLL;
     83
    6984        threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM));
    7085        if(!threadparam) goto outofmem;
    71         threadparam->fEvent          = EVENT_POLL;
     86        threadparam->dwOperation     = ASYNCIO_POLL;
    7287        threadparam->lpOverlappedObj = this;
    7388        hThreadPoll  = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId);
     
    110125OverlappedIOHandler::~OverlappedIOHandler()
    111126{
    112     dprintf(("~OverlappedIOHandler: signalling overlapped serial threads"));
     127    dprintf(("~OverlappedIOHandler: signalling overlapped threads"));
    113128    ::SetEvent(hEventExit);
    114129
     
    129144{
    130145    LPOVERLAPPED_THREAD_PARAM threadparam = (LPOVERLAPPED_THREAD_PARAM)lpThreadParam;
    131     DWORD fEvent;
     146    DWORD dwOperation;
    132147    OverlappedIOHandler *lpOverlappedObj;
    133148
     
    137152    }
    138153    lpOverlappedObj = threadparam->lpOverlappedObj;
    139     fEvent          = threadparam->fEvent;
     154    dwOperation     = threadparam->dwOperation;
    140155    //free thread parameter first
    141156    free(threadparam);
    142157
    143     return lpOverlappedObj->threadHandler(fEvent);
    144 }
    145 //******************************************************************************
    146 //******************************************************************************
    147 DWORD OverlappedIOHandler::threadHandler(DWORD fEvent)
    148 {
     158    return lpOverlappedObj->threadHandler(dwOperation);
     159}
     160//******************************************************************************
     161//******************************************************************************
     162DWORD OverlappedIOHandler::threadHandler(DWORD dwOperation)
     163{
     164    LPASYNCIOREQUEST lpRequest;
    149165    HANDLE hEvents[2];
    150166    DWORD  ret;
    151 
    152     dprintf(("OverlappedIOThread: started for event %d", fEvent));
    153     switch(fEvent) {
    154     case EVENT_READ:
    155     case EVENT_READWRITE:
     167    int    index;
     168
     169    dprintf(("OverlappedIOThread: started for event %d", dwOperation));
     170    switch(dwOperation) {
     171    case ASYNCIO_READ:
     172    case ASYNCIO_READWRITE:
    156173        hEvents[0] = hEventRead;
     174        index      = ASYNC_INDEX_READ;
    157175        break;
    158176
    159     case EVENT_WRITE:
     177    case ASYNCIO_WRITE:
    160178        hEvents[0] = hEventWrite;
     179        index      = ASYNC_INDEX_WRITE;
    161180        break;
    162181
    163     case EVENT_POLL:
     182    case ASYNCIO_POLL:
    164183        hEvents[0] = hEventPoll;
     184        index      = ASYNC_INDEX_POLL;
    165185        break;
    166186    default:
     
    182202        if(ret == (WAIT_OBJECT_0+1)) {
    183203            dprintf(("end of threadHandler signalled"));
     204            break;
     205        }
     206        ::EnterCriticalSection(&critsect);
     207        if(pending[index] == NULL) {
     208            //oh, oh
     209            ::LeaveCriticalSection(&critsect);
     210            dprintf(("!ERROR!: overlapped thread woken up, but no tasks pending!!"));
     211            DebugInt3();
     212            continue;
     213        }
     214        lpRequest       = pending[index];
     215        pending[index]  = lpRequest->next;
     216        lpRequest->next = NULL;
     217        ::LeaveCriticalSection(&critsect);
     218
     219        switch(dwOperation) {
     220        case ASYNCIO_READ:
     221        case ASYNCIO_READWRITE:
     222            lpReadHandler(lpRequest);
     223            break;
     224
     225        case ASYNCIO_WRITE:
     226            lpWriteHandler(lpRequest);
     227            break;
     228
     229        case ASYNCIO_POLL:
     230            lpPollHandler(lpRequest);
    184231            break;
    185232        }
     
    194241                                    LPDWORD       lpNumberOfBytesWritten,
    195242                                    LPOVERLAPPED  lpOverlapped,
    196                                     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
    197 {
     243                                    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
     244                                    DWORD         dwUserData)
     245{
     246    LPASYNCIOREQUEST lpRequest, current;
     247    int              index;
     248 
     249    lpRequest = new ASYNCIOREQUEST;
     250    if(lpRequest == NULL) {
     251        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     252        return FALSE;
     253    }
     254    lpRequest->dwAsyncType         = ASYNCIO_WRITE;
     255    lpRequest->hOS2Handle          = hOS2Handle;
     256    lpRequest->lpBuffer            = lpBuffer;
     257    lpRequest->nNumberOfBytes      = nNumberOfBytesToWrite;
     258    lpRequest->lpResult            = lpNumberOfBytesWritten;
     259    lpRequest->lpOverlapped        = lpOverlapped;
     260    lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     261    lpRequest->dwUserData          = dwUserData;
     262    lpRequest->next                = NULL;
     263
     264    if(dwAsyncType == ASYNCIO_READWRITE) {
     265         index = ASYNC_INDEX_READ;
     266    }
     267    else index = ASYNC_INDEX_WRITE;
     268
     269    ::EnterCriticalSection(&critsect);
     270    if(pending[index]) {
     271         current = pending[index];
     272         while(current->next) {
     273             current = current->next;
     274         }
     275         current->next = lpRequest;
     276    }
     277    else pending[index] = lpRequest;
     278    ::LeaveCriticalSection(&critsect);
     279
     280    //wake up async thread
     281    ::SetEvent((dwAsyncType == ASYNCIO_READWRITE) ? hEventRead : hEventWrite);
     282
     283    ::SetLastError(ERROR_IO_PENDING);
    198284    return FALSE;
    199285}
     
    205291                                   LPDWORD       lpNumberOfBytesRead,
    206292                                   LPOVERLAPPED  lpOverlapped,
    207                                    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
    208 {
     293                                   LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
     294                                   DWORD         dwUserData)
     295{
     296    LPASYNCIOREQUEST lpRequest, current;
     297 
     298    lpRequest = new ASYNCIOREQUEST;
     299    if(lpRequest == NULL) {
     300        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     301        return FALSE;
     302    }
     303    lpRequest->dwAsyncType         = ASYNCIO_READ;
     304    lpRequest->hOS2Handle          = hOS2Handle;
     305    lpRequest->lpBuffer            = lpBuffer;
     306    lpRequest->nNumberOfBytes      = nNumberOfBytesToRead;
     307    lpRequest->lpResult            = lpNumberOfBytesRead;
     308    lpRequest->lpOverlapped        = lpOverlapped;
     309    lpRequest->lpCompletionRoutine = lpCompletionRoutine;
     310    lpRequest->dwUserData          = dwUserData;
     311    lpRequest->next                = NULL;
     312
     313    ::EnterCriticalSection(&critsect);
     314    if(pending[ASYNC_INDEX_READ]) {
     315         current = pending[ASYNC_INDEX_READ];
     316         while(current->next) {
     317             current = current->next;
     318         }
     319         current->next = lpRequest;
     320    }
     321    else pending[ASYNC_INDEX_READ] = lpRequest;
     322    ::LeaveCriticalSection(&critsect);
     323
     324    //wake up async thread
     325    ::SetEvent(hEventRead);
     326    ::SetLastError(ERROR_IO_PENDING);
    209327    return FALSE;
    210328}
Note: See TracChangeset for help on using the changeset viewer.