#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "../ppport.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static
IV
WaitForMultiple(AV* hArray,
BOOL
fWaitAll,
DWORD
dwTimeOut)
{
dTHX;
int
count;
SV ** svpp;
HANDLE
handle;
HANDLE
* aHandles;
int
i=0;
DWORD
result;
count = av_len(hArray) + 1;
if
(count == 0) {
warn(
"No objects to wait for"
);
return
IV_MAX;
}
New(0,aHandles,count,
HANDLE
);
for
(i = 0; i < count; i++) {
svpp = av_fetch(hArray, i, 0);
if
(!svpp) {
invalid:
croak(
"Invalid object passed ($objects[%d])"
,i);
return
IV_MAX;
}
else
if
(sv_derived_from(*svpp,
"Win32::IPC"
)) {
handle = INT2PTR(
HANDLE
, SvIV(SvRV(*svpp)));
}
else
if
(sv_isobject(*svpp)) {
dSP;
handle = INVALID_HANDLE_VALUE;
ENTER;
SAVETMPS;
PUSHMARK(sp);
XPUSHs(*svpp);
PUTBACK;
result = call_method(
"get_Win32_IPC_HANDLE"
, G_SCALAR|G_EVAL);
SPAGAIN;
if
((result == 1) && (SvIOKp(TOPs))) handle = INT2PTR(
HANDLE
, POPi);
PUTBACK;
FREETMPS;
LEAVE;
if
(SvTRUE(ERRSV))
goto
unknown;
}
else
{
unknown:
croak(
"Don't know how to wait on $objects[%d]"
,i);
return
IV_MAX;
}
if
(handle == INVALID_HANDLE_VALUE)
goto
invalid;
aHandles[i] = handle;
}
result = WaitForMultipleObjects(count, aHandles, fWaitAll, dwTimeOut);
Safefree(aHandles);
if
((result >= WAIT_OBJECT_0) && (result < WAIT_OBJECT_0 + count))
return
result - WAIT_OBJECT_0 + 1;
if
((result >= WAIT_ABANDONED_0) && (result < WAIT_ABANDONED_0 + count))
return
-(IV)(result - WAIT_ABANDONED_0 + 1);
if
(result == WAIT_TIMEOUT)
return
0;
return
IV_MAX;
}
static
DWORD
constant(
char
* name)
{
errno
= 0;
if
(strEQ(name,
"INFINITE"
))
return
INFINITE;
errno
= EINVAL;
return
0;
}
MODULE = Win32::IPC PACKAGE = Win32::IPC
PROTOTYPES: ENABLE
DWORD
constant(name)
char
* name
IV
wait_any(objects,timeout=INFINITE)
SV * objects
DWORD
timeout
ALIAS:
wait_all = 1
PROTOTYPE: \@;$
PREINIT:
AV * av;
CODE:
if
(!(SvROK(objects)
&& (av = (AV*)SvRV(objects))
&& SvTYPE(av) == SVt_PVAV))
croak(
"First arg must be an array"
);
RETVAL = WaitForMultiple(av, ix, timeout);
if
(RETVAL == IV_MAX)
XSRETURN_UNDEF;
OUTPUT:
RETVAL
IV
wait(handle, timeout=INFINITE)
HANDLE
handle
DWORD
timeout
PREINIT:
DWORD
result;
CODE:
result = WaitForSingleObject(handle,timeout);
if
(result == WAIT_OBJECT_0)
RETVAL = 1;
else
if
(result == WAIT_ABANDONED_0)
RETVAL = -1;
else
if
(result == WAIT_TIMEOUT)
RETVAL = 0;
else
XSRETURN_UNDEF;
OUTPUT:
RETVAL
DWORD
Wait(handle, timeout)
HANDLE
handle
DWORD
timeout
CODE:
RETVAL = WaitForSingleObject(handle,timeout);
OUTPUT:
RETVAL