Changeset 7552 for trunk/src/kernel32/overlappedio.cpp
- Timestamp:
- Dec 5, 2001, 8:24:37 PM (24 years ago)
- 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 $ */ 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 }
Note:
See TracChangeset
for help on using the changeset viewer.