home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / threads.zip / iasyntfy.hpp < prev    next >
Text File  |  1996-02-15  |  11KB  |  206 lines

  1. #ifndef _IASYNTFY_
  2. #define _IASYNTFY_
  3. /*******************************************************************************
  4. * FILE NAME: iasyntfy.hpp
  5. *
  6. * DESCRIPTION:
  7. *   Declaration of the class(es):
  8. *     IAsyncNotifier - Base class for asynchronous notifiers.
  9. *
  10. * COPYRIGHT:
  11. *   Licensed Materials - Property of IBM
  12. *   (C) Copyright IBM Corporation 1995
  13. *   All Rights Reserved
  14. *   US Government Users Restricted Rights - Use, duplication, or disclosure
  15. *   restricted by GSA ADP Schedule Contract with IBM Corp.
  16. *
  17. *******************************************************************************/
  18. #ifndef _ISTDNTFY_
  19.   #include <istdntfy.hpp>
  20. #endif
  21.  
  22. // Other dependency classes.
  23. #ifndef  _IHANDLE_
  24.   #include <ihandle.hpp>
  25. #endif
  26.  
  27. #ifndef _IRESLOCK_
  28.   #include <ireslock.hpp>
  29. #endif
  30.  
  31. #pragma library("asyncnot.lib")
  32.  
  33. class IAsyncNotifierThread;
  34. template <class Element, class Key> class IKeySet;
  35.  
  36. // Align classes on four byte boundary.
  37. #pragma pack(4)
  38.  
  39. class IAsyncNotifier : public IStandardNotifier {
  40. /*******************************************************************************
  41. *
  42. * This abstract base class implements an asynchronous notification mechanism.
  43. * When a notification is sent via IAsyncNotifier::notifyObservers, it is not
  44. * sent synchronously as with IStandardNotifier, but is queued for later
  45. * dispatch.  In addition, if the asynchronous notifier has multiple internal
  46. * threads, the notification will be dispatched on the thread on which the
  47. * notifier was created regardless of which internal thread called
  48. * IAsyncNotifier::notifyObservers.  This class works for notifiers created
  49. * on GUI and non-GUI threads.
  50. *
  51. * If the current thread is going to be initialized for GUI, make sure it is
  52. * initialized for GUI (directly or indirectly) before any IAsyncNotifier
  53. * objects are created on the current thread.
  54. *
  55. * It is recommended that IAsyncNotifier objects be either enabled or disabled
  56. * for notification throughout their entire lifetime.  Since notifications are
  57. * generated and dispatched asynchronously, it is impossible to predict
  58. * exactly which notifications will not be dispatched if notification is
  59. * temporarily disabled.
  60. *
  61. * It is recommended that an IAsyncNotifier object not be deleted until a
  62. * notification has been processed that indicates that notification activity
  63. * for the object becomes quiescent.  For example, an IConversation::statusId
  64. * notification that indicates the conversation has closed.  In addition, if
  65. * you want to delete an IAsyncNotifier in response to one of its notifications,
  66. * do not use the delete operator.  In this case, you must use the deleteThis
  67. * member function.  If you are deleting the IAsyncNotifier at some other
  68. * time, for example as the thread it was created on terminates, use the
  69. * delete operator.
  70. *
  71. * An IAsyncNotifier object must be deleted on the same thread on which it was
  72. * created.  The deleteThis function may be used from any thread and this
  73. * condition will be met.  When an IAsyncNotifier object is deleted, all pending
  74. * notifications are destroyed and are never dispatched.  This is to ensure that
  75. * notifications are not sent for objects that do not exist.  The delete
  76. * notification is sent on the same thread on which the object is deleted.  When
  77. * deleteThis is used, the delete notification will occur on the same thread
  78. * on which the object was created.
  79. *
  80. * Subclass destructors must ensure that all internal threads are stopped.
  81. *
  82. *******************************************************************************/
  83.  
  84. public:
  85. /*------------------------------ Constructors ----------------------------------
  86. | You can not directly construct an object of this abstract base class.        |
  87. | An IAsyncNotifier object must be deleted on the same thread on which it was  |
  88. | created.  An invalid request exception is thrown if a delete is attempted    |
  89. | a different thread and the object will be in an undefined state.             |
  90. | Subclasses can initialize this class as follows:                             |
  91. |   - With the default constructor.                                            |
  92. |   - With the copy constructor.  The created object's dispatch thread is the  |
  93. |     current thread, not the dispatch thread of the parameter.                |
  94. |-----------------------------------------------------------------------------*/
  95. IAsyncNotifier ( );
  96.  
  97. IAsyncNotifier ( const IAsyncNotifier & asyncNotifier );
  98.  
  99. virtual ~IAsyncNotifier ( ) = 0;
  100.  
  101. /*----------------------------- Async Deletion ---------------------------------
  102. | Use this function rather than the delete operator to asynchronously delete   |
  103. | this object.                                                                 |
  104. |   deleteThis - Posts a notification to itself to safely delete itself.  This |
  105. |                function should be used instead of the delete operator when   |
  106. |                you wish to delete this object in response to one of its      |
  107. |                notifications.                                                |
  108. |-----------------------------------------------------------------------------*/
  109. IAsyncNotifier & deleteThis ( );
  110.  
  111. /*------------------------------- Assignment -----------------------------------
  112. | The assignment for this class is the standard assignment operator.           |
  113. |   operator = - The assignment operator must be used by subclasses to         |
  114. |                implement their own assignment operators.                     |
  115. |                The target object's dispatch thread is not changed.           |
  116. |-----------------------------------------------------------------------------*/
  117. IAsyncNotifier & operator = ( const IAsyncNotifier & rhs );
  118.  
  119. /*----------------------------------- Run --------------------------------------
  120. | Use this to start dispatching notifications for the current thread.          |
  121. |   run - If this thread is initialized for GUI,                               |
  122. |         IThread::current().processMsgs() is called and this function         |
  123. |         returns when that function returns.  If it is not initialized for    |
  124. |         GUI, it starts dispatching notification events.  This call does not  |
  125. |         return until there are no more objects with this thread as their     |
  126. |         dispatch thread.  If this is not a GUI thread and no IAsyncNotifier  |
  127. |         objects have been created on this thread, an invalid request         |
  128. |         exception is thrown.                                                 |
  129. |-----------------------------------------------------------------------------*/
  130. static void run ( );
  131.  
  132. /*-------------------------- Observer Notification -----------------------------
  133. | Use this function to asynchronously notify observers of an event.            |
  134. |   notifyObservers - If notification is enabled, queues notification for      |
  135. |                     dispatch and returns.                                    |
  136. |-----------------------------------------------------------------------------*/
  137. virtual IAsyncNotifier & notifyObservers ( const INotificationEvent & anEvent );
  138.  
  139. /*----------------------------- Dispatch Thread --------------------------------
  140. | Use this function to query the dispatch thread.                              |
  141. |   dispatchThread    - Returns the thread id for the dispatch thread.         |
  142. |-----------------------------------------------------------------------------*/
  143. const IThreadId & dispatchThread ( ) const;
  144.  
  145. /*-------------------------- Notification Clean Up -----------------------------
  146. | This function is called on the dispatch thread after each event from this    |
  147. | IAsyncNotifier is dispatched, but before the event is deleted.               |
  148. |   notificationCleanUp - The default implementation does nothing.  Subclasses |
  149. |                         must use this function to clean up objects that were |
  150. |                         created as event data.  Each subclass implementation |
  151. |                         must look like this:                                 |
  152. |                             if ( it is one of my events )                    |
  153. |                               delete the event data, if any                  |
  154. |                             else                                             |
  155. |                               BaseClass::notificationCleanUp ( anEvent );    |
  156. |-----------------------------------------------------------------------------*/
  157. virtual const IAsyncNotifier & notificationCleanUp (
  158.                                  const INotificationEvent & anEvent ) const;
  159.  
  160. /*---------------------------- Event Identifiers -------------------------------
  161. | Event Ids for notification purposes.                                         |
  162. |   dispatchThreadId - Id for the dispatch thread read only attribute.         |
  163. |-----------------------------------------------------------------------------*/
  164. static INotificationId const dispatchThreadId;
  165.  
  166. //******************* TEMPORARY ************************************************
  167. // The Visual Builder does not properly dereference pointers for reference
  168. // parameters on connections to actions and we would like to pass objects of
  169. // the class as reference parameters.  This will be fixed in the next
  170. // release.  In part by providing a "*this" attribute for all parts in addition
  171. // to the "this" attribute.  The work around to use a custom logic connection
  172. // to dereference and set the parameter does not work in the GA version due to
  173. // a code generation bug.  A fix for the bug will not be made until the first
  174. // CSD.  As the next best work around, I am temporarily adding a "*this"
  175. // attribute to the class.  These should be able to be deleted before GA
  176. // of the next release of VisualAge C++.
  177. //******************************************************************************
  178. IAsyncNotifier & thisRef () { return *this; }
  179. static INotificationId const thisRefId;
  180.  
  181.  
  182. protected:
  183. /*-------------------------- Observer Notification -----------------------------
  184. | Use this function to asynchronously notify observers of an event.            |
  185. |   notifyObservers - If notification is enabled, queues notification for      |
  186. |                     dispatch and returns.                                    |
  187. |-----------------------------------------------------------------------------*/
  188. virtual IAsyncNotifier & notifyObservers ( const INotificationId & nId );
  189.  
  190.  
  191. private:
  192. IAsyncNotifier & findOrCreateDispatchThread ( );
  193.  
  194. /*--------------------------- Private State Data -----------------------------*/
  195. IAsyncNotifierThread * theDispatchThread;
  196.  
  197. static IKeySet<IAsyncNotifierThread *, IThreadId> * threads;
  198. static IPrivateResource                             threadsKey;
  199.  
  200. }; // IAsyncNotifier
  201.  
  202. // Resume compiler default packing.
  203. #pragma pack()
  204.  
  205. #endif // _IASYNTFY_
  206.