xref: /openbsd/gnu/usr.bin/perl/ext/Amiga-Exec/Exec.xs (revision 771fbea0)
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 
5 #undef __USE_INLINE__
6 #include <exec/types.h>
7 #include <utility/tagitem.h>
8 #include <dos/dos.h>
9 #include <proto/exec.h>
10 #include <proto/intuition.h>
11 #include <proto/utility.h>
12 
13 
14 
15 struct TimeRequest *
16 OpenTimer(void)
17 {
18 	struct MsgPort *port = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
19 	if (port == NULL)
20 	{
21 		return NULL;
22 	}
23 
24 	struct TimeRequest *req = IExec->AllocSysObjectTags(ASOT_IOREQUEST,
25 		ASOIOR_Size, sizeof(struct TimeRequest),
26 		ASOIOR_ReplyPort, port,
27 		TAG_END);
28 
29 	if (req == NULL)
30 	{
31 		IExec->FreeSysObject(ASOT_PORT, port);
32 		return NULL;
33 	}
34 
35 	int8 deverr = IExec->OpenDevice("timer.device", UNIT_MICROHZ,
36 		&req->Request, 0);
37 
38 	if (deverr != IOERR_SUCCESS)
39 	{
40 		IExec->FreeSysObject(ASOT_IOREQUEST, req);
41 		IExec->FreeSysObject(ASOT_PORT, port);
42 		return NULL;
43 	}
44 
45 	return req;
46 }
47 
48 
49 void
50 CloseTimer(struct TimeRequest *req)
51 {
52 	if (req != NULL)
53 	{
54 		struct MsgPort *port = req->Request.io_Message.mn_ReplyPort;
55 
56 		IExec->CloseDevice(&req->Request);
57 		IExec->FreeSysObject(ASOT_IOREQUEST, req);
58 		IExec->FreeSysObject(ASOT_PORT, port);
59 	}
60 }
61 
62 
63 
64 uint32 WaitTimeout(uint32 signalmask , int timeout)
65 {
66 
67 	struct TimeRequest *req = NULL;
68 	uint32 timermask        = 0;
69 
70 	if (timeout > 0)
71 	{
72 		req = OpenTimer();
73 
74 		if (req != NULL)
75 		{
76 			timermask = 1L << req->Request.io_Message.mn_ReplyPort->mp_SigBit;
77 
78 			req->Request.io_Command = TR_ADDREQUEST;
79 			req->Time.Seconds       = 0;
80 			req->Time.Microseconds  = timeout;
81 
82 			IExec->SendIO(&req->Request);
83 		}
84 	}
85 
86 	uint32 waitmask = timermask |  signalmask | SIGBREAKF_CTRL_C;
87 
88 	uint32 sigmask = IExec->Wait(waitmask);
89 
90 	if (req != NULL)
91 	{
92 		IExec->AbortIO(&req->Request);
93 		IExec->WaitIO(&req->Request);
94 		CloseTimer(req);
95 	}
96 
97 	/* remove the timer mask bit */
98 
99 	return sigmask & (~timermask );
100 }
101 
102 
103 
104 MODULE = Amiga::Exec              PACKAGE = Amiga::Exec
105 
106 PROTOTYPES: DISABLE
107 
108 
109 uint32 _Wait(signalmask,timeout)
110     uint32 signalmask;
111     uint32 timeout;
112     CODE:
113     	RETVAL = WaitTimeout(signalmask,timeout);
114     OUTPUT:
115     	RETVAL
116 
117