⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 macsockotpt.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    *readReady = fd->secret->md.readReady && (availableData > 0);    *exceptReady = fd->secret->md.exceptReady;    resultOT = OTGetEndpointState((EndpointRef)fd->secret->md.osfd);    switch (resultOT) {        case T_IDLE:        case T_UNBND:            // the socket is not connected. Emulating BSD sockets,            // we mark it readable and writable. The next PR_Read            // or PR_Write will then fail. Usually, in this situation,            // fd->secret->md.exceptReady is also set, and returned if            // anyone is polling for it.            *readReady = PR_FALSE;            *writeReady = PR_FALSE;            break;        case T_DATAXFER:        // data transfer            *writeReady = fd->secret->md.writeReady;            break;        case T_INREL:           // incoming orderly release            *writeReady = fd->secret->md.writeReady;            break;        case T_OUTCON:          // outgoing connection pending          case T_INCON:           // incoming connection pending        case T_OUTREL:          // outgoing orderly release        default:            *writeReady = PR_FALSE;    }        return  *readReady || *writeReady || *exceptReady;}// check to see if any of the poll descriptors have data available// for reading or writing, by calling their poll methods (layered IO).static PRInt32 CheckPollDescMethods(PRPollDesc *pds, PRIntn npds, PRInt16 *outReadFlags, PRInt16 *outWriteFlags){    PRInt32     ready = 0;    PRPollDesc  *pd, *epd;    PRInt16     *readFlag, *writeFlag;        for (pd = pds, epd = pd + npds, readFlag = outReadFlags, writeFlag = outWriteFlags;        pd < epd;        pd++, readFlag++, writeFlag++)    {        PRInt16  in_flags_read = 0,  in_flags_write = 0;        PRInt16 out_flags_read = 0, out_flags_write = 0;        if (NULL == pd->fd || pd->in_flags == 0) continue;        if (pd->in_flags & PR_POLL_READ)        {            in_flags_read = (pd->fd->methods->poll)(                pd->fd, pd->in_flags & ~PR_POLL_WRITE, &out_flags_read);        }        if (pd->in_flags & PR_POLL_WRITE)        {            in_flags_write = (pd->fd->methods->poll)(                pd->fd, pd->in_flags & ~PR_POLL_READ, &out_flags_write);        }        if ((0 != (in_flags_read & out_flags_read)) ||            (0 != (in_flags_write & out_flags_write)))        {            ready += 1;  /* some layer has buffer input */            pd->out_flags = out_flags_read | out_flags_write;        }                *readFlag = in_flags_read;        *writeFlag = in_flags_write;    }    return ready;}// check to see if any of OT endpoints of the poll descriptors have data available// for reading or writing.static PRInt32 CheckPollDescEndpoints(PRPollDesc *pds, PRIntn npds, const PRInt16 *inReadFlags, const PRInt16 *inWriteFlags){    PRInt32 ready = 0;    PRPollDesc *pd, *epd;    const PRInt16   *readFlag, *writeFlag;        for (pd = pds, epd = pd + npds, readFlag = inReadFlags, writeFlag = inWriteFlags;         pd < epd;        pd++, readFlag++, writeFlag++)    {        PRFileDesc *bottomFD;        PRBool      readReady, writeReady, exceptReady;        PRInt16     in_flags_read = *readFlag;        PRInt16     in_flags_write = *writeFlag;        if (NULL == pd->fd || pd->in_flags == 0) continue;        bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);        /* bottomFD can be NULL for pollable sockets */        if (bottomFD)        {            if (_PR_FILEDESC_OPEN == bottomFD->secret->state)            {                pd->out_flags = 0;  /* pre-condition */                if (GetState(bottomFD, &readReady, &writeReady, &exceptReady))                {                    if (readReady)                    {                        if (in_flags_read & PR_POLL_READ)                            pd->out_flags |= PR_POLL_READ;                        if (in_flags_write & PR_POLL_READ)                            pd->out_flags |= PR_POLL_WRITE;                    }                    if (writeReady)                    {                        if (in_flags_read & PR_POLL_WRITE)                            pd->out_flags |= PR_POLL_READ;                        if (in_flags_write & PR_POLL_WRITE)                            pd->out_flags |= PR_POLL_WRITE;                    }                    if (exceptReady && (pd->in_flags & PR_POLL_EXCEPT))                    {                        pd->out_flags |= PR_POLL_EXCEPT;                    }                    if (0 != pd->out_flags) ready++;                }            }            else    /* bad state */            {                ready += 1;  /* this will cause an abrupt return */                pd->out_flags = PR_POLL_NVAL;  /* bogii */            }        }    }    return ready;}// see how many of the poll descriptors are readystatic PRInt32 CountReadyPollDescs(PRPollDesc *pds, PRIntn npds){    PRInt32 ready = 0;    PRPollDesc *pd, *epd;        for (pd = pds, epd = pd + npds; pd < epd; pd++)    {        if (pd->out_flags)            ready ++;    }    return ready;}// set or clear the poll thread on the poll descriptorsstatic void SetDescPollThread(PRPollDesc *pds, PRIntn npds, PRThread* thread){    PRInt32     ready = 0;    PRPollDesc *pd, *epd;    for (pd = pds, epd = pd + npds; pd < epd; pd++)    {           if (pd->fd)        {             PRFileDesc *bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER);            if (bottomFD && (_PR_FILEDESC_OPEN == bottomFD->secret->state))            {                if (pd->in_flags & PR_POLL_READ) {                    PR_ASSERT(thread == NULL || bottomFD->secret->md.read.thread == NULL);                    bottomFD->secret->md.read.thread = thread;                }                if (pd->in_flags & PR_POLL_WRITE) {                    // it's possible for the writing thread to be non-null during                    // a non-blocking connect, so we assert that we're on                    // the same thread, or the thread is null.                    // Note that it's strictly possible for the connect and poll                    // to be on different threads, so ideally we need to assert                    // that if md.write.thread is non-null, there is a non-blocking                    // connect in progress.                    PR_ASSERT(thread == NULL ||                        (bottomFD->secret->md.write.thread == NULL ||                         bottomFD->secret->md.write.thread == thread));                    bottomFD->secret->md.write.thread = thread;                }            }        }    }}#define DESCRIPTOR_FLAGS_ARRAY_SIZE     32PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout){    PRInt16     readFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE];    PRInt16     writeFlagsArray[DESCRIPTOR_FLAGS_ARRAY_SIZE];        PRInt16     *readFlags  = readFlagsArray;    PRInt16     *writeFlags = writeFlagsArray;    PRInt16     *ioFlags = NULL;        PRThread    *thread = _PR_MD_CURRENT_THREAD();    PRInt32     ready;        if (npds > DESCRIPTOR_FLAGS_ARRAY_SIZE)    {        // we allocate a single double-size array. The first half is used        // for read flags, and the second half for write flags.        ioFlags = (PRInt16*)PR_Malloc(sizeof(PRInt16) * npds * 2);        if (!ioFlags)        {            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);            return -1;        }                readFlags = ioFlags;        writeFlags = &ioFlags[npds];    }    if (timeout != PR_INTERVAL_NO_WAIT) {        intn        is;                // we have to be outside the lock when calling this, since        // it can call arbitrary user code (including other socket        // entry points)        (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);        _PR_INTSOFF(is);        PR_Lock(thread->md.asyncIOLock);        PrepareForAsyncCompletion(thread, 0);        SetDescPollThread(pds, npds, thread);        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);        PR_Unlock(thread->md.asyncIOLock);        _PR_FAST_INTSON(is);        ready = CountReadyPollDescs(pds, npds);        if (ready == 0) {            WaitOnThisThread(thread, timeout);            // since we may have been woken by a pollable event firing,            // we have to check both poll methods and endpoints.            (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);            (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);            ready = CountReadyPollDescs(pds, npds);        }                thread->io_pending = PR_FALSE;        SetDescPollThread(pds, npds, NULL);    }    else {        (void)CheckPollDescMethods(pds, npds, readFlags, writeFlags);        (void)CheckPollDescEndpoints(pds, npds, readFlags, writeFlags);        ready = CountReadyPollDescs(pds, npds);        }    if (readFlags != readFlagsArray)        PR_Free(ioFlags);        return ready;}void _MD_initfiledesc(PRFileDesc *fd){	// Allocate a PR_Lock to arbitrate miscellaneous OT calls for this endpoint between threads	// We presume that only one thread will be making Read calls (Recv/Accept) and that only	// one thread will be making Write calls (Send/Connect) on the endpoint at a time.	if (fd->methods->file_type == PR_DESC_SOCKET_TCP ||		fd->methods->file_type == PR_DESC_SOCKET_UDP )	{		PR_ASSERT(fd->secret->md.miscLock == NULL);		fd->secret->md.miscLock = PR_NewLock();		PR_ASSERT(fd->secret->md.miscLock != NULL);		fd->secret->md.orderlyDisconnect = PR_FALSE;		fd->secret->md.readReady = PR_FALSE;		// let's not presume we have data ready to read		fd->secret->md.writeReady = PR_TRUE;		// let's presume we can write unless we hear otherwise		fd->secret->md.exceptReady = PR_FALSE;	}}void _MD_freefiledesc(PRFileDesc *fd){	if (fd->secret->md.miscLock)	{		PR_ASSERT(fd->methods->file_type == PR_DESC_SOCKET_TCP || fd->methods->file_type == PR_DESC_SOCKET_UDP);		PR_DestroyLock(fd->secret->md.miscLock);		fd->secret->md.miscLock = NULL;	} else {		PR_ASSERT(fd->methods->file_type != PR_DESC_SOCKET_TCP && PR_DESC_SOCKET_TCP != PR_DESC_SOCKET_UDP);	}}// _MD_makenonblock is also used for sockets meant to be used for blocking I/O,// in order to install the notifier routine for async completion.void _MD_makenonblock(PRFileDesc *fd){	// We simulate non-blocking mode using async mode rather	// than put the endpoint in non-blocking mode.	// We need to install the PRFileDesc as the contextPtr for the NotifierRoutine, but it	// didn't exist at the time the endpoint was created.  It does now though...	ProviderRef	endpointRef = (ProviderRef)fd->secret->md.osfd;	OSStatus	err;		// Install fd->secret as the contextPtr for the Notifier function associated with this 	// endpoint. We use this instead of the fd itself because:	//            (a) in cases where you import I/O layers, the containing 	//                fd changes, but the secret structure does not;	//            (b) the notifier func refers only to the secret data structure	//                anyway.	err = OTInstallNotifier(endpointRef, NotifierRoutineUPP, fd->secret);	PR_ASSERT(err == kOTNoError);		// Now that we have a NotifierRoutine installed, we can make the endpoint asynchronous	err = OTSetAsynchronous(endpointRef);	PR_ASSERT(err == kOTNoError);}void _MD_initfdinheritable(PRFileDesc *fd, PRBool imported){	/* XXX this function needs to be implemented */	fd->secret->inheritable = _PR_TRI_UNKNOWN;}void _MD_queryfdinheritable(PRFileDesc *fd){	/* XXX this function needs to be implemented */	PR_ASSERT(0);}PR_IMPLEMENT(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how){#pragma unused (fd, how)/* Just succeed silently!!! */return (0);}PR_IMPLEMENT(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen){    PRThread *me = _PR_MD_CURRENT_THREAD();	EndpointRef ep = (EndpointRef) fd->secret->md.osfd;	InetAddress inetAddr;	TBind peerAddr;	OSErr err;		if (*addrlen < sizeof(InetAddress)) {		err = (OSErr) kEINVALErr;		goto ErrorExit;	}    peerAddr.addr.maxlen = sizeof(InetAddress);    peerAddr.addr.len = 0;    peerAddr.addr.buf = (UInt8*) &inetAddr;    peerAddr.qlen = 0;    PrepareForAsyncCompletion(me, fd->secret->md.osfd);    	fd->secret->md.misc.thread = me; // tell notifier routine what to wake up	err = OTGetProtAddress(ep, NULL, &peerAddr);	    if (err != kOTNoError)        goto ErrorExit;    WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT);    err = me->md.osErrCode;    if ((err == kOTNoError) && (peerAddr.addr.len < sizeof(InetAddress)))    	err = kEBADFErr; // we don't understand the address we got    if (err != kOTNoError)    	goto ErrorExit;    	    // Translate the OT peer information into an NSPR address.    addr->inet.family = AF_INET;    addr->inet.port = (PRUint16) inetAddr.fPort;    addr->inet.ip = (PRUint32) inetAddr.fHost;        *addrlen = PR_NETADDR_SIZE(addr); // return the amount of data obtained	return PR_SUCCESS;ErrorExit:    macsock_map_error(err);    return PR_FAILURE;}PR_IMPLEMENT(unsigned long) inet_addr(const char *cp){    OSStatus err;    InetHost host;        _MD_FinishInitNetAccess();    err = OTInetStringToHost((char*) cp, &host);    if (err != kOTNoError)        return -1;        return host;}static char *sAliases[1] = {NULL};static struct hostent sHostEnt = {NULL, &sAliases[0], AF_INET, sizeof (long), NULL};static InetHostInfo sHostInfo;static InetHost *sAddresses[kMaxHostAddrs+1];PR_IMPLEMENT(struct hostent *) gethostbyname(const char * name){    OSStatus err;    PRUint32 index;    PRThread *me = _PR_MD_CURRENT_THREAD();    	_MD_FinishInitNetAccess();    me->io_pending       = PR_TRUE;    me->io_fd            = NULL;    me->md.osErrCode     = noErr;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -