Changeset 3205 for trunk/src/wsock32/new/asyncapi.cpp
- Timestamp:
- Mar 23, 2000, 8:21:56 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wsock32/new/asyncapi.cpp
r3198 r3205 1 /* $Id: asyncapi.cpp,v 1. 1 2000-03-22 20:01:04sandervl Exp $ */1 /* $Id: asyncapi.cpp,v 1.2 2000-03-23 19:21:53 sandervl Exp $ */ 2 2 3 3 /* … … 7 7 * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl) 8 8 * 9 * Based on Wine code: (dlls\winsock\async.c)9 * Parts based on Wine code: (dlls\winsock\async.c) 10 10 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka. 11 11 * (C) 1999 Marcus Meissner … … 17 17 #include <os2wrap.h> 18 18 #include <stdio.h> 19 #include <stdlib.h> 19 20 #include <string.h> 20 21 #include <odin.h> … … 152 153 (WPARAM)pThreadParm->hAsyncTaskHandle, lParam); 153 154 } 154 RemoveFromQueue(pThreadParm);155 155 } 156 156 //****************************************************************************** … … 161 161 { 162 162 PASYNCTHREADPARM pThreadParm; 163 LHANDLE h Host = 0;164 LPSTR tempname ;165 LPSTR tempproto ;166 LPSTR tempaddr ;163 LHANDLE hAsyncRequest = 0; 164 LPSTR tempname = 0; 165 LPSTR tempproto = 0; 166 LPSTR tempaddr = 0; 167 167 168 168 if(!fWSAInitialized) … … 193 193 return 0; 194 194 } 195 memset(pThreadParm, 0, sizeof(*pThreadParm)); 195 196 pThreadParm->request= requesttype; 196 197 pThreadParm->hwnd = hwnd; … … 283 284 break; 284 285 } 285 return (LHANDLE)QueueAsyncJob(WSAsyncThreadProc, pThreadParm); 286 hAsyncRequest = (LHANDLE)QueueAsyncJob(WSAsyncThreadProc, pThreadParm); 287 if(hAsyncRequest == 0) { 288 free(pThreadParm); 289 if(tempname) free(tempname); 290 if(tempaddr) free(tempaddr); 291 if(tempproto) free(tempproto); 292 293 dprintf(("WSAAsyncRequest: QueueAsyncJob failure!")); 294 DebugInt3(); 295 WSASetLastError(WSAEFAULT); 296 return 0; 297 } 298 return hAsyncRequest; 286 299 } 287 300 return 0; … … 377 390 //****************************************************************************** 378 391 //****************************************************************************** 392 void AsyncNotifyEvent(PASYNCTHREADPARM pThreadParm, ULONG event, ULONG socket_error) 393 { 394 pThreadParm->u.asyncselect.lEventsPending &= ~event; 395 396 event = WSAMAKESELECTREPLY(event, socket_error); 397 398 PostMessageA(pThreadParm->hwnd, pThreadParm->msg, (WPARAM)pThreadParm->u.asyncselect.s, 399 (LPARAM)event); 400 } 401 //****************************************************************************** 402 #define nr(i) ((i != -1) ? 1 : 0) 403 #define ready(i) ((i != -1) && (sockets[i] != -1)) 404 //****************************************************************************** 405 void ASYNCCNV WSAsyncSelectThreadProc(void *pparm) 406 { 407 PASYNCTHREADPARM pThreadParm = (PASYNCTHREADPARM)pparm; 408 SOCKET sockets[3]; 409 SOCKET s = pThreadParm->u.asyncselect.s; 410 int noread, nowrite, noexcept, state, sockoptlen, sockoptval; 411 int tmp, i, lEventsPending, ret, bytesread; 412 413 while(TRUE) 414 { 415 asyncloopstart: 416 i = 0; 417 noread = nowrite = noexcept = -1; 418 419 //break if user cancelled request 420 if(pThreadParm->u.asyncselect.lEvents == 0) { 421 break; 422 } 423 424 lEventsPending = pThreadParm->u.asyncselect.lEventsPending; 425 //block if no events are pending 426 if(lEventsPending == 0) 427 { 428 //wait for events to be enabled 429 pThreadParm->u.asyncselect.asyncSem->wait(); 430 //reset event semaphore 431 pThreadParm->u.asyncselect.asyncSem->reset(); 432 continue; 433 } 434 435 if(lEventsPending & (FD_READ | FD_CLOSE | FD_ACCEPT)) { 436 noread = i++; 437 sockets[noread] = s; 438 } 439 if(lEventsPending & (FD_WRITE | FD_CONNECT)) { 440 nowrite = i++; 441 sockets[nowrite] = s; 442 } 443 if(lEventsPending & FD_OOB) { 444 noexcept = i++; 445 sockets[noexcept] = s; 446 } 447 448 dprintf(("WSAsyncSelectThreadProc %x wrs=%d, rds=%d, oos =%d, pending = %x", pThreadParm->u.asyncselect.s, noread, nowrite, noexcept, lEventsPending)); 449 450 ret = select((int *)sockets, nr(noread), nr(nowrite), nr(noexcept), -1); 451 if(ret == SOCKET_ERROR) { 452 int selecterr = sock_errno(); 453 switch(selecterr) 454 { 455 case SOCEINTR: 456 goto asyncloopstart; //so_cancel was called 457 458 case SOCECONNRESET: 459 case SOCEPIPE: 460 if(lEventsPending & FD_CLOSE) 461 AsyncNotifyEvent(pThreadParm, FD_CLOSE, WSAECONNRESET); 462 463 //remote connection broken (so can't receive data anymore) 464 //but can still send 465 pThreadParm->u.asyncselect.lEventsPending &= ~(FD_READ | FD_ACCEPT); 466 goto asyncloopstart; 467 468 case SOCEINVAL: 469 if(lEventsPending & FD_CLOSE) 470 AsyncNotifyEvent(pThreadParm, FD_CLOSE, selecterr); 471 break; 472 default: 473 dprintf(("WSAsyncSelectThreadProc: select SOCKET_ERROR %x", selecterr)); 474 break; //something bad happened 475 } 476 break; 477 } 478 479 if(ready(nowrite)) 480 { 481 state = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)); 482 483 if(lEventsPending & FD_CONNECT) { 484 if(state & SS_ISCONNECTED) { 485 AsyncNotifyEvent(pThreadParm, FD_CONNECT, NO_ERROR); 486 } 487 else { 488 sockoptlen = sizeof(int); 489 490 ret = getsockopt(s, SOL_SOCKET, SO_ERROR, 491 (char *) &sockoptval, &sockoptlen); 492 if(sockoptval == (WSAECONNREFUSED-WSABASEERR)) { 493 AsyncNotifyEvent(pThreadParm, FD_CONNECT, WSAECONNREFUSED); 494 } 495 } 496 } 497 else 498 if(!(state & SS_CANTSENDMORE) && (lEventsPending & FD_WRITE)) { 499 AsyncNotifyEvent(pThreadParm, FD_WRITE, NO_ERROR); 500 } 501 } 502 503 if(ready(noread)) 504 { 505 state = ioctl(s, FIONREAD, (CHAR *) &bytesread, sizeof(bytesread)); 506 if(state == SOCKET_ERROR) { 507 if(lEventsPending & FD_CLOSE) 508 { 509 AsyncNotifyEvent(pThreadParm, FD_CLOSE, NO_ERROR); 510 //remote connection broken (so can't receive data anymore) 511 //but can still send 512 pThreadParm->u.asyncselect.lEventsPending &= ~(FD_READ | FD_ACCEPT); 513 continue; 514 } 515 else { 516 dprintf(("WSAsyncSelectThreadProc: ioctl SOCKET_ERROR!")); 517 break; //todo: correct??? 518 } 519 } 520 if(lEventsPending & FD_ACCEPT) 521 { 522 sockoptlen = sizeof(sockoptlen); 523 524 ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS, 525 (char *) &sockoptval, &sockoptlen); 526 if(ret == SOCKET_ERROR) { 527 dprintf(("WSAsyncSelectThreadProc: getsockopt SOCKET_ERROR!")); 528 break; 529 } 530 if((sockoptval & SO_ACCEPTCONN) == SO_ACCEPTCONN) { 531 AsyncNotifyEvent(pThreadParm, FD_ACCEPT, NO_ERROR); 532 } 533 } 534 if((lEventsPending & FD_READ) && bytesread > 0) { 535 AsyncNotifyEvent(pThreadParm, FD_READ, NO_ERROR); 536 } 537 } 538 if(ready(noexcept)) 539 { 540 if(lEventsPending & FD_OOB) { 541 AsyncNotifyEvent(pThreadParm, FD_OOB, NO_ERROR); 542 } 543 } 544 if((pThreadParm->u.asyncselect.lEventsPending & (FD_ACCEPT|FD_CLOSE|FD_CONNECT)) == 545 (lEventsPending & (FD_ACCEPT|FD_CLOSE|FD_CONNECT))) { 546 DosSleep(10); 547 } 548 } 549 delete pThreadParm->u.asyncselect.asyncSem; 550 } 551 //****************************************************************************** 552 //****************************************************************************** 379 553 ODINFUNCTION4(int,WSAAsyncSelect, 380 554 SOCKET,s, … … 383 557 long,lEvent) 384 558 { 385 return SOCKET_ERROR; 386 } 387 //****************************************************************************** 388 //****************************************************************************** 559 PASYNCTHREADPARM pThreadParm; 560 int nonblock = 1; 561 int ret; 562 563 if(!fWSAInitialized) 564 { 565 WSASetLastError(WSANOTINITIALISED); 566 return SOCKET_ERROR; 567 } 568 else 569 if(WSAIsBlocking()) 570 { 571 WSASetLastError(WSAEINPROGRESS); // blocking call in progress 572 return SOCKET_ERROR; 573 } 574 else 575 if(hWnd && !IsWindow(hWnd)) 576 { 577 WSASetLastError(WSAEINVAL); // invalid parameter 578 return SOCKET_ERROR; 579 } 580 //Set socket to non-blocking mode 581 ret = ioctl(s, FIONBIO, (char *) &nonblock, sizeof(nonblock)); 582 if(ret == SOCKET_ERROR) { 583 WSASetLastError(wsaErrno()); 584 return SOCKET_ERROR; 585 } 586 if(FindAndSetAsyncEvent(s, hWnd, wMsg, lEvent) == TRUE) { 587 //found and changed active async event 588 WSASetLastError(NO_ERROR); 589 return NO_ERROR; 590 } 591 pThreadParm = (PASYNCTHREADPARM)malloc(sizeof(ASYNCTHREADPARM)); 592 if(pThreadParm == NULL) { 593 dprintf(("WSAAsyncSelect: malloc failure!")); 594 DebugInt3(); 595 WSASetLastError(WSAEFAULT); 596 return SOCKET_ERROR; 597 } 598 memset(pThreadParm, 0, sizeof(*pThreadParm)); 599 pThreadParm->request= ASYNC_SELECT; 600 pThreadParm->hwnd = hWnd; 601 pThreadParm->msg = wMsg; 602 pThreadParm->u.asyncselect.lEvents = lEvent; 603 pThreadParm->u.asyncselect.lEventsPending = lEvent; 604 pThreadParm->u.asyncselect.s = s; 605 pThreadParm->u.asyncselect.asyncSem = new VSemaphore; 606 if(pThreadParm->u.asyncselect.asyncSem == NULL) { 607 dprintf(("WSAAsyncSelect: VSemaphore alloc failure!")); 608 DebugInt3(); 609 WSASetLastError(WSAEFAULT); 610 return SOCKET_ERROR; 611 } 612 if(QueueAsyncJob(WSAsyncSelectThreadProc, pThreadParm) == 0) { 613 delete pThreadParm->u.asyncselect.asyncSem; 614 free(pThreadParm); 615 dprintf(("WSAAsyncSelect: QueueAsyncJob failure!")); 616 DebugInt3(); 617 WSASetLastError(WSAEFAULT); 618 return SOCKET_ERROR; 619 } 620 WSASetLastError(NO_ERROR); 621 return NO_ERROR; 622 } 623 //****************************************************************************** 624 //******************************************************************************
Note:
See TracChangeset
for help on using the changeset viewer.