PageRenderTime 18ms CodeModel.GetById 11ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/core/externals/update-engine/externals/google-toolbox-for-mac/Foundation/GTMAbstractDOListener.h

http://macfuse.googlecode.com/
C++ Header | 231 lines | 48 code | 23 blank | 160 comment | 0 complexity | faa0e785464bd824f9a2b32579f44190 MD5 | raw file
  1//
  2//  GTMAbstractDOListener.h
  3//
  4//  Copyright 2006-2009 Google Inc.
  5//
  6//  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  7//  use this file except in compliance with the License.  You may obtain a copy
  8//  of the License at
  9//
 10//  http://www.apache.org/licenses/LICENSE-2.0
 11//
 12//  Unless required by applicable law or agreed to in writing, software
 13//  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 14//  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 15//  License for the specific language governing permissions and limitations under
 16//  the License.
 17//
 18#import <Foundation/Foundation.h>
 19#import "GTMDefines.h"
 20
 21#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
 22@class GTMReceivePortDelegate;
 23#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
 24
 25// Abstract base class for DO "listeners".
 26// A class that needs to vend itself over DO should subclass this abstract 
 27// class.  This class takes care of certain things like creating a new thread 
 28// to handle requests, setting request/reply timeouts, and ensuring the vended
 29// object only gets requests that comply with the specified protocol.
 30//
 31// Subclassers will want to use the
 32// GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL macro for easier debugging
 33// of stack traces. Please read it's description below.
 34//
 35@interface GTMAbstractDOListener : NSObject <NSConnectionDelegate> {
 36 @protected
 37  NSString *registeredName_;
 38  __weak Protocol *protocol_;
 39  NSConnection *connection_;
 40  BOOL isRunningInNewThread_;
 41  BOOL shouldShutdown_;
 42  NSTimeInterval requestTimeout_;
 43  NSTimeInterval replyTimeout_;
 44  NSPort *port_;
 45  NSTimeInterval heartRate_;
 46
 47#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
 48  GTMReceivePortDelegate *receivePortDelegate_;  // Strong (only used on Tiger)
 49#endif // MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
 50}
 51
 52// Returns a set of all live instances of GTMAbstractDOListener subclasses.
 53// If no listeners have been created, this will return an empty array--not nil.
 54//
 55// TODO: Remove this method
 56//
 57+ (NSArray *)allListeners;
 58
 59// Initializer.  This actually calls
 60// initWithRegisteredName:protocol:port with [NSMachPort port] as the port.
 61//
 62// Args:
 63//   name - the name that the object will register under
 64//   proto - the protocol that this object (self) should conform to
 65//
 66- (id)initWithRegisteredName:(NSString *)name protocol:(Protocol *)proto;
 67
 68// The designated initializer.
 69//
 70// Args:
 71//   name - the name used to register the port.  While not necessarily required
 72//          for an NSSocketPort this class still requires it.
 73//   proto - the protocol that this object (self) should conform to
 74//   port - the port to be used when creating the NSConnection.  If a NSMachPort
 75//          is being used then initWithRegisteredName:protocol is recommended.
 76//          Otherwise the port must be allocted by the caller.
 77//
 78- (id)initWithRegisteredName:(NSString *)name
 79                    protocol:(Protocol *)proto
 80                        port:(NSPort *)port;
 81
 82// Returns the name that this server will register with the 
 83// mach port name sever.  This is the name of the port that this class
 84// will "listen" on when -runInNewThread is called.
 85//
 86// Returns:
 87//   The registered name as a string
 88//
 89- (NSString *)registeredName;
 90
 91// Sets the registered name to use when listening over DO.  This only makes
 92// sense to be called before -runInNewThread has been called, because
 93// -runInNewThread will listen on this "registered name", so setting it
 94// afterwards would do nothing.
 95//
 96// Args:
 97//   name - the name to register under.  May not be nil.
 98//
 99- (void)setRegisteredName:(NSString *)name;
