home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 …ember: Reference Library / Apple Developer Reference Library (December 1999) (Disk 1).iso / pc / technical documentation / develop / develop issue 26 / develop issue 26 code / truffles - display mgr. / sprocket / sources / aethreads.cp next >
Encoding:
Text File  |  1995-05-30  |  4.0 KB  |  177 lines

  1. /*
  2.     File:        AEThreads.c
  3.                   
  4.     Contains:    Routines for installing threaded AppleEvent handlers
  5.  
  6.     Written by: Steve Sisak
  7.  
  8.      Copyright:    © 1993-94 Steve Sisak
  9.                 License is granted to use, modify, make derivative works, and 
  10.                 duplicate this code at will, so long as this notice remains intact.
  11.  
  12.     Change History (most recent first):
  13.     
  14.          <1>     1/24/95    DRF        First checked in.
  15. */
  16.  
  17. #ifndef __AETHREADS__
  18. #include "AEThreads.h"
  19. #endif
  20. #ifndef __ERRORS__
  21. #include <Errors.h>
  22. #endif
  23. #ifndef __APPLEEVENTS__
  24. #include <AppleEvents.h>
  25. #endif
  26.  
  27. #include "ThreadContext.h"
  28. #include "Exceptions.h"
  29.  
  30.  
  31. pascal OSErr SpawnAEThread(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
  32.  
  33. class AEThreadContext : public TThreadContext
  34. {
  35. protected:
  36.     AEEventHandlerUPP    fHandler;    // The real handler
  37.     const AppleEvent*    fEvent;
  38.     AppleEvent*            fReply;
  39.     long                fRefcon;
  40.  
  41. public:
  42.     AEThreadContext(AEEventHandlerUPP handler, const AppleEvent* event, AppleEvent* reply, long refcon) : fHandler(handler), fEvent(event), fReply(reply), fRefcon(refcon) {};
  43.     virtual    ~AEThreadContext() {};
  44.     
  45.     static pascal void*            AEThreadProc(AEThreadContext* context);
  46.  
  47.     friend pascal OSErr SpawnAEThread(const AppleEvent *theAppleEvent, AppleEvent *reply, long handlerRefcon);
  48. };
  49.  
  50. struct AEThreadDesc                    // Kept in the OS refcon
  51. {
  52.     AEEventHandlerUPP    handler;    // The real handler
  53.     long                refcon;        // The real refcon
  54.     Size                stackSize;    // Stack size for handling event
  55.     ThreadOptions        options;    // Thread options for event
  56.     ThreadID            holder;        // used as a semaphore
  57. };
  58.  
  59. AEEventHandlerUPP gSpawnAEThreadUPP = nil;
  60.  
  61. //#pragma segment foobar
  62.  
  63. pascal OSErr AEInstallThreadedEventHandler(
  64.     AEEventClass        theAEEventClass,
  65.     AEEventID            theAEEventID,
  66.     AEEventHandlerUPP    proc,
  67.     long                handlerRefcon,
  68.     ThreadOptions        options,
  69.     Size                stacksize)
  70. {
  71.     AEThreadDesc* desc = (AEThreadDesc*) NewPtr(sizeof(AEThreadDesc));
  72.     OSErr          err  = MemError();
  73.     
  74.     if (gSpawnAEThreadUPP == nil)
  75.     {
  76.         gSpawnAEThreadUPP = NewAEEventHandlerProc(SpawnAEThread);
  77.     }
  78.     
  79.     if (err == noErr)
  80.     {
  81.         desc->handler    = proc;
  82.         desc->refcon    = handlerRefcon;
  83.         desc->stackSize    = stacksize;
  84.         desc->options    = options;
  85.         desc->holder    = kNoThreadID;
  86.  
  87.         err = AEInstallEventHandler(theAEEventClass, theAEEventID, gSpawnAEThreadUPP, (long) desc, false);
  88.     }
  89.     
  90.     return err;
  91. }
  92.  
  93.  
  94. pascal void* AEThreadContext::AEThreadProc(AEThreadContext* context)
  95. {
  96.     OSErr result = noErr;
  97.  
  98.     Try
  99.     {
  100.         result = CallAEEventHandlerProc(context->fHandler, context->fEvent, context->fReply, context->fRefcon);
  101.  
  102.         // Since the event was suspended, we need to stuff the error code ourselves    
  103.         // note that there's not much we can do about reporting errors beyond here
  104.     }
  105.     Catch(err)
  106.     {
  107.         result = err;
  108.     }
  109.     
  110.     OSErr err;
  111.         
  112.     err = AEPutAttributePtr(context->fReply, keyErrorNumber, typeShortInteger, &result, sizeof(result));
  113.  
  114. #if qDebug
  115.     if (err)
  116.         ProgramBreak("\pAEPutAttributePtr failed installing error code - very bad");
  117. #endif
  118.  
  119.     err = AEResumeTheCurrentEvent(context->fEvent, context->fReply, kAENoDispatch, 0);    // This had better work
  120.  
  121. #if qDebug
  122.     if (err)
  123.         DebugStr("\pAEResumeTheCurrentEvent failed - very bad");
  124. #endif
  125.  
  126.     delete context;
  127.  
  128.     return nil;
  129. }
  130.  
  131. pascal OSErr AEHandleInThread(
  132.                     const AppleEvent*    event,
  133.                     AppleEvent*            reply,
  134.                     AEEventHandlerUPP    handler,
  135.                     long                handlerRefcon,
  136.                     ThreadOptions        options,
  137.                     Size                stacksize)
  138. {
  139.     OSErr             result;
  140.     AEThreadContext* context = new AEThreadContext(handler, event, reply, handlerRefcon);
  141.     
  142.     Try
  143.     {
  144.         FailNIL(context);
  145.     
  146.         context->CreateThread(kCooperativeThread, (ThreadEntryProcPtr) AEThreadContext::AEThreadProc, stacksize, options);
  147.  
  148.         result = AESuspendTheCurrentEvent(event);
  149.     }
  150.     Catch(err)
  151.     {
  152.         delete context;
  153.  
  154.         result = err;
  155.     }
  156.     
  157.     return result;
  158. }
  159.  
  160.  
  161. //#pragma segment Spawn
  162.  
  163. pascal OSErr SpawnAEThread(const AppleEvent *event, AppleEvent *reply, long handlerRefcon)
  164. {
  165.     AEThreadDesc* desc = (AEThreadDesc*) handlerRefcon;
  166.  
  167.      return AEHandleInThread(event, reply,
  168.                             desc->handler,
  169.                             desc->refcon,
  170.                             desc->options,
  171.                             desc->stackSize);
  172. }
  173.  
  174.  
  175.  
  176.  
  177.