Ignore:
Timestamp:
Mar 23, 2000, 8:21:56 PM (25 years ago)
Author:
sandervl
Message:

wsock32\new update

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:04 sandervl Exp $ */
     1/* $Id: asyncapi.cpp,v 1.2 2000-03-23 19:21:53 sandervl Exp $ */
    22
    33/*
     
    77 * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
    88 *
    9  * Based on Wine code: (dlls\winsock\async.c)
     9 * Parts based on Wine code: (dlls\winsock\async.c)
    1010 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
    1111 * (C) 1999 Marcus Meissner
     
    1717#include <os2wrap.h>
    1818#include <stdio.h>
     19#include <stdlib.h>
    1920#include <string.h>
    2021#include <odin.h>
     
    152153                     (WPARAM)pThreadParm->hAsyncTaskHandle, lParam);
    153154   }
    154    RemoveFromQueue(pThreadParm);
    155155}
    156156//******************************************************************************
     
    161161{
    162162  PASYNCTHREADPARM pThreadParm;
    163   LHANDLE          hHost = 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;
    167167
    168168   if(!fWSAInitialized)
     
    193193                return 0;
    194194        }
     195        memset(pThreadParm, 0, sizeof(*pThreadParm));
    195196        pThreadParm->request= requesttype;
    196197        pThreadParm->hwnd   = hwnd;
     
    283284                break;
    284285        }
    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;
    286299   }
    287300   return 0;
     
    377390//******************************************************************************
    378391//******************************************************************************
     392void 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//******************************************************************************
     405void 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   {
     415asyncloopstart:
     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//******************************************************************************
    379553ODINFUNCTION4(int,WSAAsyncSelect,
    380554              SOCKET,s,
     
    383557              long,lEvent)
    384558{
    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.