Changeset 7552 for trunk/src


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

overlapped io updates

Location:
trunk/src/kernel32
Files:
2 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}
  • trunk/src/kernel32/overlappedio.h

    r7551 r7552  
    1 /* $Id: overlappedio.h,v 1.2 2001-12-05 18:06:03 sandervl Exp $ */
     1/* $Id: overlappedio.h,v 1.3 2001-12-05 19:24:37 sandervl Exp $ */
    22
    33/*
     
    1313#define __OVERLAPPEDIO_H__
    1414
    15 #define EVENT_READ              1
    16 #define EVENT_WRITE             2
    17 #define EVENT_READWRITE         (EVENT_WRITE|EVENT_READ)
    18 #define EVENT_POLL              4
     15#define NR_ASYNC_OPERATIONS     3
     16#define ASYNC_INDEX_READ        0
     17#define ASYNC_INDEX_WRITE       1
     18#define ASYNC_INDEX_POLL        2
     19
     20#define ASYNCIO_READ            1
     21#define ASYNCIO_WRITE           2
     22#define ASYNCIO_READWRITE       4
     23#define ASYNCIO_POLL            8
    1924
    2025//forward decl
     
    2227
    2328typedef struct {
    24     DWORD                fEvent;
     29    DWORD                dwOperation;
    2530    OverlappedIOHandler *lpOverlappedObj;
    2631} OVERLAPPED_THREAD_PARAM, *LPOVERLAPPED_THREAD_PARAM;
    2732
    28 typedef DWORD (* SYSTEM LPOVERLAPPED_HANDLER)(DWORD dwUserData, LPOVERLAPPED lpOverlapped);
     33typedef struct tagOVERLAPPED_ODIN{
     34  DWORD               dwAsyncType;
     35  HANDLE              hOS2Handle;
     36  LPCVOID             lpBuffer;
     37  ULONG               nNumberOfBytes;
     38  LPOVERLAPPED        lpOverlapped;
     39  LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine;
     40  DWORD              *lpResult;
     41  DWORD               dwUserData;
     42  tagOVERLAPPED_ODIN *next;
     43} ASYNCIOREQUEST, *LPASYNCIOREQUEST;
     44
     45typedef DWORD (* SYSTEM LPOVERLAPPED_HANDLER)(LPASYNCIOREQUEST lpRequest);
    2946
    3047enum OverlappedIOError {
    31   OutOfMemory, EventCreationFailed, ThreadCreationFailed
     48  InvalidParameter, OutOfMemory, EventCreationFailed, ThreadCreationFailed
    3249};
    3350
     
    4562                      LPDWORD       lpNumberOfBytesWritten,
    4663                      LPOVERLAPPED  lpOverlapped,
    47                       LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
     64                      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
     65                      DWORD         dwUserData);
    4866
    4967     BOOL   ReadFile(HANDLE        hOS2Handle,
     
    5270                     LPDWORD       lpNumberOfBytesRead,
    5371                     LPOVERLAPPED  lpOverlapped,
    54                      LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
     72                     LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
     73                     DWORD         dwUserData);
    5574
    5675     BOOL   CancelIo(HANDLE hOS2Handle);
     
    81100     CRITICAL_SECTION     critsect;
    82101
    83      //linked list of pending operations
    84      LPOVERLAPPED pending;
    85 
     102     DWORD                dwAsyncType;
     103     //[ASYNC_INDEX_READ]  list of pending read (+ write if half-duplex mode) operations
     104     //[ASYNC_INDEX_WRITE] list of pending write (full-duplex mode) operations
     105     //[ASYNC_INDEX_POLL]  list of pending poll operations
     106     LPASYNCIOREQUEST     pending[NR_ASYNC_OPERATIONS];
    86107
    87108     friend       DWORD CALLBACK OverlappedIOThread(LPVOID lpThreadParam);
Note: See TracChangeset for help on using the changeset viewer.