- Timestamp:
- Dec 5, 2001, 8:24:37 PM (24 years ago)
- 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 $ */ 2 2 3 3 /* … … 32 32 OverlappedIOError errcode = OutOfMemory; 33 33 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; 38 43 39 44 ::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 43 53 hEventExit = ::CreateEventA(NULL, TRUE, FALSE, NULL); 44 54 if(!hEventPoll || !hEventRead || !hEventWrite || !hEventExit) … … 52 62 LPOVERLAPPED_THREAD_PARAM threadparam; 53 63 64 dwAsyncType = (lpWriteHandler) ? ASYNCIO_READ : ASYNCIO_READWRITE; 54 65 threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM)); 55 66 if(!threadparam) goto outofmem; 56 57 threadparam->fEvent = (lpWriteHandler) ? EVENT_READ : EVENT_READWRITE; 67 threadparam->dwOperation = dwAsyncType; 58 68 threadparam->lpOverlappedObj = this; 59 69 hThreadRead = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId); 70 60 71 if(lpWriteHandler) { 72 dwAsyncType |= ASYNCIO_WRITE; 73 61 74 threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM)); 62 75 if(!threadparam) goto outofmem; 63 threadparam-> fEvent = EVENT_WRITE;76 threadparam->dwOperation = ASYNCIO_WRITE; 64 77 threadparam->lpOverlappedObj = this; 65 78 hThreadWrite = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId); … … 67 80 68 81 if(lpPollHandler) { 82 dwAsyncType |= ASYNCIO_POLL; 83 69 84 threadparam = (LPOVERLAPPED_THREAD_PARAM)malloc(sizeof(OVERLAPPED_THREAD_PARAM)); 70 85 if(!threadparam) goto outofmem; 71 threadparam-> fEvent = EVENT_POLL;86 threadparam->dwOperation = ASYNCIO_POLL; 72 87 threadparam->lpOverlappedObj = this; 73 88 hThreadPoll = ::CreateThread(NULL, 32*1024, OverlappedIOThread, (LPVOID)threadparam, 0, &dwThreadId); … … 110 125 OverlappedIOHandler::~OverlappedIOHandler() 111 126 { 112 dprintf(("~OverlappedIOHandler: signalling overlapped serialthreads"));127 dprintf(("~OverlappedIOHandler: signalling overlapped threads")); 113 128 ::SetEvent(hEventExit); 114 129 … … 129 144 { 130 145 LPOVERLAPPED_THREAD_PARAM threadparam = (LPOVERLAPPED_THREAD_PARAM)lpThreadParam; 131 DWORD fEvent;146 DWORD dwOperation; 132 147 OverlappedIOHandler *lpOverlappedObj; 133 148 … … 137 152 } 138 153 lpOverlappedObj = threadparam->lpOverlappedObj; 139 fEvent = threadparam->fEvent;154 dwOperation = threadparam->dwOperation; 140 155 //free thread parameter first 141 156 free(threadparam); 142 157 143 return lpOverlappedObj->threadHandler(fEvent); 144 } 145 //****************************************************************************** 146 //****************************************************************************** 147 DWORD OverlappedIOHandler::threadHandler(DWORD fEvent) 148 { 158 return lpOverlappedObj->threadHandler(dwOperation); 159 } 160 //****************************************************************************** 161 //****************************************************************************** 162 DWORD OverlappedIOHandler::threadHandler(DWORD dwOperation) 163 { 164 LPASYNCIOREQUEST lpRequest; 149 165 HANDLE hEvents[2]; 150 166 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: 156 173 hEvents[0] = hEventRead; 174 index = ASYNC_INDEX_READ; 157 175 break; 158 176 159 case EVENT_WRITE:177 case ASYNCIO_WRITE: 160 178 hEvents[0] = hEventWrite; 179 index = ASYNC_INDEX_WRITE; 161 180 break; 162 181 163 case EVENT_POLL:182 case ASYNCIO_POLL: 164 183 hEvents[0] = hEventPoll; 184 index = ASYNC_INDEX_POLL; 165 185 break; 166 186 default: … … 182 202 if(ret == (WAIT_OBJECT_0+1)) { 183 203 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); 184 231 break; 185 232 } … … 194 241 LPDWORD lpNumberOfBytesWritten, 195 242 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); 198 284 return FALSE; 199 285 } … … 205 291 LPDWORD lpNumberOfBytesRead, 206 292 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); 209 327 return FALSE; 210 328 } -
trunk/src/kernel32/overlappedio.h
r7551 r7552 1 /* $Id: overlappedio.h,v 1. 2 2001-12-05 18:06:03sandervl Exp $ */1 /* $Id: overlappedio.h,v 1.3 2001-12-05 19:24:37 sandervl Exp $ */ 2 2 3 3 /* … … 13 13 #define __OVERLAPPEDIO_H__ 14 14 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 19 24 20 25 //forward decl … … 22 27 23 28 typedef struct { 24 DWORD fEvent;29 DWORD dwOperation; 25 30 OverlappedIOHandler *lpOverlappedObj; 26 31 } OVERLAPPED_THREAD_PARAM, *LPOVERLAPPED_THREAD_PARAM; 27 32 28 typedef DWORD (* SYSTEM LPOVERLAPPED_HANDLER)(DWORD dwUserData, LPOVERLAPPED lpOverlapped); 33 typedef 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 45 typedef DWORD (* SYSTEM LPOVERLAPPED_HANDLER)(LPASYNCIOREQUEST lpRequest); 29 46 30 47 enum OverlappedIOError { 31 OutOfMemory, EventCreationFailed, ThreadCreationFailed48 InvalidParameter, OutOfMemory, EventCreationFailed, ThreadCreationFailed 32 49 }; 33 50 … … 45 62 LPDWORD lpNumberOfBytesWritten, 46 63 LPOVERLAPPED lpOverlapped, 47 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); 64 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 65 DWORD dwUserData); 48 66 49 67 BOOL ReadFile(HANDLE hOS2Handle, … … 52 70 LPDWORD lpNumberOfBytesRead, 53 71 LPOVERLAPPED lpOverlapped, 54 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); 72 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, 73 DWORD dwUserData); 55 74 56 75 BOOL CancelIo(HANDLE hOS2Handle); … … 81 100 CRITICAL_SECTION critsect; 82 101 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]; 86 107 87 108 friend DWORD CALLBACK OverlappedIOThread(LPVOID lpThreadParam);
Note:
See TracChangeset
for help on using the changeset viewer.