100
101// Get/set the request timeout interval.  If set to a value less than 0,
102// the default DO connection timeout will be used (maximum possible value).
103//
104- (NSTimeInterval)requestTimeout;
105- (void)setRequestTimeout:(NSTimeInterval)timeout;
106
107// Get/set the reply timeout interval.  If set to a value less than 0,
108// the default DO connection timeout will be used (maximum possible value).
109//
110- (NSTimeInterval)replyTimeout;
111- (void)setReplyTimeout:(NSTimeInterval)timeout;
112
113// Get/set how long the thread will spin the run loop.  This only takes affect
114// if runInNewThreadWithErrorTarget:selector:withObjectArgument: is used.  The
115// default heart rate is 10.0 seconds.
116//
117- (void)setThreadHeartRate:(NSTimeInterval)heartRate;
118- (NSTimeInterval)ThreadHeartRate;
119
120// Returns the listeners associated NSConnection.  May be nil if no connection
121// has been setup yet.
122//
123- (NSConnection *)connection;
124
125// Starts the DO system listening using the current thread and current runloop.
126// It only makes sense to call this method -OR- -runInNewThread, but not both.
127// Returns YES if it was able to startup the DO listener, NO otherwise.
128//
129- (BOOL)runInCurrentThread;
130
131// Starts the DO system listening, and creates a new thread to handle the DO
132// connections.  It only makes sense to call this method -OR-
133// -runInCurrentThread, but not both.
134// if |errObject| is non nil, it will be used along with |selector| and
135// |argument| to signal that the startup of the listener in the new thread
136// failed.  The actual selector will be invoked back on the main thread so
137// it does not have to be thread safe.
138// The most basic way to call this method is as follows:
139//    [listener runInNewThreadWithErrorTarget:nil
140//                                   selector:NULL
141//                         withObjectArgument:nil];
142//
143// Note: Using the example above you will not know if the listener failed to
144// startup due to some error.
145//
146- (void)runInNewThreadWithErrorTarget:(id)errObject
147                             selector:(SEL)selector
148                   withObjectArgument:(id)argument;
149
150// Shuts down the connection.  If it was running in a new thread, that thread
151// should exit (within about 10 seconds).  This call does not block.
152//
153// NOTE: This method is called in -dealloc, so if -runInNewThread had previously
154// been called, -dealloc will return *before* the thread actually exits.  This
155// can be a problem as "self" may be gone before the thread exits.  This is a
156// bug and needs to be fixed.  Currently, to be safe, only call -shutdown if
157// -runInCurrentThread had previously been called.
158//
159- (void)shutdown;
160
161@end
162
163
164// Methods that subclasses may implement to vary the behavior of this abstract
165// class.
166//
167@interface GTMAbstractDOListener (GTMAbstractDOListenerSubclassMethods)
168
169// Called by the -runIn* methods.  In the case where a new thread is being used,
170// this method is called on the new thread.  The default implementation of this
171// method just returns YES, but subclasses can override it to do subclass
172// specific initialization.  If this method returns NO, the -runIn* method that
173// called it will fail with an error.
174//
175// Returns:
176//   YES if the -runIn* method should continue successfully, NO if the it should
177//   fail.
178//
179- (BOOL)doRunInitialization;
180
181// Called as the "main" for the thread spun off by GTMAbstractDOListener.
182// Not really for use by subclassers, except to use the 
183// GTMABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL macro defined below.
184//
185// This method runs forever in a new thread.  This method actually starts the
186// DO connection listening.
187//
188- (void)threadMain:(NSInvocation *)failureCallback;
189
190@end
191
192// GTMAbstractDOListeners used to be hard to debug because crashes in their
193// stacks looked like this:
194//
195// #0  0x90009cd7 in mach_msg_trap ()
196// #1  0x90009c38 in mach_msg ()
197// #2  0x9082d2b3 in CFRunLoopRunSpecific ()
198// #3  0x9082cace in CFRunLoopRunInMode ()
199// #4  0x9282ad3a in -[NSRunLoop runMode:beforeDate:] ()
200// #5  0x928788e4 in -[NSRunLoop runUntilDate:] ()
201// #6  0x00052696 in -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:] ...
202// #7  0x927f52e0 in forkThreadForFunction ()
203// #8  0x90024227 in _pthread_body ()
204//
205// and there was no good way to figure out what thread had the problem because
206// they all originated from
207// -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:]
208//
209// If you add GTMABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL to the impl of your
210// subclass you will get a stack that looks like this:
211// #0  0x90009cd7 in mach_msg_trap ()
212// #1  0x90009c38 in mach_msg ()
213// #2  0x9082d2b3 in CFRunLoopRunSpecific ()
214// #3  0x9082cace in CFRunLoopRunInMode ()
215// #4  0x9282ad3a in -[NSRunLoop runMode:beforeDate:] ()
216// #5  0x928788e4 in -[NSRunLoop runUntilDate:] ()
217// #6  0x00052696 in -[GTMAbstractDOListener(GTMAbstractDOListenerSubclassMethods) threadMain:] ...
218// #7  0x0004b35c in -[GDStatsListener threadMain:]
219// #8  0x927f52e0 in forkThreadForFunction () #9  0x90024227 in _pthread_body ()
220//
221// so we can see that this was the GDStatsListener thread that failed.
222// It will look something like this
223// @implemetation MySubclassOfGTMAbstractDOListenerSubclassMethods
224// GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL
225// ....
226// @end
227
228#define GTM_ABSTRACTDOLISTENER_SUBCLASS_THREADMAIN_IMPL \
229  - (void)threadMain:(NSInvocation *)failureCallback { \
230    [super threadMain:failureCallback]; \
231  }