home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / suplib.lzh / SUPLIB / SRC / ASYNCOP.C < prev    next >
C/C++ Source or Header  |  1991-08-16  |  3KB  |  147 lines

  1.  
  2. /*
  3.  *  ASYNCOP.C
  4.  */
  5.  
  6. #include <local/typedefs.h>
  7.  
  8. #define ASYMSG    struct _ASYMSG
  9. #define ASYHAN    struct _ASYHAN
  10.  
  11. ASYMSG {
  12.     MSG msg;
  13.     void (*func)();
  14.     long arg1;
  15.     long arg2;
  16.     long arg3;
  17. };
  18.  
  19. ASYHAN {
  20.     PORT *rport;    /*    Reply Port    */
  21.     PORT *port;     /*    Send Port    */
  22.     long acount;    /*    Messages Sent    */
  23.     long ccount;    /*    Messages Replied*/
  24.     long a4,a5;     /*    A4 and A5    */
  25. };
  26.  
  27. void asyhandler();
  28.  
  29. void *
  30. NewAsyncOp()
  31. {
  32.     register TASK *task;
  33.     register TASK *mytask = FindTask(NULL);
  34.     register ASYHAN *as = AllocMem(sizeof(ASYHAN), MEMF_CLEAR|MEMF_PUBLIC);
  35.  
  36.     as->rport = CreatePort(NULL, 0);
  37.     PutA4A5(&as->a4);
  38.     task = CreateTask("async.task", (ubyte)(mytask->tc_Node.ln_Pri + 1), (APTR)asyhandler, 4096);
  39.     task->tc_UserData = (APTR)as;
  40.  
  41.     Signal(task, SIGBREAKF_CTRL_F);
  42.     Wait(1 << as->rport->mp_SigBit);
  43.  
  44.     return((void *)as);
  45. }
  46.  
  47. void
  48. StartAsyncOp(_as, func, arg1, arg2, arg3)
  49. void *_as;
  50. void (*func)();
  51. int arg1, arg2, arg3;
  52. {
  53.     ASYHAN *as = (ASYHAN *)_as;
  54.     ASYMSG *am = (ASYMSG *)GetMsg(as->rport);    /*  Free Msg List   */
  55.  
  56.     if (!am) {
  57.     am = AllocMem(sizeof(ASYMSG), MEMF_PUBLIC|MEMF_CLEAR);
  58.     am->msg.mn_ReplyPort = as->rport;
  59.     }
  60.     am->func = func;
  61.     am->arg1 = arg1;
  62.     am->arg2 = arg2;
  63.     am->arg3 = arg3;
  64.     ++as->acount;
  65.     PutMsg(as->port, (MSG *)am);
  66. }
  67.  
  68. int
  69. CheckAsyncOp(_as, n)
  70. void *_as;
  71. long n;
  72. {
  73.     ASYHAN *as = (ASYHAN *)_as;
  74.     if (n > as->acount)
  75.     n = as->acount;
  76.     return(n <= as->ccount);
  77. }
  78.  
  79. /*
  80.  *  acount = #messages sent
  81.  *  ccount = #messages replied
  82.  */
  83.  
  84. void
  85. WaitAsyncOp(_as, n)
  86. void *_as;
  87. long n;
  88. {
  89.     ASYHAN *as = (ASYHAN *)_as;
  90.     if (n > as->acount)
  91.     n = as->acount;
  92.     while (n > as->ccount)
  93.     Wait(1 << as->rport->mp_SigBit);
  94.     Forbid();
  95.     as->ccount -= n;
  96.     Permit();
  97.     as->acount -= n;
  98. }
  99.  
  100. void
  101. CloseAsyncOp(_as)
  102. void *_as;
  103. {
  104.     ASYHAN *as = (ASYHAN *)_as;
  105.     ASYMSG EndMsg;
  106.     ASYMSG *am;
  107.  
  108.     WaitAsyncOp(as, -1);                /*  Wait for all operations to complete */
  109.     while (am = (ASYMSG *)GetMsg(as->rport))      /*  Free any messages   */
  110.     FreeMem(am, sizeof(ASYMSG));
  111.     EndMsg.func = NULL;
  112.     EndMsg.msg.mn_ReplyPort = as->rport;
  113.     PutMsg(as->port, (MSG *)&EndMsg);
  114.     WaitPort(as->rport);
  115.     (void)GetMsg(as->rport);
  116.     DeletePort(as->rport);
  117.     FreeMem(as, sizeof(*as));
  118. }
  119.  
  120. static
  121. void
  122. asyhandler()
  123. {
  124.     register ASYHAN *as;
  125.     register ASYMSG *am;
  126.  
  127.     Wait(SIGBREAKF_CTRL_F);
  128.     as = (ASYHAN *)FindTask(NULL)->tc_UserData;
  129.     as->port = CreatePort(NULL, 0);
  130.     Signal(as->rport->mp_SigTask, 1 << as->rport->mp_SigBit);
  131.     for (;;) {
  132.     WaitPort(as->port);
  133.     am = (ASYMSG *)GetMsg(as->port);
  134.     if (!am->func)
  135.         break;
  136.     CallAMFunc(&as->a4, &am->func);
  137.     ++as->ccount;
  138.     ReplyMsg((MSG *)am);
  139.     }
  140.     DeletePort(as->port);
  141.     as->port = NULL;
  142.     Forbid();
  143.     ReplyMsg((MSG *)am);
  144. }
  145.  
  146.  
  147.