From: Peter J. Holzer on
On 2010-02-23 20:49, Tad McClellan <tadmc(a)seesig.invalid> wrote:
> Dilbert <dilbert1999(a)gmail.com> wrote:
>> Is there an advanced sleep command for Windows that sleeps for 1
>> second *maximum* ?, i.e. if any key was hit during the sleep
>
>
> I don't think you understand the definition of "sleep" here...
>
> "sleep" means "do not do _anything_".
>
> Monitoring the keyboard is "something", so it cannot be done while sleeping.
>
> That is, if it could notice that something happened on the keyboard,
> then it was not truly sleeping.

If it could notice that time has passed, then it was not truly sleeping
;-)

"Sleeping" means that the process has told the OS to suspend it until a
given amount of time has passed or until the process needs to be resumed
(or terminated) for another reason.

There is in fact one Unix system call (and corresponding Perl builtin
function) which has exactly the semantics Dilbert wants:

select

It tells the OS:

Suspend me until IO is possible on one of these file descriptors
or until x seconds have passed, whichever happens earlier.

hp
From: Ben Morrow on

Quoth Dilbert <dilbert1999(a)gmail.com>:
> I have a perl program (under windows vista) that records every
> scancode / keystroke I make (it even records when I hit the Ctrl-key,
> the Shift-key, F1, F2, etc....
>
> So the program works ok for me, but it has a "do{...}until" loop that
> better should be replaced by a sleep command. My concern is that I
> waste a lot of CPU cycles in the do{...}until loop, that could be
> avoided if I replace that loop by a sleep command
>
> How can I achieve this ? does such a command exist under windows ?
> (just in case you might ask: I already tried each and every option in
> Term::Readkey, it definitely does not record when I hit the Ctrl-key,
> Shift-key, etc...) Fortunately, Win32::Console does the job quite
> well, it is just the do{...}until loop that bothers me because it
> wastes CPU cycles.
>
> Here is the program:
>
> use strict;
> use warnings;
>
> use Win32::Console;
>
> my $CONS_INP = Win32::Console->new(STD_INPUT_HANDLE);
>
> while (1) {
>
> # I want to sleep here until a key is pressed...
> # How can I achieve this under Windows... ???
>
> my @event;
> do {
> @event = $CONS_INP->Input() if $CONS_INP->GetEvents();
> } until @event;

AFAICT from the MSDN docs, ->Input should block until there is something
to read. That is, replace the whole do/until loop with

my @event = $CONS_INP->Input();

If I'm wrong, or if you need the process to wake up after a timeout even
without an event, you want wait_all from Win32::IPC.

Ben

From: Ben Morrow on

Quoth "Peter J. Holzer" <hjp-usenet2(a)hjp.at>:
> On 2010-02-23 20:49, Tad McClellan <tadmc(a)seesig.invalid> wrote:
> > Dilbert <dilbert1999(a)gmail.com> wrote:
> >> Is there an advanced sleep command for Windows that sleeps for 1
> >> second *maximum* ?, i.e. if any key was hit during the sleep
> >
> > I don't think you understand the definition of "sleep" here...
> >
> > "sleep" means "do not do _anything_".
> >
> > Monitoring the keyboard is "something", so it cannot be done while sleeping.
> >
> > That is, if it could notice that something happened on the keyboard,
> > then it was not truly sleeping.
>
> If it could notice that time has passed, then it was not truly sleeping
> ;-)
>
> "Sleeping" means that the process has told the OS to suspend it until a
> given amount of time has passed or until the process needs to be resumed
> (or terminated) for another reason.
>
> There is in fact one Unix system call (and corresponding Perl builtin
> function) which has exactly the semantics Dilbert wants:
>
> select

Unfortunately select doesn't generally work on Win32, since it doesn't
have a proper unified fd model. The perl builtin calls a version that
only works on sockets.

The native Win32 replacement for select(2) is WaitForMultipleObjects,
which will wait for any HANDLE. This is wrapped by the Win32::IPC
module.

Arguably perl's select on Win32 ought to use WFMO to provide semantics
more like Unix' select(2), but it doesn't.

Ben

From: sln on
On Tue, 23 Feb 2010 22:09:47 +0000, Ben Morrow <ben(a)morrow.me.uk> wrote:

>> do {
>> @event = $CONS_INP->Input() if $CONS_INP->GetEvents();
>> } until @event;
>
>AFAICT from the MSDN docs, ->Input should block until there is something
>to read. That is, replace the whole do/until loop with
>
> my @event = $CONS_INP->Input();
>
That could probably be tested with a print statement
and fingers on Ctrl-C.
do {
@event = $CONS_INP->Input() if $CONS_INP->GetEvents();
print ".";
} until @event;

I wouldn't know why if $CONS_INP->GetEvents() would be needed
unless he is managing his own queue, otherwise the perl thread
running this program would be blocked. And you can PeekMessage
I guess.

-sln
From: sln on
On Tue, 23 Feb 2010 22:24:53 +0000, Ben Morrow <ben(a)morrow.me.uk> wrote:

>
>Quoth "Peter J. Holzer" <hjp-usenet2(a)hjp.at>:
>> On 2010-02-23 20:49, Tad McClellan <tadmc(a)seesig.invalid> wrote:
>> > Dilbert <dilbert1999(a)gmail.com> wrote:
>> >> Is there an advanced sleep command for Windows that sleeps for 1
>> >> second *maximum* ?, i.e. if any key was hit during the sleep
>> >
>> > I don't think you understand the definition of "sleep" here...
>> >
>> > "sleep" means "do not do _anything_".
>> >
>> > Monitoring the keyboard is "something", so it cannot be done while sleeping.
>> >
>> > That is, if it could notice that something happened on the keyboard,
>> > then it was not truly sleeping.
>>
>> If it could notice that time has passed, then it was not truly sleeping
>> ;-)
>>
>> "Sleeping" means that the process has told the OS to suspend it until a
>> given amount of time has passed or until the process needs to be resumed
>> (or terminated) for another reason.
>>
>> There is in fact one Unix system call (and corresponding Perl builtin
>> function) which has exactly the semantics Dilbert wants:
>>
>> select
>
>Unfortunately select doesn't generally work on Win32, since it doesn't
>have a proper unified fd model. The perl builtin calls a version that
>only works on sockets.
>
>The native Win32 replacement for select(2) is WaitForMultipleObjects,
>which will wait for any HANDLE. This is wrapped by the Win32::IPC
>module.
>
>Arguably perl's select on Win32 ought to use WFMO to provide semantics
>more like Unix' select(2), but it doesn't.
>
>Ben

Probably in its simplest form all thats necessary is this:

#include <Windows.h>
#include <Winbase.h>
#include <Wincon.h>

HANDLE hStdin;
DWORD ret;

if (hStdin = GetStdHandle( STD_INPUT_HANDLE ))
{
while (1)
{
// Wait for state of a console input buffer handle to be signaled
ret = WaitForSingleObject( hStdin, INFINITE );
switch (ret)
{
// process low level buffer events
case WAIT_OBJECT_0:
if ( ReadConsoleInput( hStdin, ...) ) {
switch() {
...
}
}
else {
ExitError( "ReadConsole" );
}
break;

// Not waiting for timeouts
default:
ExitError( "WaitForSingleObject" );
break;
}
}
ExitError( "GetStdHandle" );

I'm sure Win32::IPC has the WFSO but can it get the
console handle via either CreateFile(..CONIN$..) or
GetStdHandle(STD_INPUT_HANDLE)? Then a module has to
do a low level input buffer read. Maybe thats what
the Win32::Console does and could do the async waiting
as well because I would think the module wouldn't just
be doing busy waiting (polling).

-sln