Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

7
Task/Events/00-META.yaml Normal file
View file

@ -0,0 +1,7 @@
---
category:
- Encyclopedia
from: http://rosettacode.org/wiki/Events
note: Concurrency
requires:
- Concurrency

24
Task/Events/00-TASK.txt Normal file
View file

@ -0,0 +1,24 @@
'''Event''' is a synchronization object. An event has two states ''signaled'' and ''reset''. A [[task]] may await for the event to enter the desired state, usually the ''signaled'' state. It is released once the state is entered. Releasing waiting tasks is called ''event notification''. Programmatically controlled events can be set by a [[task]] into one of its states.
In [[concurrent programming]] event also refers to a notification that some state has been reached through an asynchronous activity. The source of the event can be:
* ''internal'', from another [[task]], programmatically;
* ''external'', from the hardware, such as user input, timer, etc. Signaling an event from the hardware is accomplished by means of hardware [[interrupts]].
Event is a low-level synchronization mechanism. It neither identify the state that caused it signaled, nor the source of, nor who is the subject of notification. Events augmented by data and/or publisher-subscriber schemes are often referred as '''messages''', '''signals''' etc.
In the context of general programming '''event-driven architecture''' refers to a design that deploy events in order to synchronize [[task]]s with the asynchronous activities they must be aware of. The opposite approach is '''polling''' sometimes called '''busy waiting''', when the synchronization is achieved by an explicit periodic querying the state of the activity. As the name suggests busy waiting consumes system resources even when the external activity does not change its state.
Event-driven architectures are widely used in GUI design and SCADA systems. They are flexible and have relatively short response times. At the same time event-driven architectures suffer to the problems related to their unpredictability. They face [[race condition]], deadlocking, live locks and priority inversion. For this reason [[real-time computing|real-time]] systems tend to polling schemes, trading performance for predictability in the worst case scenario.
=Variants of events=
==Manual-reset event==
This event changes its state by an explicit request of a [[task]]. I.e. once signaled it remains in this state until it will be explicitly reset.
==Pulse event==
A pulse event when signaled releases all [[task]]s awaiting it and then is automatically reset.
=Sample implementations / APIs=
Show how a manual-reset event can be implemented in the language or else use an API to a library that provides events. Write a program that waits 1s and then signals the event to a [[task]] waiting for the event.

View file

@ -0,0 +1,7 @@
protected type Event is
procedure Signal;
procedure Reset;
entry Wait;
private
Fired : Boolean := False;
end Event;

View file

@ -0,0 +1,14 @@
protected body Event is
procedure Signal is
begin
Fired := True;
end Signal;
procedure Reset is
begin
Fired := False;
end Reset;
entry Wait when Fired is
begin
null;
end Wait;
end Event;

View file

@ -0,0 +1,18 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Events is
-- Place the event implementation here
X : Event;
task A;
task body A is
begin
Put_Line ("A is waiting for X");
X.Wait;
Put_Line ("A received X");
end A;
begin
delay 1.0;
Put_Line ("Signal X");
X.Signal;
end Test_Events;

View file

