diff options
author | cvs2hg <devnull@localhost> | 1999-03-17 21:25:09 +0000 |
---|---|---|
committer | cvs2hg <devnull@localhost> | 1999-03-17 21:25:09 +0000 |
commit | c66610351084bebf1401d80dad1837388c03172a (patch) | |
tree | 4e62c843c13dd733a9a9f6ee4f594491c7a6c581 | |
parent | 45ef5e9ceccb997b2de55b6ef0d3af5b7bd0a372 (diff) | |
download | nspr-hg-c66610351084bebf1401d80dad1837388c03172a.tar.gz |
fixup commit for tag 'NSPRPUB_RELEASE_3_1'NSPRPUB_RELEASE_3_1
-rw-r--r-- | pr/include/md/_macos.h | 29 | ||||
-rw-r--r-- | pr/include/private/primpl.h | 5 | ||||
-rw-r--r-- | pr/src/io/prio.c | 3 | ||||
-rw-r--r-- | pr/src/md/mac/macsockotpt.c | 695 |
4 files changed, 286 insertions, 446 deletions
diff --git a/pr/include/md/_macos.h b/pr/include/md/_macos.h index 724a686b..cabda034 100644 --- a/pr/include/md/_macos.h +++ b/pr/include/md/_macos.h @@ -51,11 +51,12 @@ struct _MDProcess { }; struct _MDThread { - jmp_buf jb; - int osErrCode; - PRLock * asyncIOLock; - PRCondVar * asyncIOCVar; - PRBool notifyPending; + jmp_buf jb; + int osErrCode; + PRLock *asyncIOLock; + PRCondVar *asyncIOCVar; + void *cookie; + PRBool notifyPending; }; struct _MDThreadStack { @@ -82,21 +83,8 @@ struct _MDCPU { PRInt8 notused; }; -typedef struct _MDSocketCallerInfo { - PRThread * thread; - void * cookie; -} _MDSocketCallerInfo; - struct _MDFileDesc { - PRInt32 osfd; - PRBool connectionOpen; - PRBool readReady; - PRBool writeReady; - PRBool exceptReady; - PRLock * miscLock; - _MDSocketCallerInfo misc; - _MDSocketCallerInfo read; - _MDSocketCallerInfo write; + PRInt32 osfd; }; /* @@ -389,8 +377,7 @@ extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, c #define _MD_SENDTO _MD_sendto #define _MD_RECVFROM _MD_recvfrom #define _MD_PR_POLL _MD_poll -#define _MD_INIT_FILEDESC _MD_initfiledesc -#define _MD_FREE_FILEDESC _MD_freefiledesc +#define _MD_INIT_FILEDESC(fd) #define _MD_MAKE_NONBLOCK _MD_makenonblock #define _MD_GET_SOCKET_ERROR() _PR_MD_CURRENT_THREAD()->md.osErrCode diff --git a/pr/include/private/primpl.h b/pr/include/private/primpl.h index 10476e7c..fa9a48c6 100644 --- a/pr/include/private/primpl.h +++ b/pr/include/private/primpl.h @@ -977,11 +977,6 @@ extern PRInt32 _PR_MD_CLOSE_DIR(_MDDir *md); extern void _PR_MD_INIT_FILEDESC(PRFileDesc *fd); #define _PR_MD_INIT_FILEDESC _MD_INIT_FILEDESC -#ifdef XP_MAC -extern void _PR_MD_FREE_FILEDESC(PRFileDesc *fd); -#define _PR_MD_FREE_FILEDESC _MD_FREE_FILEDESC -#endif - extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd); #define _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK diff --git a/pr/src/io/prio.c b/pr/src/io/prio.c index 1e128e54..bbf5c099 100644 --- a/pr/src/io/prio.c +++ b/pr/src/io/prio.c @@ -101,9 +101,6 @@ PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc( PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd) { PR_ASSERT(fd); -#ifdef XP_MAC - _PR_MD_FREE_FILEDESC(fd); -#endif _PR_Putfd(fd); } diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c index 6da0089b..618f411d 100644 --- a/pr/src/md/mac/macsockotpt.c +++ b/pr/src/md/mac/macsockotpt.c @@ -20,46 +20,52 @@ #define OTUNIXERRORS 1 #include <Gestalt.h> -#include <OpenTransport.h> +/* + Since Apple put out new headers without + putting in a way to test for them, we found some random symbol which + isn't defined in the "1.1" headers. +*/ +#include <OpenTransport.h> +#ifdef kOTInvalidStreamRef +/* old */ +#define GESTALT_OPEN_TPT_PRESENT gestaltOpenTptPresent +#define GESTALT_OPEN_TPT_TCP_PRESENT gestaltOpenTptTCPPresent +#else +/* new */ #define GESTALT_OPEN_TPT_PRESENT gestaltOpenTptPresentMask #define GESTALT_OPEN_TPT_TCP_PRESENT gestaltOpenTptTCPPresentMask +#endif #include <OpenTptInternet.h> // All the internet typedefs #include "primpl.h" typedef enum SndRcvOpCode { kSTREAM_SEND, - kSTREAM_RECEIVE, + kSTREAM_RECEIVE , kDGRAM_SEND, kDGRAM_RECEIVE } SndRcvOpCode; -static struct { - PRLock * lock; - InetSvcRef serviceRef; - PRThread * thread; - void * cookie; -} dnsContext; +static InetSvcRef sSvcRef; -static pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie); static pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie); -static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady); +static PRBool GetState(EndpointRef endpoint, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady); extern void WaitOnThisThread(PRThread *thread, PRIntervalTime timeout); extern void DoneWaitingOnThisThread(PRThread *thread); - void _MD_InitNetAccess() { - OSErr err; + OSErr err; OSStatus errOT; - PRBool hasOTTCPIP = PR_FALSE; - PRBool hasOT = PR_FALSE; - long gestaltResult; + PRBool hasOTTCPIP = PR_FALSE; + PRBool hasOT = PR_FALSE; + long gestaltResult; + PRThread *me = _PR_MD_CURRENT_THREAD(); err = Gestalt(gestaltOpenTpt, &gestaltResult); if (err == noErr) @@ -74,48 +80,22 @@ void _MD_InitNetAccess() errOT = InitOpenTransport(); PR_ASSERT(err == kOTNoError); - - dnsContext.lock = PR_NewLock(); - PR_ASSERT(dnsContext.lock != NULL); - - dnsContext.thread = _PR_MD_CURRENT_THREAD(); - dnsContext.cookie = NULL; - - dnsContext.serviceRef = OTOpenInternetServices(kDefaultInternetServicesPath, NULL, &errOT); + + sSvcRef = OTOpenInternetServices(kDefaultInternetServicesPath, NULL, &errOT); if (errOT != kOTNoError) return; /* no network -- oh well */ - PR_ASSERT((dnsContext.serviceRef != NULL) && (errOT == kOTNoError)); + PR_ASSERT((sSvcRef != NULL) && (errOT == kOTNoError)); /* Install notify function for DNR Address To String completion */ - errOT = OTInstallNotifier(dnsContext.serviceRef, DNSNotifierRoutine, &dnsContext); + errOT = OTInstallNotifier(sSvcRef, NotifierRoutine, me); PR_ASSERT(errOT == kOTNoError); /* Put us into async mode */ - errOT = OTSetAsynchronous(dnsContext.serviceRef); + errOT = OTSetAsynchronous(sSvcRef); PR_ASSERT(errOT == kOTNoError); /* XXX Does not handle absence of open tpt and tcp yet! */ } - -pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie) -{ -#pragma unused(contextPtr) - _PRCPU * cpu = _PR_MD_CURRENT_CPU(); - - if (code == T_DNRSTRINGTOADDRCOMPLETE) { - dnsContext.thread->md.osErrCode = result; - dnsContext.cookie = cookie; - if (_PR_MD_GET_INTSOFF()) { - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - dnsContext.thread->md.notifyPending = PR_TRUE; - return; - } - DoneWaitingOnThisThread(dnsContext.thread); - } - // or else we don't handle the event -} - - static void macsock_map_error(OSStatus err) { _PR_MD_CURRENT_THREAD()->md.osErrCode = err; @@ -193,161 +173,80 @@ static void macsock_map_error(OSStatus err) } } +static void PrepareThreadForAsyncIO(PRThread *thread, EndpointRef endpoint, PRInt32 osfd) +{ + OSStatus err; + thread->io_pending = PR_TRUE; + thread->io_fd = osfd; + thread->md.osErrCode = noErr; -static void PrepareForAsyncCompletion(PRThread * thread, PRFileDesc * fd) -{ - thread->io_pending = PR_TRUE; - thread->io_fd = fd->secret->md.osfd; - thread->md.osErrCode = noErr; + OTRemoveNotifier(endpoint); + err = OTInstallNotifier(endpoint, NotifierRoutine, thread); + PR_ASSERT(err == kOTNoError); } - // Notification routine // Async callback routine. // A5 is OK. Cannot allocate memory here pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie) { - PRFileDesc * fd = (PRFileDesc *) contextPtr; - EndpointRef endpoint = (EndpointRef)fd->secret->md.osfd; - PRThread * thread = NULL; - _PRCPU * cpu = _PR_MD_CURRENT_CPU(); - OSStatus err; - TDiscon discon; - OTResult resultOT; - + PRThread * thread = (PRThread *) contextPtr; + _PRCPU *cpu = _PR_MD_CURRENT_CPU(); + switch (code) { -// OTLook Events - - case T_LISTEN: // A connection request is available - PR_ASSERT(!"T_LISTEN Not implemented"); // listen or reject? +// Async Completion Event + case T_OPENCOMPLETE: + case T_BINDCOMPLETE: + case T_UNBINDCOMPLETE: + case T_GETPROTADDRCOMPLETE: + case T_ACCEPTCOMPLETE: +// Connect callback + case T_CONNECT: +// Standard or expedited data is available + case T_DATA: + case T_EXDATA: +// Standard or expedited data Flow control lifted + case T_GODATA: + case T_GOEXDATA: +// Asynchronous Listen Event + case T_LISTEN: +// DNR String To Address Complete Event + case T_DNRSTRINGTOADDRCOMPLETE: +// Option Management Request Complete Event + case T_OPTMGMTCOMPLETE: + thread->md.osErrCode = result; + thread->md.cookie = cookie; + if (_PR_MD_GET_INTSOFF()) { + cpu->u.missed[cpu->where] |= _PR_MISSED_IO; + thread->md.notifyPending = PR_TRUE; + return; + } + DoneWaitingOnThisThread(thread); break; - - case T_CONNECT: // Confirmation of a connect request - // cookie = sndCall parameter from OTConnect() - err = OTRcvConnect(endpoint, NULL); - PR_ASSERT(err == kOTNoError); - // wake up waiting thread, if any - thread = fd->secret->md.write.thread; - fd->secret->md.write.thread = NULL; - fd->secret->md.write.cookie = cookie; - fd->secret->md.connectionOpen = PR_TRUE; +// T_ORDREL orderly release is available; nothing to do + case T_ORDREL: break; - case T_DATA: // Standard data is available - fd->secret->md.readReady = PR_TRUE; - - // wake up waiting thread, if any - thread = fd->secret->md.read.thread; - fd->secret->md.read.thread = NULL; - fd->secret->md.read.cookie = cookie; - break; - - case T_EXDATA: // Expedited data is available - PR_ASSERT(!"T_EXDATA Not implemented"); - return; - - case T_DISCONNECT: // A disconnect is available - memset(&discon, 0 , sizeof(discon)); - err = OTRcvDisconnect(endpoint, &discon); - PR_ASSERT(err == kOTNoError); - macsock_map_error(discon.reason); - fd->secret->md.exceptReady = PR_TRUE; - fd->secret->md.connectionOpen = PR_FALSE; - break; - - case T_ERROR: // obsolete/unused in library - PR_ASSERT(!"T_ERROR Not implemented"); - return; - - case T_UDERR: // UDP Send error; clear the error - (void) OTRcvUDErr((EndpointRef) cookie, NULL); +// T_PASSCON; nothing to do + case T_PASSCON: break; - case T_ORDREL: // An orderly release is available - err = OTRcvOrderlyDisconnect(endpoint); - PR_ASSERT(err == kOTNoError); - fd->secret->md.readReady = PR_TRUE; // mark readable (to emulate bsd sockets) - // remember connection is closed, so we can return 0 on read or receive - fd->secret->md.connectionOpen = PR_FALSE; - break; - - case T_GODATA: // Flow control lifted on standard data - fd->secret->md.writeReady = PR_TRUE; - resultOT = OTLook(endpoint); // clear T_GODATA event - PR_ASSERT(resultOT == T_GODATA); - - // wake up waiting thread, if any - thread = fd->secret->md.write.thread; - fd->secret->md.write.thread = NULL; - fd->secret->md.write.cookie = cookie; +// T_DISCONNECT; disconnect is available; nothing to do + case T_DISCONNECT: break; - case T_GOEXDATA: // Flow control lifted on expedited data - PR_ASSERT(!"T_GOEXDATA Not implemented"); - return; - - case T_REQUEST: // An Incoming request is available - PR_ASSERT(!"T_REQUEST Not implemented"); - return; - - case T_REPLY: // An Incoming reply is available - PR_ASSERT(!"T_REPLY Not implemented"); - return; - - case T_PASSCON: // State is now T_DATAXFER - // OTAccept() complete, receiving endpoint in T_DATAXFER state - // cookie = OTAccept() resRef parameter - break; - - case T_RESET: // Protocol has been reset - PR_ASSERT(!"T_RESET Not implemented"); - return; - -// Async Completion Events - case T_BINDCOMPLETE: - case T_UNBINDCOMPLETE: - case T_ACCEPTCOMPLETE: - case T_OPTMGMTCOMPLETE: - case T_GETPROTADDRCOMPLETE: - thread = fd->secret->md.misc.thread; - fd->secret->md.misc.thread = NULL; - fd->secret->md.misc.cookie = cookie; +// UDP Send error; clear the error + case T_UDERR: + (void) OTRcvUDErr((EndpointRef) cookie, NULL); break; - -// case T_OPENCOMPLETE: // we open endpoints in synchronous mode -// case T_REPLYCOMPLETE: -// case T_DISCONNECTCOMPLETE: // we don't call OTSndDisconnect() -// case T_RESOLVEADDRCOMPLETE: -// case T_GETINFOCOMPLETE: -// case T_SYNCCOMPLETE: -// case T_MEMORYRELEASED: // only if OTAckSends() called on endpoint -// case T_REGNAMECOMPLETE: -// case T_DELNAMECOMPLETE: -// case T_LKUPNAMECOMPLETE: -// case T_LKUPNAMERESULT: - // OpenTptInternet.h -// case T_DNRSTRINGTOADDRCOMPLETE: // DNS is handled by dnsContext in DNSNotifierRoutine() -// case T_DNRADDRTONAMECOMPLETE: -// case T_DNRSYSINFOCOMPLETE: -// case T_DNRMAILEXCHANGECOMPLETE: -// case T_DNRQUERYCOMPLETE: + default: - // we should probably have a bit more sophisticated handling of kOTSystemSleep, etc. - // PR_ASSERT(code != 0); - return; + PR_ASSERT(0); + break; } - - if (thread) { - thread->md.osErrCode = result; - if (_PR_MD_GET_INTSOFF()) { - cpu->u.missed[cpu->where] |= _PR_MISSED_IO; - thread->md.notifyPending = PR_TRUE; - return; - } - DoneWaitingOnThisThread(thread); - } } @@ -355,23 +254,27 @@ static OSErr CreateSocket(int type, EndpointRef *endpoint) { OSStatus err; PRThread *me = _PR_MD_CURRENT_THREAD(); - char * configName; - OTConfiguration *config; - EndpointRef ep; - - // for now we just create the endpoint - // we'll make it asynchronous and give it a notifier routine in _MD_makenonblock() switch (type){ - case SOCK_STREAM: configName = kTCPName; break; - case SOCK_DGRAM: configName = kUDPName; break; + case SOCK_STREAM: + err = OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0, NULL, + NotifierRoutine, me); + break; + case SOCK_DGRAM: + err = OTAsyncOpenEndpoint(OTCreateConfiguration(kUDPName), 0, NULL, + NotifierRoutine, me); + break; } - config = OTCreateConfiguration(configName); - ep = OTOpenEndpoint(config, 0, NULL, &err); if (err != kOTNoError) goto ErrorExit; - *endpoint = ep; + WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); + + err = me->md.osErrCode; + if (err != kOTNoError) + goto ErrorExit; + + *endpoint = me->md.cookie; PR_ASSERT(*endpoint != NULL); return kOTNoError; @@ -436,14 +339,14 @@ ErrorExit: return -1; } - // Errors: -// EBADF -- bad socket id +// EBADF -- bad socket id // EFAULT -- bad address format PRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen) { + PRInt32 osfd = fd->secret->md.osfd; OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; TBind bindReq; PRThread *me = _PR_MD_CURRENT_THREAD(); PRUint32 retryCount = 0; @@ -458,38 +361,39 @@ PRInt32 _MD_bind(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen) goto ErrorExit; } + // setup our request +#if 0 + if ((addr->inet.port == 0) || (addr->inet.ip == 0)) + bindReq.addr.len = 0; + else +#endif /* - * There seems to be a bug with OT related to OTBind failing with kOTNoAddressErr even though + * There seems to be a bug with OT ralted to OTBind failing with kOTNoAddressErr eventhough * a proper legal address was supplied. This happens very rarely and just retrying the * operation after a certain time (less than 1 sec. does not work) seems to succeed. */ TryAgain: - // setup our request bindReq.addr.len = addrlen; bindReq.addr.maxlen = addrlen; bindReq.addr.buf = (UInt8*) addr; bindReq.qlen = 1; - - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd); - fd->secret->md.misc.thread = me; + + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTBind(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); + if (err != kOTNoError) goto ErrorExit; - } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; + PR_ASSERT(me->md.cookie == NULL); + return kOTNoError; ErrorExit: @@ -503,7 +407,6 @@ ErrorExit: return -1; } - // Errors: // EBADF -- bad socket id PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) @@ -531,7 +434,7 @@ PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) bindReq.addr.buf = (UInt8*) &addr; bindReq.qlen = 0; - PrepareForAsyncCompletion(me, osfd); + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTGetProtAddress(endpoint, &bindReq, NULL); if (err != kOTNoError) @@ -543,7 +446,7 @@ PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) if (err != kOTNoError) goto ErrorExit; - PrepareForAsyncCompletion(me, osfd); + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTUnbind(endpoint); if (err != kOTNoError) @@ -557,7 +460,7 @@ PRInt32 _MD_listen(PRFileDesc *fd, PRIntn backlog) bindReq.qlen = backlog; - PrepareForAsyncCompletion(me, osfd); + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTBind(endpoint, &bindReq, NULL); if (err != kOTNoError) @@ -583,13 +486,13 @@ ErrorExit: } - // Errors: // EBADF -- bad socket id PRInt32 _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) { + PRInt32 osfd = fd->secret->md.osfd; OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; TBind bindReq; PRThread *me = _PR_MD_CURRENT_THREAD(); @@ -614,24 +517,20 @@ PRInt32 _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) bindReq.addr.buf = (UInt8*) addr; bindReq.qlen = 0; - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd); - fd->secret->md.misc.thread = me; + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTGetProtAddress(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); + if (err != kOTNoError) goto ErrorExit; - } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; + PR_ASSERT(me->md.cookie == &bindReq); + return kOTNoError; ErrorExit: @@ -639,11 +538,11 @@ ErrorExit: return -1; } - PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* optval, PRInt32* optlen) { OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + PRInt32 osfd = fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; TOptMgmt cmd; TOption *opt; PRThread *me = _PR_MD_CURRENT_THREAD(); @@ -677,19 +576,13 @@ PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, char* op cmd.opt.buf = (UInt8*)optionBuffer; cmd.flags = T_CURRENT; - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd); - fd->secret->md.misc.thread = me; + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTOptionManagement(endpoint, &cmd, &cmd); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); + if (err != kOTNoError) goto ErrorExit; - } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); err = me->md.osErrCode; if (err != kOTNoError) @@ -764,11 +657,11 @@ ErrorExit: return PR_FAILURE; } - PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const char* optval, PRInt32 optlen) { OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + PRInt32 osfd = fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; TOptMgmt cmd; TOption *opt; PRThread *me = _PR_MD_CURRENT_THREAD(); @@ -870,19 +763,13 @@ PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level, PRInt32 optname, const ch break; } - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd); - fd->secret->md.misc.thread = me; + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTOptionManagement(endpoint, &cmd, &cmd); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); + if (err != kOTNoError) goto ErrorExit; - } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); err = me->md.osErrCode; if (err != kOTNoError) @@ -907,7 +794,6 @@ ErrorExit: return PR_FAILURE; } - PRInt32 _MD_socketavailable(PRFileDesc *fd) { PRInt32 osfd = fd->secret->md.osfd; @@ -937,17 +823,11 @@ ErrorExit: return -1; } - PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) { -#pragma unused (fd, addr, addrlen, timeout) - - PR_ASSERT(!"_MD_accept Not implemented"); - return -1; - -#if 0 + PRInt32 osfd = fd->secret->md.osfd; OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); TBind bindReq; PRNetAddr bindAddr; @@ -967,7 +847,7 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva call.addr.len = PR_NETADDR_SIZE(&callAddr); call.addr.buf = (UInt8*) &callAddr; - PrepareForAsyncCompletion(me, fd); + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTListen (endpoint, &call); if (err != kOTNoError && (err != kOTNoDataErr || fd->secret->nonblocking)) { @@ -981,7 +861,7 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva if (err != kOTNoError) goto ErrorExit; - PrepareForAsyncCompletion(me, fd); + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTListen (endpoint, &call); if (err == kOTNoError) @@ -1005,7 +885,7 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva bindReq.addr.buf = (UInt8*) &bindAddr; bindReq.qlen = 0; - PrepareThreadForAsyncIO(me, newosfd); + PrepareThreadForAsyncIO(me, newEndpoint, newosfd); err = OTBind(newEndpoint, &bindReq, NULL); if (err != kOTNoError) @@ -1017,7 +897,7 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva if (err != kOTNoError) goto ErrorExit; - PrepareThreadForAsyncIO(me, newosfd); + PrepareThreadForAsyncIO(me, endpoint, newosfd); err = OTAccept (endpoint, newEndpoint, &call); if (err != kOTNoError) @@ -1029,6 +909,8 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva if (err != kOTNoError) goto ErrorExit; + PR_ASSERT(me->md.cookie != NULL); + if (addr != NULL) *addr = callAddr; if (addrlen != NULL) @@ -1041,14 +923,13 @@ ErrorExit: _MD_closesocket(newosfd); macsock_map_error(err); return -1; -#endif } - PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) { + PRInt32 osfd = fd->secret->md.osfd; OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); TCall sndCall; TBind bindReq; @@ -1073,19 +954,13 @@ PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRInterva bindReq.addr.buf = (UInt8*) &bindAddr; bindReq.qlen = 0; - PR_Lock(fd->secret->md.miscLock); - PrepareForAsyncCompletion(me, fd); - fd->secret->md.misc.thread = me; + PrepareThreadForAsyncIO(me, endpoint, osfd); err = OTBind(endpoint, &bindReq, NULL); - if (err != kOTNoError) { - me->io_pending = PR_FALSE; - PR_Unlock(fd->secret->md.miscLock); + if (err != kOTNoError) goto ErrorExit; - } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(fd->secret->md.miscLock); err = me->md.osErrCode; if (err != kOTNoError) @@ -1096,33 +971,29 @@ PRInt32 _MD_connect(PRFileDesc *fd, PRNetAddr *addr, PRUint32 addrlen, PRInterva sndCall.addr.maxlen = addrlen; sndCall.addr.len = addrlen; sndCall.addr.buf = (UInt8*) addr; + + PrepareThreadForAsyncIO(me, endpoint, osfd); - if (!fd->secret->nonblocking) { - PrepareForAsyncCompletion(me, fd); - fd->secret->md.write.thread = me; - } - err = OTConnect (endpoint, &sndCall, NULL); - if (err == kOTNoError) { - PR_ASSERT(!"OTConnect returned kOTNoError in async mode!?!"); - } - if (fd->secret->nonblocking) { - if (err == kOTNoDataErr) - err = EINPROGRESS; - goto ErrorExit; - } else { - if (err != kOTNoError && err != kOTNoDataErr) { - me->io_pending = PR_FALSE; - goto ErrorExit; - } - } - + if (err != kOTNoError && err != kOTNoDataErr) + goto ErrorExit; + if (err == kOTNoDataErr && fd->secret->nonblocking) { + err = kEINPROGRESSErr; + me->io_pending = PR_FALSE; + goto ErrorExit; + } + WaitOnThisThread(me, timeout); err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; + PR_ASSERT(me->md.cookie != NULL); + + err = OTRcvConnect(endpoint, NULL); + PR_ASSERT(err == kOTNoError); + return kOTNoError; ErrorExit: @@ -1130,7 +1001,6 @@ ErrorExit: return -1; } - // Errors: // EBADF -- bad socket id // EFAULT -- bad buffer @@ -1139,7 +1009,8 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, { OSStatus err; OTResult result; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + PRInt32 osfd = fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 bytesLeft = amount; @@ -1162,57 +1033,48 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount, while (bytesLeft > 0) { - PrepareForAsyncCompletion(me, fd); + PrepareThreadForAsyncIO(me, endpoint, osfd); - if (opCode == kSTREAM_SEND) { - fd->secret->md.write.thread = me; - fd->secret->md.writeReady = PR_FALSE; // expect the worst + if (opCode == kSTREAM_SEND) result = OTSnd(endpoint, buf, bytesLeft, NULL); - if (result != kOTFlowErr) // hope for the best - fd->secret->md.writeReady = PR_TRUE; - } else { - fd->secret->md.read.thread = me; - fd->secret->md.readReady = PR_FALSE; // expect the worst + else result = OTRcv(endpoint, buf, bytesLeft, NULL); - if (result != kOTNoDataErr) // hope for the best - fd->secret->md.readReady = PR_TRUE; - } - me->io_pending = PR_FALSE; if (result > 0) { buf = (void *) ( (UInt32) buf + (UInt32)result ); bytesLeft -= result; + me->io_pending = PR_FALSE; if (opCode == kSTREAM_RECEIVE) return result; } else { - switch (result) { - case kOTOutStateErr: // it has been closed - return 0; - - case kOTLookErr: - PR_ASSERT(!"call to OTLook() required after all."); - break; - - case kOTFlowErr: - case kOTNoDataErr: - case kEAGAINErr: - case kEWOULDBLOCKErr: - if (fd->secret->nonblocking) { - err = result; - goto ErrorExit; - } - - WaitOnThisThread(me, timeout); - err = me->md.osErrCode; - if (err != kOTNoError) - goto ErrorExit; - break; - - default: - err = result; - goto ErrorExit; - } - } + if (result == kOTOutStateErr) { /* it has been closed */ + me->io_pending = PR_FALSE; + return 0; + } + if (result == kOTLookErr) { + PRBool readReady,writeReady,exceptReady; + /* process the event and then continue the operation */ + (void) GetState(endpoint, &readReady, &writeReady, &exceptReady); + continue; + } + if (result != kOTNoDataErr && result != kOTFlowErr && + result != kEAGAINErr && result != kEWOULDBLOCKErr) { + me->io_pending = PR_FALSE; + err = result; + goto ErrorExit; + } else if (fd->secret->nonblocking) { + me->io_pending = PR_FALSE; + err = result; + goto ErrorExit; + } + WaitOnThisThread(me, timeout); + me->io_pending = PR_FALSE; + err = me->md.osErrCode; + if (err != kOTNoError) + goto ErrorExit; + + PR_ASSERT(me->md.cookie != NULL); + } } return amount; @@ -1222,14 +1084,12 @@ ErrorExit: return -1; } - PRInt32 _MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { return (SendReceiveStream(fd, buf, amount, flags, timeout, kSTREAM_RECEIVE)); } - PRInt32 _MD_send(PRFileDesc *fd,const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { @@ -1245,11 +1105,11 @@ static PRInt32 SendReceiveDgram(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntervalTime timeout, SndRcvOpCode opCode) { OSStatus err; - EndpointRef endpoint = (EndpointRef) fd->secret->md.osfd; + PRInt32 osfd = fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; PRThread *me = _PR_MD_CURRENT_THREAD(); PRInt32 bytesLeft = amount; TUnitData dgram; - OTResult result; PR_ASSERT(flags == 0); @@ -1278,33 +1138,28 @@ static PRInt32 SendReceiveDgram(PRFileDesc *fd, void *buf, PRInt32 amount, while (bytesLeft > 0) { - PrepareForAsyncCompletion(me, fd); + PrepareThreadForAsyncIO(me, endpoint, osfd); - if (opCode == kDGRAM_SEND) { - fd->secret->md.write.thread = me; - fd->secret->md.writeReady = PR_FALSE; // expect the worst + if (opCode == kDGRAM_SEND) err = OTSndUData(endpoint, &dgram); - if (result != kOTFlowErr) // hope for the best - fd->secret->md.writeReady = PR_TRUE; - } else { - fd->secret->md.read.thread = me; - fd->secret->md.readReady = PR_FALSE; // expect the worst + else err = OTRcvUData(endpoint, &dgram, NULL); - if (result != kOTNoDataErr) // hope for the best - fd->secret->md.readReady = PR_TRUE; - } if (err == kOTNoError) { buf = (void *) ( (UInt32) buf + (UInt32)dgram.udata.len ); bytesLeft -= dgram.udata.len; dgram.udata.buf = (UInt8*) buf; me->io_pending = PR_FALSE; - } else { + } + else { PR_ASSERT(err == kOTNoDataErr || err == kOTOutStateErr); WaitOnThisThread(me, timeout); + me->io_pending = PR_FALSE; err = me->md.osErrCode; if (err != kOTNoError) goto ErrorExit; + + PR_ASSERT(me->md.cookie != NULL); } } @@ -1318,7 +1173,6 @@ ErrorExit: return -1; } - PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout) @@ -1327,7 +1181,6 @@ PRInt32 _MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount, timeout, kDGRAM_RECEIVE)); } - PRInt32 _MD_sendto(PRFileDesc *fd,const void *buf, PRInt32 amount, PRIntn flags, PRNetAddr *addr, PRUint32 addrlen, PRIntervalTime timeout) @@ -1336,7 +1189,6 @@ PRInt32 _MD_sendto(PRFileDesc *fd,const void *buf, PRInt32 amount, timeout, kDGRAM_SEND)); } - PRInt32 _MD_closesocket(PRInt32 osfd) { OSStatus err; @@ -1351,7 +1203,35 @@ PRInt32 _MD_closesocket(PRInt32 osfd) if (me->io_pending && me->io_fd == osfd) me->io_pending = PR_FALSE; +#if 0 + { + OTResult state; + state = OTGetEndpointState(endpoint); + + err = OTSndOrderlyDisconnect(endpoint); + if (err != kOTNoError && err != kOTOutStateErr) + goto ErrorExit; + + state = OTGetEndpointState(endpoint); + + err = OTUnbind(endpoint); + if (err != kOTNoError && err != kOTOutStateErr) + goto ErrorExit; + + state = OTGetEndpointState(endpoint); + + err = OTSetSynchronous(endpoint); + if (err != kOTNoError) + goto ErrorExit; + + err = OTSetBlocking(endpoint); + if (err != kOTNoError) + goto ErrorExit; + } +#endif + (void) OTSndOrderlyDisconnect(endpoint); + err = OTCloseProvider(endpoint); if (err != kOTNoError) goto ErrorExit; @@ -1363,7 +1243,6 @@ ErrorExit: return -1; } - PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) { #pragma unused (fd, iov, iov_size, timeout) @@ -1373,15 +1252,39 @@ PRInt32 _MD_writev(PRFileDesc *fd, const struct PRIOVec *iov, PRInt32 iov_size, return -1; } - -static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady) +static PRBool GetState(EndpointRef endpoint, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady) { + OSStatus err; OTResult resultOT; + TDiscon discon; + PRBool result = PR_FALSE; - *readReady = fd->secret->md.readReady; - *exceptReady = fd->secret->md.exceptReady; + *readReady = *writeReady = *exceptReady = PR_FALSE; - resultOT = OTGetEndpointState((EndpointRef)fd->secret->md.osfd); + resultOT = OTLook(endpoint); + switch (resultOT) { + case T_DATA: + case T_LISTEN: + *readReady = PR_TRUE; + break; + case T_CONNECT: + err = OTRcvConnect(endpoint, NULL); + PR_ASSERT(err == kOTNoError); + break; + case T_DISCONNECT: + memset(&discon, 0 , sizeof(discon)); + err = OTRcvDisconnect(endpoint, &discon); + PR_ASSERT(err == kOTNoError); + macsock_map_error(discon.reason); + *exceptReady = PR_TRUE; + break; + case T_ORDREL: + *readReady = PR_TRUE; + err = OTRcvOrderlyDisconnect(endpoint); + PR_ASSERT(err == kOTNoError); + break; + } + resultOT = OTGetEndpointState(endpoint); switch (resultOT) { case T_DATAXFER: case T_INREL: @@ -1391,9 +1294,11 @@ static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PR *writeReady = PR_FALSE; } - return *readReady || *writeReady || *exceptReady; -} + if ((*readReady == PR_TRUE) || (*writeReady==PR_TRUE) || (*exceptReady==PR_TRUE)) + result = PR_TRUE; + return result; +} PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) { @@ -1412,7 +1317,7 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) { for (pd = pds, epd = pd + npds; pd < epd; pd++) { - PRInt16 in_flags_read = 0, in_flags_write = 0; + 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; @@ -1435,15 +1340,20 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) } else { - PRFileDesc *bottomFD; + PRFileDesc *bottom; + EndpointRef endpoint; PRBool readReady, writeReady, exceptReady; pd->out_flags = 0; /* pre-condition */ - bottomFD = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); - PR_ASSERT(NULL != bottomFD); - if ((NULL != bottomFD) && (_PR_FILEDESC_OPEN == bottomFD->secret->state)) + bottom = PR_GetIdentitiesLayer(pd->fd, PR_NSPR_IO_LAYER); + PR_ASSERT(NULL != bottom); + if ((NULL != bottom) + && (_PR_FILEDESC_OPEN == bottom->secret->state)) { - if (GetState(bottomFD, &readReady, &writeReady, &exceptReady)) + endpoint = (EndpointRef)bottom->secret->md.osfd; + + if (GetState(endpoint, + &readReady, &writeReady, &exceptReady)) { if (readReady) { @@ -1484,56 +1394,15 @@ PRInt32 _MD_poll(PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout) return 0; /* timed out */ } - -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.connectionOpen = PR_FALSE; // starts out closed - 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); - } -} - 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 the PRFileDesc as the contextPtr for the Notifier function associated with this Endpoint. - err = OTInstallNotifier(endpointRef, NotifierRoutine, fd); - PR_ASSERT(err == kOTNoError); - - // Now that we have a NotifierRoutine installed, we can make the endpoint asynchronous - err = OTSetAsynchronous(endpointRef); - PR_ASSERT(err == kOTNoError); -} + OSStatus err; + PRInt32 osfd = fd->secret->md.osfd; + EndpointRef endpoint = (EndpointRef) osfd; + err = OTSetNonBlocking(endpoint); + PR_ASSERT(err == kOTNoError || err == kOTOutStateErr); +} PR_IMPLEMENT(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how) { @@ -1543,7 +1412,6 @@ PR_IMPLEMENT(PRInt32) _MD_shutdown(PRFileDesc *fd, PRIntn how) return (0); } - PR_IMPLEMENT(PRStatus) _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen) { #pragma unused (fd, addr, addrlen) @@ -1571,21 +1439,15 @@ static struct hostent sHostEnt = {NULL, &sAliases[0], AF_INET, sizeof (long), NU 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(); - me->io_pending = PR_TRUE; - me->io_fd = NULL; - me->md.osErrCode = noErr; - - PR_Lock(dnsContext.lock); // so we can safely store our thread ptr in dnsContext - dnsContext.thread = me; // so we know what thread to wake up when OTInetStringToAddress completes + PrepareThreadForAsyncIO(me, sSvcRef, NULL); - err = OTInetStringToAddress(dnsContext.serviceRef, (char *)name, &sHostInfo); + err = OTInetStringToAddress(sSvcRef, (char *)name, &sHostInfo); if (err != kOTNoError) { me->io_pending = PR_FALSE; me->md.osErrCode = err; @@ -1593,7 +1455,6 @@ PR_IMPLEMENT(struct hostent *) gethostbyname(const char * name) } WaitOnThisThread(me, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(dnsContext.lock); if (me->md.osErrCode != kOTNoError) goto ErrorExit; @@ -1636,7 +1497,7 @@ PRStatus _MD_gethostname(char *name, int namelen) InetInterfaceInfo info; /* - * On a Macintosh, we don't have the concept of a local host name. + * On a Macintosh, we donŐt have the concept of a local host name. * We do though have an IP address & everyone should be happy with * a string version of that for a name. * The alternative here is to ping a local DNS for our name, they @@ -1710,7 +1571,7 @@ int _MD_mac_get_nonblocking_connect_error(PRInt32 osfd) resultOT = OTGetEndpointState(endpoint); switch (resultOT) { case T_OUTCON: - macsock_map_error(EINPROGRESS); + macsock_map_error(kEINPROGRESSErr); return -1; case T_DATAXFER: return 0; |