home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * ASYNCOP.C
- */
-
- #include <local/typedefs.h>
-
- #define ASYMSG struct _ASYMSG
- #define ASYHAN struct _ASYHAN
-
- ASYMSG {
- MSG msg;
- void (*func)();
- long arg1;
- long arg2;
- long arg3;
- };
-
- ASYHAN {
- PORT *rport; /* Reply Port */
- PORT *port; /* Send Port */
- long acount; /* Messages Sent */
- long ccount; /* Messages Replied*/
- long a4,a5; /* A4 and A5 */
- };
-
- static void asyhandler();
-
- void *
- NewAsyncOp()
- {
- register TASK *task;
- register TASK *mytask = FindTask(NULL);
- register ASYHAN *as = AllocMem(sizeof(ASYHAN), MEMF_CLEAR|MEMF_PUBLIC);
-
- as->rport = CreatePort(NULL, 0);
- PutA4A5(&as->a4);
- task = CreateTask("async.task", (ubyte)(mytask->tc_Node.ln_Pri + 1), (APTR)asyhandler, 4096);
- task->tc_UserData = (APTR)as;
-
- Signal(task, SIGBREAKF_CTRL_F);
- Wait(1 << as->rport->mp_SigBit);
-
- return((void *)as);
- }
-
- void
- StartAsyncOp(_as, func, arg1, arg2, arg3)
- void *_as;
- void (*func)();
- int arg1, arg2, arg3;
- {
- ASYHAN *as = (ASYHAN *)_as;
- ASYMSG *am = (ASYMSG *)GetMsg(as->rport); /* Free Msg List */
-
- if (!am) {
- am = AllocMem(sizeof(ASYMSG), MEMF_PUBLIC|MEMF_CLEAR);
- am->msg.mn_ReplyPort = as->rport;
- }
- am->func = func;
- am->arg1 = arg1;
- am->arg2 = arg2;
- am->arg3 = arg3;
- ++as->acount;
- PutMsg(as->port, (MSG *)am);
- }
-
- int
- CheckAsyncOp(_as, n)
- void *_as;
- long n;
- {
- ASYHAN *as = (ASYHAN *)_as;
- if (n > as->acount)
- n = as->acount;
- return(n <= as->ccount);
- }
-
- /*
- * acount = #messages sent
- * ccount = #messages replied
- */
-
- void
- WaitAsyncOp(_as, n)
- void *_as;
- long n;
- {
- ASYHAN *as = (ASYHAN *)_as;
- if (n > as->acount)
- n = as->acount;
- while (n > as->ccount)
- Wait(1 << as->rport->mp_SigBit);
- Forbid();
- as->ccount -= n;
- Permit();
- as->acount -= n;
- }
-
- void
- CloseAsyncOp(_as)
- void *_as;
- {
- ASYHAN *as = (ASYHAN *)_as;
- ASYMSG EndMsg;
- ASYMSG *am;
-
- WaitAsyncOp(as, -1); /* Wait for all operations to complete */
- while (am = (ASYMSG *)GetMsg(as->rport)) /* Free any messages */
- FreeMem(am, sizeof(ASYMSG));
- EndMsg.func = NULL;
- EndMsg.msg.mn_ReplyPort = as->rport;
- PutMsg(as->port, (MSG *)&EndMsg);
- WaitPort(as->rport);
- (void)GetMsg(as->rport);
- DeletePort(as->rport);
- FreeMem(as, sizeof(*as));
- }
-
- static
- void
- asyhandler()
- {
- register ASYHAN *as;
- register ASYMSG *am;
-
- Wait(SIGBREAKF_CTRL_F);
- as = (ASYHAN *)FindTask(NULL)->tc_UserData;
- as->port = CreatePort(NULL, 0);
- Signal(as->rport->mp_SigTask, 1 << as->rport->mp_SigBit);
- for (;;) {
- WaitPort(as->port);
- am = (ASYMSG *)GetMsg(as->port);
- if (!am->func)
- break;
- CallAMFunc(&as->a4, &am->func);
- ++as->ccount;
- ReplyMsg((MSG *)am);
- }
- DeletePort(as->port);
- as->port = NULL;
- Forbid();
- ReplyMsg((MSG *)am);
- }
-
-
-