1239310Sdim#include "EXTERN.h"
2239310Sdim#include "perl.h"
3239310Sdim#include "XSUB.h"
4239310Sdim
5239310Sdim#undef __USE_INLINE__
6239310Sdim#include <exec/types.h>
7239310Sdim#include <utility/tagitem.h>
8239310Sdim#include <dos/dos.h>
9239310Sdim#include <proto/exec.h>
10239310Sdim#include <proto/intuition.h>
11239310Sdim#include <proto/utility.h>
12239310Sdim
13239310Sdim
14239310Sdim
15239310Sdimstruct TimeRequest *
16239310SdimOpenTimer(void)
17239310Sdim{
18239310Sdim	struct MsgPort *port = IExec->AllocSysObjectTags(ASOT_PORT, TAG_END);
19239310Sdim	if (port == NULL)
20239310Sdim	{
21280031Sdim		return NULL;
22239310Sdim	}
23239310Sdim
24239310Sdim	struct TimeRequest *req = IExec->AllocSysObjectTags(ASOT_IOREQUEST,
25276479Sdim		ASOIOR_Size, sizeof(struct TimeRequest),
26276479Sdim		ASOIOR_ReplyPort, port,
27276479Sdim		TAG_END);
28261991Sdim
29261991Sdim	if (req == NULL)
30261991Sdim	{
31288943Sdim		IExec->FreeSysObject(ASOT_PORT, port);
32239310Sdim		return NULL;
33249423Sdim	}
34249423Sdim
35249423Sdim	int8 deverr = IExec->OpenDevice("timer.device", UNIT_MICROHZ,
36261991Sdim		&req->Request, 0);
37261991Sdim
38261991Sdim	if (deverr != IOERR_SUCCESS)
39261991Sdim	{
40296417Sdim		IExec->FreeSysObject(ASOT_IOREQUEST, req);
41296417Sdim		IExec->FreeSysObject(ASOT_PORT, port);
42261991Sdim		return NULL;
43296417Sdim	}
44296417Sdim
45296417Sdim	return req;
46296417Sdim}
47296417Sdim
48296417Sdim
49296417Sdimvoid
50296417SdimCloseTimer(struct TimeRequest *req)
51296417Sdim{
52296417Sdim	if (req != NULL)
53296417Sdim	{
54296417Sdim		struct MsgPort *port = req->Request.io_Message.mn_ReplyPort;
55296417Sdim
56296417Sdim		IExec->CloseDevice(&req->Request);
57296417Sdim		IExec->FreeSysObject(ASOT_IOREQUEST, req);
58296417Sdim		IExec->FreeSysObject(ASOT_PORT, port);
59296417Sdim	}
60296417Sdim}
61261991Sdim
62239310Sdim
63296417Sdim
64296417Sdimuint32 WaitTimeout(uint32 signalmask , int timeout)
65239310Sdim{
66239310Sdim
67249423Sdim	struct TimeRequest *req = NULL;
68239310Sdim	uint32 timermask        = 0;
69239310Sdim
70239310Sdim	if (timeout > 0)
71239310Sdim	{
72249423Sdim		req = OpenTimer();
73249423Sdim
74239310Sdim		if (req != NULL)
75239310Sdim		{
76239310Sdim			timermask = 1L << req->Request.io_Message.mn_ReplyPort->mp_SigBit;
77239310Sdim
78239310Sdim			req->Request.io_Command = TR_ADDREQUEST;
79239310Sdim			req->Time.Seconds       = 0;
80239310Sdim			req->Time.Microseconds  = timeout;
81239310Sdim
82239310Sdim			IExec->SendIO(&req->Request);
83239310Sdim		}
84239310Sdim	}
85239310Sdim
86239310Sdim	uint32 waitmask = timermask |  signalmask | SIGBREAKF_CTRL_C;
87239310Sdim
88239310Sdim	uint32 sigmask = IExec->Wait(waitmask);
89239310Sdim
90239310Sdim	if (req != NULL)
91239310Sdim	{
92239310Sdim		IExec->AbortIO(&req->Request);
93249423Sdim		IExec->WaitIO(&req->Request);
94249423Sdim		CloseTimer(req);
95239310Sdim	}
96239310Sdim
97239310Sdim	/* remove the timer mask bit */
98239310Sdim
99239310Sdim	return sigmask & (~timermask );
100239310Sdim}
101239310Sdim
102239310Sdim
103239310Sdim
104249423SdimMODULE = Amiga::Exec              PACKAGE = Amiga::Exec
105249423Sdim
106239310SdimPROTOTYPES: DISABLE
107239310Sdim
108239310Sdim
109239310Sdimuint32 _Wait(signalmask,timeout)
110239310Sdim    uint32 signalmask;
111239310Sdim    uint32 timeout;
112239310Sdim    CODE:
113239310Sdim    	RETVAL = WaitTimeout(signalmask,timeout);
114239310Sdim    OUTPUT:
115239310Sdim    	RETVAL
116239310Sdim
117239310Sdim