home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 July: Mac OS SDK / Dev.CD Jul 97 SDK1.toast / Development Kits (Disc 1) / Apple Shared Library Manager / ASLM Examples / Example Tools / Sources / TArbitratorExample3.cp < prev    next >
Encoding:
Text File  |  1996-11-19  |  7.8 KB  |  201 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        TArbitratorExample3.cp
  3.  
  4.     Contains:    This module show an more complex example of how to use the TArbitrator class.
  5.  
  6.     Copyright:    © 1993 by Apple Computer, Inc., all rights reserved.
  7.  
  8. */
  9.  
  10. #include "TInitSLM.h"            // the TInitSLM class and SLM include files
  11.  
  12. ///————————————————————————————————————————————————————————————————————————————————————
  13. ///    CONSTANTS
  14. ///————————————————————————————————————————————————————————————————————————————————————
  15.  
  16. // id of the object we register with the arbitrator
  17. #define kObjectID    "tool:Arbt$MethodNotifier"
  18.  
  19. ///————————————————————————————————————————————————————————————————————————————————————
  20. ///    GLOBALS
  21. ///————————————————————————————————————————————————————————————————————————————————————
  22.  
  23. TArbitrator *gArbitrator;
  24.  
  25. ///————————————————————————————————————————————————————————————————————————————————————
  26. /// PROTOTYPES
  27. ///————————————————————————————————————————————————————————————————————————————————————
  28.  
  29. static TToken*    get_exclusive_access();
  30. static void        request_token(TProcNotifier *requestNotifier);
  31. static void        notify_owner( void*, EventCode, OSErrParm, void* theData );
  32. static void        notify_requester( void*, EventCode, OSErrParm, void* theData );
  33.  
  34. /*————————————————————————————————————————————————————————————————————————————————————
  35.     main 
  36.     
  37.     A Simple program demonstrating the use of TArbitrator & TToken. An object is created
  38.     and then registered with the arbitrator. This results in a token be created for the
  39.     object which is maintained by the arbitrator. When the object is then claimed for exclusive
  40.     access the arbitrator gives up the token to the new owner. The new owner creates a
  41.     a notifier for the token so it can be notified if anyone requests the token. A
  42.     requester then creates a notifier so that when it requests the token it will be
  43.     notified when it becomes available. When the request is made the owner's notifier
  44.     gets called. He gives up the token which then causes the requestor's notifier to get
  45.     called who then claims new ownership of the token.
  46.     
  47. ————————————————————————————————————————————————————————————————————————————————————*/
  48.  
  49. main()
  50. {    
  51.     TInitSLM initLibraryManager;                // initialize the shared library manager
  52.     
  53.     if( initLibraryManager.Failed() )        // If we failed, let's go home
  54.         return 1;
  55.  
  56.     void     *myobject = nil;        // this object we will register with the arbitrator
  57.     TToken     *exclusivetoken = nil;    // the token that will hold the object
  58.     
  59.     TRY
  60.         gArbitrator = new TArbitrator;        // create our own TArbitrator
  61.         FailNULL( gArbitrator, ErrorCode(), "Sorry failed to create an arbitrator");
  62.     
  63.         // allocate a block of memory that we will register so others can access it
  64.         myobject = new char[256];
  65.         FailNULL( myobject, ErrorCode(), "Sorry failed to allocate memory for our object");
  66.     
  67.         Fail( gArbitrator->RegisterObject(kObjectID, myobject), "Unable to register" );
  68.     
  69.         cout << "Registering an object at " << myobject << endl;
  70.         
  71.         FailNULL( exclusivetoken = get_exclusive_access(), ErrorCode(), "Failed to get exclusive access" );
  72.  
  73.         // %%% Why are we creating these. Give info about their purpose
  74.             
  75.         // Create a notifier for the owner of the object/token. It will be called when someone
  76.         // requests the token from the owner.
  77.         TProcNotifier ownernotifier( notify_owner );
  78.         exclusivetoken->SetNotifier( &ownernotifier );
  79.         
  80.         // Create a notifier for the requester of the object. It will be called when the
  81.         // request is fullfilled.
  82.         TProcNotifier requesternotifier( notify_requester );
  83.         request_token(&requesternotifier);
  84.     ENDTRY
  85.  
  86.     delete myobject;                    // clean up we are done                
  87.     delete gArbitrator;                    // You don't want this to hang-around, do you?
  88.  
  89.     return 0;
  90. }
  91.  
  92. /*————————————————————————————————————————————————————————————————————————————————————
  93.     get_exclusive_access
  94.     
  95.     call this routine once you have registered an object, and need to get exclusive
  96.     access to the object. This routine also checks to see if the exclusive access
  97.     was successful.
  98. ————————————————————————————————————————————————————————————————————————————————————*/
  99.  
  100. static TToken*    get_exclusive_access()
  101. {
  102.     TToken     *exclusivetoken = gArbitrator->GetToken( kObjectID, kExclusiveTokenRequest );
  103.  
  104.     if( exclusivetoken ) {                    // we got exclusive access
  105.             
  106.         // Now let's try to access it and we should fail
  107.         TToken *tmptoken = gArbitrator->GetToken( kObjectID, kExclusiveTokenRequest );
  108.  
  109.         if( tmptoken )                        // hopefully tmptoken should be nil
  110.             cout << "Hey, wait a minute! I was suppose to have exclusive access" << endl;
  111.         else {
  112.             cout << "Got exclusive access to the object at ";
  113.             cout << (void*)exclusivetoken->GetObject() << endl;
  114.         }
  115.     }
  116.     
  117.     return exclusivetoken;
  118. }
  119.  
  120. /*————————————————————————————————————————————————————————————————————————————————————
  121.     request_token
  122.     
  123.     this routine is called to request the token even though someone else may already
  124.     have exclusive access to it. We pass in a notifier that will be called when the
  125.     owner gives up access to the token.
  126. ————————————————————————————————————————————————————————————————————————————————————*/
  127.  
  128. static void request_token(TProcNotifier *requesterNotifier)
  129. {
  130.     // Call ActiveRequest to register a request for a token and notify the current
  131.     // owner that request is pending, and return the TRequestToken.  Once we have
  132.     // the request token we unregister the requested token by deleting it or by
  133.     // calling TRequestToken::Exchange, a method that returns the requested token
  134.     // if it is available and deletes the request.
  135.  
  136.     TRequestToken*  myrequest =
  137.         gArbitrator->ActiveRequest( kObjectID, kExclusiveTokenRequest, requesterNotifier );
  138.  
  139.     if( myrequest ) {
  140.         // The owner has been notified by now. If he didn't give up the token then
  141.         // Exchange() will return NULL. If this ever happens you can wait around until
  142.         // eventually the token is release at which time the requestor's notifer will
  143.         // be called, or you can just give up and delete the request token.
  144.         
  145.         TToken *reqtoken = myrequest->Exchange();
  146.         if( reqtoken ) {                    // this is the token we are looking for
  147.             if( reqtoken->GetObject() ) {
  148.                 cout << "Now we can have an exclusive access to the object ";
  149.                 cout << "located at " << (void*)reqtoken->GetObject() << endl;
  150.             }
  151.             else {
  152.                 cout << "Sorry, the owner wont let go of the object.\n" << endl;
  153.                 delete myrequest;            // We are done with our request
  154.             }
  155.         }
  156.     }
  157. }
  158.  
  159. /*————————————————————————————————————————————————————————————————————————————————————
  160.     notify_owner
  161.     
  162.     This routine is called when a requester requests a registered token. Here the 
  163.     owner can decide whether or not to give up an owned object to a TRequestToken.
  164. ————————————————————————————————————————————————————————————————————————————————————*/
  165.  
  166. static void notify_owner( void* refPtr, EventCode, OSErrParm, void* theData )
  167. {
  168.     TRequestToken    *requestedtoken;
  169.     
  170.     cout << "TMyNotifier::NotifyOwner……";
  171.     
  172.     if( requestedtoken = ((TTokenNotification *)theData)->GetRequestToken() ) {
  173.         // give up our exclusive access.
  174.         cout << " giving up an owned object to TRequestToken" << endl;
  175.         requestedtoken->Give(((TTokenNotification*)theData)->GetToken());
  176.     }
  177. }
  178.     
  179. /*————————————————————————————————————————————————————————————————————————————————————
  180.     notify_requester
  181.     
  182.     This routine is called to notify the requester whether when the request
  183.     has been granted. NotifyRequester can obtain the token by using the GetObject
  184.     method of the requested token.
  185. ————————————————————————————————————————————————————————————————————————————————————*/
  186.  
  187. static void notify_requester( void* refPtr, EventCode, OSErrParm, void* theData )
  188. {
  189.     TRequestToken    *requestedtoken;
  190.     
  191.     cout << "TMyNotifier::NotifyRequester……";
  192.     if( requestedtoken = ((TTokenNotification *)theData)->GetRequestToken() ) {
  193.         TToken*    thetoken = (TToken *)requestedtoken->GetObject();
  194.         if( thetoken ) {
  195.             cout << "got the requested token, now the buffer at ";
  196.             cout << (void*)thetoken->GetObject();
  197.             cout << " is available"<<endl;
  198.         }
  199.     }
  200. }
  201.