@ -0,0 +1,11 @@
SetTimer, internal, 1000
Return
internal: ; fire on a timer
TrayTip, internal, internal event!`npress F2 for external event
SetTimer, internal, off
Return
F2:: ; external event: fire on F2 key press
TrayTip, external, f2 key pressed
Return

View file

@ -0,0 +1,3 @@
subroutine Timer1_Timer()
print hour; ":"; minute; ":"; second
end subroutine

View file

@ -0,0 +1,17 @@
INSTALL @lib$+"TIMERLIB"
WAIT_TIMEOUT = 258
SYS "CreateEvent", 0, 1, 0, 0 TO hEvent%
timerID% = FN_ontimer(1000, PROCelapsed, 0)
PRINT "Waiting for event..."
REPEAT
SYS "WaitForSingleObject", hEvent%, 1 TO res%
UNTIL res% <> WAIT_TIMEOUT
PRINT "Event signalled"
END
DEF PROCelapsed
SYS "SetEvent", hEvent%
ENDPROC

View file

@ -0,0 +1,16 @@
INSTALL @lib$+"TIMERLIB"
Event% = FALSE
timerID% = FN_ontimer(1000, PROCelapsed, 0)
PRINT "Waiting for event..."
REPEAT
WAIT 0
UNTIL Event%
PRINT "Event signalled"
END
DEF PROCelapsed
Event% = TRUE
ENDPROC

View file

@ -0,0 +1,20 @@
using System;
using System.Timers;
class Program
{
static void Main()
{
var timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(OnElapsed);
Console.WriteLine(DateTime.Now);
timer.Start();
Console.ReadLine();
}
static void OnElapsed(object sender, ElapsedEventArgs eventArgs)
{
Console.WriteLine(eventArgs.SignalTime);
((Timer)sender).Stop();
}
}

19
Task/Events/C/events.c Normal file
View file

@ -0,0 +1,19 @@
#include <stdio.h>
#include <unistd.h>
int main()
{
int p[2];
pipe(p);
if (fork()) {
close(p[0]);
sleep(1);
write(p[1], p, 1);
wait(0);
} else {
close(p[1]);
read(p[0], p + 1, 1);
puts("received signal from pipe");
}
return 0;
}

View file

@ -0,0 +1,37 @@
(ns async-example.core
(:require [clojure.core.async :refer [>! <! >!! <!! go chan]])
(:require [clj-time.core :as time])
(:require [clj-time.format :as time-format])
(:gen-class))
;; Helper functions (logging & time stamp)
; Time stamp format
(def custom-formatter (time-format/formatter "yyyy:MM:dd:ss.SS"))
(defn safe-println [& more]
" This function avoids interleaving of text output when using println due to race condition for multi-processes printing
as discussed http://yellerapp.com/posts/2014-12-11-14-race-condition-in-clojure-println.html "
(.write *out* (str (clojure.string/join " " more) "\n")))
(defn log [s]
" Outputs mesage with time stamp "
(safe-println (time-format/unparse custom-formatter (time/now)) ":" s))
;; Main code
(defn -main [& args]
(let [c (chan)]
(log "Program start")
(go
(log "Task start")
(log (str "Event received by task: "(<! c))))
(<!!
(go
(log "program sleeping")
(Thread/sleep 1000) ; Wait 1 second
(log "Program signaling event")
(>! c "reset") ; Send message to task
))))
; Invoke -main function
(-main)

View file

@ -0,0 +1,54 @@
program Events;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Windows;
type
TWaitThread = class(TThread)
private
FEvent: THandle;
public
procedure Sync;
procedure Execute; override;
constructor Create(const aEvent: THandle); reintroduce;
end;
{ TWaitThread }
constructor TWaitThread.Create(const aEvent: THandle);
begin
inherited Create(False);
FEvent := aEvent;
end;
procedure TWaitThread.Execute;
var
res: Cardinal;
begin
res := WaitForSingleObject(FEvent, INFINITE);
if res = 0 then
Synchronize(Sync);
end;
procedure TWaitThread.Sync;
begin
Writeln(DateTimeToStr(Now));
end;
var
event: THandle;
begin
Writeln(DateTimeToStr(Now));
event := CreateEvent(nil, False, False, 'Event');
with TWaitThread.Create(event) do
try
Sleep(1000);
SetEvent(event)
finally
Free;
end;
Readln;
end.

24
Task/Events/E/events-1.e Normal file
View file

@ -0,0 +1,24 @@
def makeEvent() {
def [var fired, var firer] := Ref.promise()
def event {
to signal() {
firer.resolveRace(null) # all current and future wait()s will resolve
}
to reset() {
if (firer.isDone()) { # ignore multiple resets. If we didn't, then
# reset() wait() reset() signal() would never
# resolve that wait().
# create all fresh state
def [p, r] := Ref.promise()
fired := p
firer := r
}
}
to wait() {
return fired
}
}
return event
}

16
Task/Events/E/events-2.e Normal file
View file

@ -0,0 +1,16 @@
def e := makeEvent()
{
when (e.wait()) -> {
println("[2] Received event.")
}
println("[2] Waiting for event...")
}
{
timer.whenPast(timer.now() + 1000, def _() {
println("[1] Signaling event.")
e.signal()
})
println("[1] Waiting 1 second...")
}

View file

@ -0,0 +1,28 @@
defmodule Events do
def log(msg) do
time = Time.utc_now |> to_string |> String.slice(0..7)
IO.puts "#{time} => #{msg}"
end
def task do
log("Task start")
receive do
:go -> :ok
end
log("Task resumed")
end
def main do
log("Program start")
{pid,ref} = spawn_monitor(__MODULE__,:task,[])
log("Program sleeping")
Process.sleep(1000)
log("Program signalling event")
send(pid, :go)
receive do
{:DOWN,^ref,_,_,_} -> :task_is_down
end
end
end
Events.main

View file

@ -0,0 +1,22 @@
-module(events).
-compile(export_all).
log(Msg) ->
{H,M,S} = erlang:time(),
io:fwrite("~2.B:~2.B:~2.B => ~s~n",[H,M,S,Msg]).
task() ->
log("Task start"),
receive
go -> ok
end,
log("Task resumed").
main() ->
log("Program start"),
P = spawn(?MODULE,task,[]),
log("Program sleeping"),
timer:sleep(1000),
log("Program signalling event"),
P ! go,
timer:sleep(100).

View file

@ -0,0 +1,7 @@
66> events:main().
0: 0:57 => Program start
0: 0:57 => Program sleeping
0: 0:57 => Task start
0: 0:58 => Program signalling event
0: 0:58 => Task resumed
ok

View file

@ -0,0 +1,15 @@
open System
open System.Timers
let onElapsed (sender : obj) (eventArgs : ElapsedEventArgs) =
printfn "%A" eventArgs.SignalTime
(sender :?> Timer).Stop()
[<EntryPoint>]
let main argv =
let timer = new Timer(1000.)
timer.Elapsed.AddHandler(new ElapsedEventHandler(onElapsed))
printfn "%A" DateTime.Now
timer.Start()
ignore <| Console.ReadLine()
0

View file

@ -0,0 +1,3 @@
Sub Timer1_Timer()
Print Time
End Sub

View file

@ -0,0 +1,5 @@
Public Sub Timer1_Timer()
Print Str(Time(Now))
End

23
Task/Events/Go/events.go Normal file
View file

@ -0,0 +1,23 @@
package main
import (
"log"
"os"
"time"
)
func main() {
l := log.New(os.Stdout, "", log.Ltime | log.Lmicroseconds)
l.Println("program start")
event := make(chan int)
go func() {
l.Println("task start")
<-event
l.Println("event reset by task")
}()
l.Println("program sleeping")
time.Sleep(1 * time.Second)
l.Println("program signaling event")
event <- 0
time.Sleep(100 * time.Millisecond)
}

View file

@ -0,0 +1,11 @@
import Control.Concurrent (threadDelay, forkIO)
import Control.Concurrent.SampleVar
-- An Event is defined as a SampleVar with no data.
-- http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-SampleVar.html
newtype Event = Event (SampleVar ())
newEvent = fmap Event (newEmptySampleVar)
signalEvent (Event sv) = writeSampleVar sv ()
resetEvent (Event sv) = emptySampleVar sv
waitEvent (Event sv) = readSampleVar sv

View file

@ -0,0 +1,11 @@
main = do e <- newEvent
forkIO (waitTask e)
putStrLn "[1] Waiting 1 second..."
threadDelay 1000000 {- µs -}
putStrLn "[1] Signaling event."
signalEvent e
threadDelay 1000000 {- µs -} -- defer program exit for reception
waitTask e = do putStrLn "[2] Waiting for event..."
waitEvent e
putStrLn "[2] Received event."

View file

@ -0,0 +1,20 @@
record Event(cond, value)
procedure main()
event := Event(condvar())
t1 := thread {
write("Task one waiting for event....")
critical event.cond: while /(event.value) do wait(event.cond)
write("Task one received event.")
}
t2 := thread {
write("Task two waiting for event....")
critical event.cond: while /(event.value) do wait(event.cond)
write("Task two received event.")
}
delay(1000) # Let main thread post the event.
event.value := "yes"
write("Signalling event.")
signal(event.cond,0)
every wait(t1|t2)
end

View file

@ -0,0 +1,10 @@
YUI().use('event-custom', function(Y) {
// add a custom event:
Y.on('my:event', function () {
alert("Event fired");
});
// fire the event after one second:
setTimeout(function () {
Y.fire('my:event');
}, 1000);
});

View file

@ -0,0 +1,10 @@
YUI().use('node-event-simulate', function(Y) {
// add a click event handler to a DOM node with id "button":
Y.one("#button").on("click", function (e) {
alert("Button clicked");
});
// simulate the click after one second:
setTimeout(function () {
Y.one("#button").simulate("click");
}, 1000);
});

View file

@ -0,0 +1,20 @@
function dolongcomputation(cond)
det(rand(4000, 4000))
Base.notify(cond)
end
function printnotice(cond)
Base.wait(cond)
println("They are finished.")
end
function delegate()
println("Starting task, sleeping...")
condition = Base.Condition()
Base.@async(printnotice(condition))
Base.@async(dolongcomputation(condition))
end
delegate()
sleep(5)
println("Done sleeping.")

View file

@ -0,0 +1,19 @@
(defun log (msg)
(let ((`#(,h ,m ,s) (erlang:time)))
(lfe_io:format "~2.B:~2.B:~2.B => ~s~n" `(,h ,m ,s ,msg))))
(defun task ()
(log "Task start")
(receive
('go 'ok))
(log "Task resumed"))
(defun run ()
(log "Program start")
(let ((pid (spawn (lambda () (task)))))
(progn
(log "Program sleeping")
(timer:sleep 1000)
(log "Program signalling event")
(! pid 'go)
(timer:sleep 100))))

View file

@ -0,0 +1,9 @@
-- the current window was closed
on closeWindow
...
end
-- the left mouse button was pressed by the user
on mouseDown
...
end

View file

@ -0,0 +1,8 @@
-- send event #mouseDown programmatically to sprite 1
sendSprite(1, #mouseDown)
-- send custom event #foo to named sprite "bar"
sendSprite("bar", #foo)
-- send custom event #fooBar to all existing sprites
sendAllSprites(#fooBar)

View file

@ -0,0 +1,15 @@
mx = xtra("Msg").new()
-- send message WM_LBUTTONDOWN to a specific window identified by HWND hwnd
WM_LBUTTONDOWN = 513
MK_LBUTTON = 1
lParam = 65536*y + x
mx.send_msg (hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam)
-- listen for WM_COPYDATA and WM_MOUSEWHEEL messages sent to current application
-- window, notify Lingo callback function 'msgReceived' when such messages occur.
-- This callback function will receive hwnd, message, wParam and lParam as arguments
-- (and for WM_COPYDATA messages also the data that was sent as ByteArray).
WM_COPYDATA = 74
WM_MOUSEWHEEL = 522
mx.msg_listen([WM_COPYDATA, WM_MOUSEWHEEL], VOID, #msgReceived)

View file

@ -0,0 +1,2 @@
Print["Will exit in 4 seconds"]; Pause[4]; Quit[]
->Will exit in 4 seconds

View file

@ -0,0 +1,14 @@
import posix
var p: array[2, cint]
discard pipe p
if fork() > 0:
discard close p[0]
discard sleep 1
discard p[1].write(addr p[0], 1)
var x: cint = 0
discard wait (addr x)
else:
discard close p[1]
discard p[0].read(addr p[1], 1)
echo "received signal from pipe"

View file

@ -0,0 +1,30 @@
import locks
from os import sleep
import times
from strformat import fmt
var
# condition variable which shared across threads
cond: Cond
lock: Lock
threadproc: Thread[void]
proc waiting {.thread.} =
echo "spawned waiting proc"
let start = getTime()
cond.wait lock
echo fmt"thread ended after waiting {getTime() - start}."
proc main =
initCond cond
initLock lock
threadproc.createThread waiting
echo "in main proc"
os.sleep 1000
echo "send signal/event notification"
signal cond
joinThread threadproc
deinitCond cond
deinitLock lock
main()

View file

@ -0,0 +1,6 @@
: anEvent
| ch |
Channel new ->ch
#[ ch receive "Ok, event is signaled !" println ] &
System sleep(1000)
ch send($myEvent) ;

View file

@ -0,0 +1,11 @@
import: emitter
: anEvent2
| e i |
Emitter new(null) ->e
e onEvent($myEvent, #[ "Event is signaled !" println ])
10 loop: i [
1000 System sleep
$myEvent e emit
]
e close ;

View file

@ -0,0 +1,29 @@
declare
fun {NewEvent}
{NewCell _}
end
proc {SignalEvent Event}
@Event = unit
end
proc {ResetEvent Event}
Event := _
end
proc {WaitEvent Event}
{Wait @Event}
end
E = {NewEvent}
in
thread
{System.showInfo "[2] Waiting for event..."}
{WaitEvent E}
{System.showInfo "[2] Received event."}
end
{System.showInfo "[1] Waiting 1 second..."}
{Delay 1000}
{System.showInfo "[1] Signaling event."}
{SignalEvent E}

View file

@ -0,0 +1,13 @@
declare
E
in
thread
{System.showInfo "[2] Waiting for event..."}
{Wait E}
{System.showInfo "[2] Received event."}
end
{System.showInfo "[1] Waiting 1 second..."}
{Delay 1000}
{System.showInfo "[1] Signaling event."}
E = unit

View file

@ -0,0 +1,20 @@
declare
MyPort
in
thread
MyStream
in
{NewPort ?MyStream ?MyPort}
{System.showInfo "[2] Waiting for event..."}
for Event in MyStream do
{System.showInfo "[2] Received event."}
{System.showInfo "[2] Waiting for event again..."}
end
end
for do
{System.showInfo "[1] Waiting 1 second..."}
{Delay 1000}
{System.showInfo "[1] Signaling event."}
{Port.send MyPort unit}
end

View file

@ -0,0 +1,31 @@
use AnyEvent;
# a new condition with a callback:
my $quit = AnyEvent->condvar(
cb => sub {
warn "Bye!\n";
}
);
# a new timer, starts after 2s and repeats every 0.25s:
my $counter = 1;
my $hi = AnyEvent->timer(
after => 2,
interval => 0.25,
cb => sub {
warn "Hi!\n";
# flag the condition as ready after 4 times:
$quit->send if ++$counter > 4;
}
);
# another timer, runs the callback once after 1s:
my $hello = AnyEvent->timer(
after => 1,
cb => sub {
warn "Hello world!\n";
}
);
# wait for the $quit condition to be ready:
$quit->recv();

View file

@ -0,0 +1,15 @@
use AnyEvent;
my $quit = AE::cv sub { warn "Bye!\n" };
my $counter = 1;
my $hi = AE::timer 2, 0.25, sub {
warn "Hi!\n";
$quit->send if ++$counter > 4;
};
my $hello = AE::timer 1, 0, sub {
warn "Hello world!\n";
};
$quit->recv;

View file

@ -0,0 +1,32 @@
(notonline)-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">lock</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">init_cs</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">timedate</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">format_timedate</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">date</span><span style="color: #0000FF;">(),</span><span style="color: #008000;">" h:m:s\n"</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">echo</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- see note</span>
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">enter_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">threads</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">create_thread</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"echo"</span><span style="color: #0000FF;">),{</span><span style="color: #008000;">"job1"</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">create_thread</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"echo"</span><span style="color: #0000FF;">),{</span><span style="color: #008000;">"job2"</span><span style="color: #0000FF;">})}</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"main"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"free"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">showtime</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">leave_cs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lock</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">wait_thread</span><span style="color: #0000FF;">(</span><span style="color: #000000;">threads</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"done\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--

View file

@ -0,0 +1,19 @@
-->
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">1000</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_F5</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">iteration</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #7060A8;">IupSetInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (restart timer)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"K_ANY"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<!--

View file

@ -0,0 +1,3 @@
(alarm 1
(prinl "Exit in 4 seconds")
(alarm 4 (bye)) )

View file

@ -0,0 +1,16 @@
$timer = New-Object -TypeName System.Timers.Timer -Property @{Enabled=$true; Interval=1000; AutoReset=$true}
$action = {
$global:counter += 1
Write-Host “Event counter is ${counter}: $((Get-Date).ToString("hh:mm:ss"))”
if ($counter -ge $event.MessageData)
{
Write-Host “Timer stopped”
$timer.Stop()
}
}
$job = Register-ObjectEvent -InputObject $timer -MessageData 5 -SourceIdentifier Count -EventName Elapsed -Action $action
$global:counter = 0
& $job.Module {$global:counter}

View file

@ -0,0 +1,12 @@
OpenWindow (0, 10, 10, 150, 40, "Event Demo")
ButtonGadget (1, 10, 10, 35, 20, "Quit")
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget And EventGadget() = 1
End
EndIf
ForEver

View file

@ -0,0 +1,20 @@
import threading
import time
def wait_for_event(event):
event.wait()
print("Thread: Got event")
e = threading.Event()
t = threading.Thread(target=wait_for_event, args=(e,))
t.start()
print("Main: Waiting one second")
time.sleep(1.0)
print("Main: Setting event")
e.set()
time.sleep(1.0)
print("Main: Done")
t.join()

View file

@ -0,0 +1,18 @@
/*REXX program demonstrates a method of handling events (this is a time─driven pgm).*/
signal on halt /*allow user to HALT (Break) the pgm.*/
parse arg timeEvent /*allow the "event" to be specified. */
if timeEvent='' then timeEvent= 5 /*Not specified? Then use the default.*/
event?: do forever /*determine if an event has occurred. */
theEvent= right(time(), 1) /*maybe it's an event, ─or─ maybe not.*/
if pos(theEvent, timeEvent)>0 then signal happening
end /*forever*/
say 'Control should never get here!' /*This is a logic can─never─happen ! */
halt: say ' program halted.'; exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
happening: say 'an event occurred at' time()", the event is:" theEvent
do while theEvent==right(time(), 1) /*spin until a tic (a second) changes. */
nop /*replace NOP with the "process" code.*/
end /*while*/ /*NOP is a REXX statement, does nothing*/
signal event? /*see if another event has happened. */

View file

@ -0,0 +1,8 @@
#lang racket
(define task (thread (lambda () (printf "Got: ~s\n" (thread-receive)))))
(thread-send task ; wait for it, then send it
(sync (alarm-evt (+ 1000 (current-inexact-milliseconds)))))
(void (sync task)) ; wait for the task to be done before exiting

View file

@ -0,0 +1,14 @@
note now, " program start";
my $event = Channel.new;
my $todo = start {
note now, " task start";
$event.receive;
note now, " event reset by task";
}
note now, " program sleeping";
sleep 1;
note now, " program signaling event";
$event.send(0);
await $todo;

View file

@ -0,0 +1,17 @@
use std::{sync::mpsc, thread, time::Duration};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("[1] Starting");
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
println!("[2] Waiting for event");
rx.recv();
println!("[2] Received event");
});
thread::sleep(Duration::from_secs(1));
println!("[1] Sending event");
tx.send(())?;
thread::sleep(Duration::from_secs(1));
Ok(())
}

View file

@ -0,0 +1,54 @@
# Simple task framework built from coroutines
proc pause ms {
after $ms [info coroutine];yield
}
proc task {name script} {
coroutine $name apply [list {} \
"set ::tasks(\[info coro]) 1;$script;unset ::tasks(\[info coro])"]
}
proc waitForTasksToFinish {} {
global tasks
while {[array size tasks]} {
vwait tasks
}
}
# Make an Ada-like event class
oo::class create Event {
variable waiting fired
constructor {} {
set waiting {}
set fired 0
}
method wait {} {
while {!$fired} {
lappend waiting [info coroutine]
yield
}
}
method signal {} {
set wake $waiting
set waiting {}
set fired 1
foreach task $wake {
$task
}
}
method reset {} {
set fired 0
}
}
# Execute the example
Event create X
task A {
puts "waiting for event"
X wait
puts "received event"
}
task B {
pause 1000
puts "signalling X"
X signal
}
waitForTasksToFinish

View file

@ -0,0 +1,4 @@
after 1000 set X signalled
puts "waiting for event"
vwait X
puts "received event"

View file

@ -0,0 +1,17 @@
import "scheduler" for Scheduler
import "timer" for Timer
var a = 3
// add a task
Scheduler.add {
a = a * a
}
// add another task
Scheduler.add {
a = a + 1
}
System.print(a) // still 3
Timer.sleep(3000) // wait 3 seconds
System.print(a) // now 3 * 3 + 1 = 10

View file

@ -0,0 +1,3 @@
sub Timer1_Timer()
print Time$
end sub

View file

@ -0,0 +1,6 @@
var event=Atomic.Bool(); // False
// create thread waiting for event
fcn(event){event.wait(); println(vm," ping!")}.launch(event);
Atomic.sleep(1);
event.set();
println("done")