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