1.1 --- a/PortMapper/MYDNSService.m Fri Apr 24 10:10:32 2009 -0700
1.2 +++ b/PortMapper/MYDNSService.m Mon Apr 27 09:03:56 2009 -0700
1.3 @@ -27,20 +27,32 @@
1.4
1.5 - (void) dealloc
1.6 {
1.7 + Log(@"DEALLOC %@ %p", self.class,self);
1.8 if( _serviceRef )
1.9 - [self stopService];
1.10 + [self cancel];
1.11 [super dealloc];
1.12 }
1.13
1.14 - (void) finalize
1.15 {
1.16 if( _serviceRef )
1.17 - [self stopService];
1.18 + [self cancel];
1.19 [super finalize];
1.20 }
1.21
1.22
1.23 -@synthesize serviceRef=_serviceRef, error=_error;
1.24 +- (DNSServiceErrorType) error {
1.25 + return _error;
1.26 +}
1.27 +
1.28 +- (void) setError: (DNSServiceErrorType)error {
1.29 + if (error)
1.30 + Warn(@"%@ error := %i", self,error);
1.31 + _error = error;
1.32 +}
1.33 +
1.34 +
1.35 +@synthesize continuous=_continuous, serviceRef=_serviceRef;
1.36
1.37
1.38 - (DNSServiceRef) createServiceRef {
1.39 @@ -48,11 +60,17 @@
1.40 }
1.41
1.42
1.43 -- (BOOL) open
1.44 +- (BOOL) start
1.45 {
1.46 if (_serviceRef)
1.47 - return YES;
1.48 + return YES; // already started
1.49 +
1.50 + if (_error)
1.51 + self.error = 0;
1.52 +
1.53 + // Ask the subclass to create a DNSServiceRef:
1.54 _serviceRef = [self createServiceRef];
1.55 +
1.56 if (_serviceRef) {
1.57 // Wrap a CFSocket around the service's socket:
1.58 CFSocketContext ctxt = { 0, self, CFRetain, CFRelease, NULL };
1.59 @@ -66,7 +84,7 @@
1.60 _socketSource = CFSocketCreateRunLoopSource(NULL, _socket, 0);
1.61 if( _socketSource ) {
1.62 CFRunLoopAddSource(CFRunLoopGetCurrent(), _socketSource, kCFRunLoopCommonModes);
1.63 - LogTo(DNS,@"Opening %@",self);
1.64 + LogTo(DNS,@"Opening %@ -- service=%p",self,_serviceRef);
1.65 return YES; // success
1.66 }
1.67 }
1.68 @@ -74,13 +92,14 @@
1.69 if (!_error)
1.70 self.error = kDNSServiceErr_Unknown;
1.71 LogTo(DNS,@"Failed to open %@ -- err=%i",self,_error);
1.72 - [self stopService];
1.73 + [self cancel];
1.74 return NO;
1.75 }
1.76
1.77
1.78 -- (void) stopService
1.79 +- (void) cancel
1.80 {
1.81 + [self retain]; // Prevents _socket's dealloc from releasing & deallocing me!
1.82 if( _socketSource ) {
1.83 CFRunLoopSourceInvalidate(_socketSource);
1.84 CFRelease(_socketSource);
1.85 @@ -96,17 +115,45 @@
1.86 DNSServiceRefDeallocate(_serviceRef);
1.87 _serviceRef = NULL;
1.88 }
1.89 + [self release];
1.90 }
1.91
1.92
1.93 -- (void) close
1.94 +- (void) stop
1.95 {
1.96 - [self stopService];
1.97 + [self cancel];
1.98 if (_error)
1.99 self.error = 0;
1.100 }
1.101
1.102
1.103 +- (BOOL) priv_processResult
1.104 +{
1.105 + Assert(_serviceRef);
1.106 + DNSServiceErrorType err = DNSServiceProcessResult(_serviceRef);
1.107 + if (err) {
1.108 + // An error here means the socket has failed and should be closed.
1.109 + self.error = err;
1.110 + [self cancel];
1.111 + return NO;
1.112 + } else {
1.113 + if (!_continuous)
1.114 + [self cancel];
1.115 + return YES;
1.116 + }
1.117 +}
1.118 +
1.119 +- (BOOL) waitForReply
1.120 +{
1.121 + if (!_serviceRef)
1.122 + return NO;
1.123 + LogTo(DNS,@"Waiting for %@ ...", self);
1.124 + BOOL ok = [self priv_processResult];
1.125 + LogTo(DNS,@" ...done waiting");
1.126 + return ok;
1.127 +}
1.128 +
1.129 +
1.130 /** CFSocket callback, informing us that _socket has data available, which means
1.131 that the DNS service has an incoming result to be processed. This will end up invoking
1.132 the service's specific callback. */
1.133 @@ -114,14 +161,11 @@
1.134 CFSocketCallBackType type,
1.135 CFDataRef address, const void *data, void *clientCallBackInfo)
1.136 {
1.137 - MYDNSService *serviceObj = (MYDNSService*)clientCallBackInfo;
1.138 - DNSServiceRef service = serviceObj.serviceRef;
1.139 - DNSServiceErrorType err = DNSServiceProcessResult(service);
1.140 - if( err ) {
1.141 - // An error here means the socket has failed and should be closed.
1.142 - serviceObj.error = err;
1.143 - [serviceObj stopService];
1.144 - }
1.145 + NSAutoreleasePool *pool = [NSAutoreleasePool new];
1.146 + @try{
1.147 + [(MYDNSService*)clientCallBackInfo priv_processResult];
1.148 + }catchAndReport(@"PortMapper serviceCallback");
1.149 + [pool drain];
1.150 }
1.151
1.152