summaryrefslogtreecommitdiff
path: root/pr/src/md/mac/macsockotpt.c
diff options
context:
space:
mode:
Diffstat (limited to 'pr/src/md/mac/macsockotpt.c')
-rw-r--r--pr/src/md/mac/macsockotpt.c129
1 files changed, 75 insertions, 54 deletions
diff --git a/pr/src/md/mac/macsockotpt.c b/pr/src/md/mac/macsockotpt.c
index 7b6e4441..53023ad0 100644
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -29,6 +29,12 @@
#define GESTALT_OPEN_TPT_TCP_PRESENT gestaltOpenTptTCPPresentMask
#include <OpenTptInternet.h> // All the internet typedefs
+
+#if (UNIVERSAL_INTERFACES_VERSION >= 0x0330)
+// for some reason Apple removed this typedef.
+typedef struct OTConfiguration OTConfiguration;
+#endif
+
#include "primpl.h"
typedef enum SndRcvOpCode {
@@ -45,11 +51,10 @@ static struct {
void * cookie;
} dnsContext;
-static PRBool gOTInitialized;
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 pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
+static pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie);
static PRBool GetState(PRFileDesc *fd, PRBool *readReady, PRBool *writeReady, PRBool *exceptReady);
@@ -59,24 +64,20 @@ extern void DoneWaitingOnThisThread(PRThread *thread);
#if TARGET_CARBON
OTClientContextPtr clientContext = NULL;
-OTNotifyUPP DNSNotifierRoutineUPP;
-OTNotifyUPP notifierRoutineUPP;
-
-#define DNS_NOTIFIER_ROUTINE DNSNotifierRoutineUPP
-#define NOTIFIER_ROUTINE notifierRoutineUPP
-#define INIT_OPEN_TRANSPORT() InitOpenTransport(clientContext, kInitOTForExtensionMask)
-#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServices(config, flags, err, clientContext)
-#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpoint(config, flags, info, err, clientContext)
+#define INIT_OPEN_TRANSPORT() InitOpenTransportInContext(kInitOTForExtensionMask, &clientContext)
+#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServicesInContext(config, flags, err, clientContext)
+#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpointInContext(config, flags, info, err, clientContext)
#else
-#define DNS_NOTIFIER_ROUTINE DNSNotifierRoutine
-#define NOTIFIER_ROUTINE NotifierRoutine
#define INIT_OPEN_TRANSPORT() InitOpenTransport()
#define OT_OPEN_INTERNET_SERVICES(config, flags, err) OTOpenInternetServices(config, flags, err)
#define OT_OPEN_ENDPOINT(config, flags, info, err) OTOpenEndpoint(config, flags, info, err)
#endif /* TARGET_CARBON */
+static OTNotifyUPP DNSNotifierRoutineUPP;
+static OTNotifyUPP NotifierRoutineUPP;
+static OTNotifyUPP RawEndpointNotifierRoutineUPP;
void _MD_InitNetAccess()
{
@@ -97,26 +98,20 @@ void _MD_InitNetAccess()
PR_ASSERT(hasOTTCPIP == PR_TRUE);
-#if TARGET_CARBON
DNSNotifierRoutineUPP = NewOTNotifyUPP(DNSNotifierRoutine);
- notifierRoutineUPP = NewOTNotifyUPP(NotifierRoutine);
-
- errOT = OTAllocClientContext((UInt32)0, &clientContext);
- PR_ASSERT(err == kOTNoError);
-#endif
-
+ NotifierRoutineUPP = NewOTNotifyUPP(NotifierRoutine);
+ RawEndpointNotifierRoutineUPP = NewOTNotifyUPP(RawEndpointNotifierRoutine);
errOT = INIT_OPEN_TRANSPORT();
PR_ASSERT(err == kOTNoError);
+ dnsContext.serviceRef = NULL;
dnsContext.lock = PR_NewLock();
PR_ASSERT(dnsContext.lock != NULL);
dnsContext.thread = _PR_MD_CURRENT_THREAD();
dnsContext.cookie = NULL;
- gOTInitialized = PR_FALSE;
-
/* XXX Does not handle absence of open tpt and tcp yet! */
}
@@ -124,36 +119,65 @@ static void _MD_FinishInitNetAccess()
{
OSStatus errOT;
+ if (dnsContext.serviceRef)
+ return;
+
dnsContext.serviceRef = OT_OPEN_INTERNET_SERVICES(kDefaultInternetServicesPath, NULL, &errOT);
- if (errOT != kOTNoError) return; /* no network -- oh well */
+ if (errOT != kOTNoError) {
+ dnsContext.serviceRef = NULL;
+ return; /* no network -- oh well */
+ }
+
PR_ASSERT((dnsContext.serviceRef != NULL) && (errOT == kOTNoError));
/* Install notify function for DNR Address To String completion */
- errOT = OTInstallNotifier(dnsContext.serviceRef, DNS_NOTIFIER_ROUTINE, &dnsContext);
+ errOT = OTInstallNotifier(dnsContext.serviceRef, DNSNotifierRoutineUPP, &dnsContext);
PR_ASSERT(errOT == kOTNoError);
/* Put us into async mode */
errOT = OTSetAsynchronous(dnsContext.serviceRef);
PR_ASSERT(errOT == kOTNoError);
-
- gOTInitialized = PR_TRUE;
}
-pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
+static pascal void DNSNotifierRoutine(void * contextPtr, OTEventCode otEvent, OTResult result, void * cookie)
{
#pragma unused(contextPtr)
_PRCPU * cpu = _PR_MD_CURRENT_CPU();
-
- if (code == T_DNRSTRINGTOADDRCOMPLETE) {
+ OSStatus errOT;
+
dnsContext.thread->md.osErrCode = result;
dnsContext.cookie = cookie;
- if (_PR_MD_GET_INTSOFF()) {
- cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
- dnsContext.thread->md.missedIONotify = PR_TRUE;
- return;
- }
- DoneWaitingOnThisThread(dnsContext.thread);
+
+ switch (otEvent) {
+ case T_DNRSTRINGTOADDRCOMPLETE:
+ if (_PR_MD_GET_INTSOFF()) {
+ cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+ dnsContext.thread->md.missedIONotify = PR_TRUE;
+ return;
+ }
+ DoneWaitingOnThisThread(dnsContext.thread);
+ break;
+
+ case kOTProviderWillClose:
+ errOT = OTSetSynchronous(dnsContext.serviceRef);
+ // fall through to kOTProviderIsClosed case
+
+ case kOTProviderIsClosed:
+ errOT = OTCloseProvider((ProviderRef)dnsContext.serviceRef);
+ dnsContext.serviceRef = nil;
+
+ if (_PR_MD_GET_INTSOFF()) {
+ cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+ dnsContext.thread->md.missedIONotify = PR_TRUE;
+ return;
+ }
+ DoneWaitingOnThisThread(dnsContext.thread);
+ break;
+
+ default: // or else we don't handle the event
+ PR_ASSERT(otEvent==NULL);
+
}
// or else we don't handle the event
}
@@ -262,7 +286,7 @@ WakeUpNotifiedThread(PRThread *thread, OTResult result)
// Notification routine
// Async callback routine.
// A5 is OK. Cannot allocate memory here
-pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
+static pascal void NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
{
PRFilePrivate *secret = (PRFilePrivate *) contextPtr;
_MDFileDesc * md = &(secret->md);
@@ -473,7 +497,6 @@ PRInt32 _MD_socket(int domain, int type, int protocol)
OSStatus err;
EndpointRef endpoint;
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
// We only deal with internet domain
@@ -1037,7 +1060,7 @@ typedef struct RawEndpointAndThread
// Notification routine for raw endpoints not yet attached to a PRFileDesc.
// Async callback routine.
// A5 is OK. Cannot allocate memory here
-pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
+static pascal void RawEndpointNotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
{
RawEndpointAndThread *endthr = (RawEndpointAndThread *) contextPtr;
PRThread * thread = endthr->thread;
@@ -1194,7 +1217,7 @@ PRInt32 _MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen, PRInterva
endthr->thread = me;
endthr->endpoint = (EndpointRef) newosfd;
- err = OTInstallNotifier((ProviderRef) newosfd, RawEndpointNotifierRoutine, endthr);
+ err = OTInstallNotifier((ProviderRef) newosfd, RawEndpointNotifierRoutineUPP, endthr);
PR_ASSERT(err == kOTNoError);
err = OTSetAsynchronous((EndpointRef) newosfd);
@@ -1350,6 +1373,7 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
PRInt32 bytesLeft = amount;
PR_ASSERT(flags == 0);
+ PR_ASSERT(opCode == kSTREAM_SEND || opCode == kSTREAM_RECEIVE);
if (endpoint == NULL) {
err = kEBADFErr;
@@ -1361,11 +1385,6 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
goto ErrorExit;
}
- if (opCode != kSTREAM_SEND && opCode != kSTREAM_RECEIVE) {
- err = kEINVALErr;
- goto ErrorExit;
- }
-
while (bytesLeft > 0) {
PrepareForAsyncCompletion(me, fd->secret->md.osfd);
@@ -1434,6 +1453,10 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
}
me->io_pending = PR_FALSE;
+ if (opCode == kSTREAM_SEND)
+ fd->secret->md.write.thread = nil;
+ else
+ fd->secret->md.read.thread = nil;
if (result > 0) {
buf = (void *) ( (UInt32) buf + (UInt32)result );
@@ -1442,9 +1465,6 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
return result;
} else {
switch (result) {
- case kOTOutStateErr: // it has been closed
- return 0;
-
case kOTLookErr:
PR_ASSERT(!"call to OTLook() required after all.");
break;
@@ -1464,6 +1484,7 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
goto ErrorExit;
break;
+ case kOTOutStateErr: // it has been closed, fall through to handle error
default:
err = result;
goto ErrorExit;
@@ -1471,9 +1492,13 @@ static PRInt32 SendReceiveStream(PRFileDesc *fd, void *buf, PRInt32 amount,
}
}
+ PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == nil :
+ fd->secret->md.read.thread == nil);
return amount;
ErrorExit:
+ PR_ASSERT(opCode == kSTREAM_SEND ? fd->secret->md.write.thread == nil :
+ fd->secret->md.read.thread == nil);
macsock_map_error(err);
return -1;
}
@@ -1789,7 +1814,7 @@ void _MD_makenonblock(PRFileDesc *fd)
// fd changes, but the secret structure does not;
// (b) the notifier func refers only to the secret data structure
// anyway.
- err = OTInstallNotifier(endpointRef, NOTIFIER_ROUTINE, fd->secret);
+ err = OTInstallNotifier(endpointRef, NotifierRoutineUPP, fd->secret);
PR_ASSERT(err == kOTNoError);
// Now that we have a NotifierRoutine installed, we can make the endpoint asynchronous
@@ -1862,11 +1887,11 @@ PR_IMPLEMENT(unsigned long) inet_addr(const char *cp)
OSStatus err;
InetHost host;
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
err = OTInetStringToHost((char*) cp, &host);
- PR_ASSERT(err == kOTNoError);
+ if (err != kOTNoError)
+ return -1;
return host;
}
@@ -1884,7 +1909,6 @@ PR_IMPLEMENT(struct hostent *) gethostbyname(const char * name)
PRUint32 index;
PRThread *me = _PR_MD_CURRENT_THREAD();
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
me->io_pending = PR_TRUE;
@@ -1925,7 +1949,6 @@ PR_IMPLEMENT(struct hostent *) gethostbyaddr(const void *addr, int addrlen, int
PR_ASSERT(type == AF_INET);
PR_ASSERT(addrlen == sizeof(struct in_addr));
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
OTInetHostToString((InetHost)addr, sHostInfo.name);
@@ -1936,7 +1959,6 @@ PR_IMPLEMENT(struct hostent *) gethostbyaddr(const void *addr, int addrlen, int
PR_IMPLEMENT(char *) inet_ntoa(struct in_addr addr)
{
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
OTInetHostToString((InetHost)addr.s_addr, sHostInfo.name);
@@ -1950,7 +1972,6 @@ PRStatus _MD_gethostname(char *name, int namelen)
OSStatus err;
InetInterfaceInfo info;
- if (!gOTInitialized)
_MD_FinishInitNetAccess();
/*