Does everyone still think that group watchers are a good idea? If so,
show me some demo scripts! ;-)
----- Forwarded message from [EMAIL PROTECTED] -----
Date: Mon, 7 Feb 2000 22:34:11 +0100
Subject: CPAN Upload: JPRIT/Event-0.65.tar.gz
From: [EMAIL PROTECTED]
To: [EMAIL PROTECTED],
[EMAIL PROTECTED]
The uploaded file
Event-0.65.tar.gz
has entered CPAN as
file: $CPAN/authors/id/JPRIT/Event-0.65.tar.gz
size: 64725 bytes
md5: 4eaeb58978f3379e4d404a3deaff49d4
No action is required on your part
Request entered by: JPRIT (Joshua N. Pritikin)
Request entered on: Mon, 07 Feb 2000 21:33:05 GMT
Request completed: Mon, 07 Feb 2000 21:34:11 GMT
Virtually Yours,
Id: paused,v 1.68 1999/10/22 14:39:12 k Exp k
----- End forwarded message -----
# This is a patch for Event-0.64 to update it to Event-0.65
#
# To apply this patch:
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'applypatch' program with this patch file as input.
#
# If you do not have 'applypatch', it is part of the 'makepatch' package
# that you can fetch from the Comprehensive Perl Archive Network:
# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
# In the above URL, 'x' should be 2 or higher.
#
# To apply this patch without the use of 'applypatch':
# STEP 1: Chdir to the source directory.
# If you have a decent Bourne-type shell:
# STEP 2: Run the shell with this file as input.
# If you don't have such a shell, you may need to manually create
# the files as shown below.
# STEP 3: Run the 'patch' program with this file as input.
#
# These are the commands needed to create/delete files/directories:
#
touch 'c/group.c'
chmod 0444 'c/group.c'
touch 'demo/group.t'
chmod 0444 'demo/group.t'
touch 'lib/Event/group.pm'
chmod 0444 'lib/Event/group.pm'
touch 't/fifo.t'
chmod 0444 't/fifo.t'
#
# This command terminates the shell and need not be executed manually.
exit
#
#### End of Preamble ####
#### Patch data follows ####
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/ChangeLog'
'/usr/tmp/mp4384.d/new/Event-0.65/ChangeLog'
Index: ./ChangeLog
--- ./ChangeLog Fri Feb 4 17:42:33 2000
+++ ./ChangeLog Mon Feb 7 16:21:58 2000
@@ -1,3 +1,16 @@
+2000-02-07 Joshua Pritikin <[EMAIL PROTECTED]>
+
+ * Release 0.65.
+
+ * Group watchers for watching watchers. See demo/group.t
+
+ * Fix got() documentation, spotted by
+ [EMAIL PROTECTED]
+
+ * Make callback a prerequisite for starting watchers.
+
+ * Add test checking FIFO dispatch of equal priority events.
+
2000-02-04 Joshua Pritikin <[EMAIL PROTECTED]>
* Release 0.64.
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/Event.h'
'/usr/tmp/mp4384.d/new/Event-0.65/Event.h'
Index: ./Event.h
--- ./Event.h Tue Feb 1 12:18:39 2000
+++ ./Event.h Mon Feb 7 15:19:18 2000
@@ -150,7 +150,7 @@ struct pe_watcher_vtbl {
#define WaDESTROYED_off(ev) (WaFLAGS(ev) &= ~PE_DESTROYED)
#define WaCANDESTROY(ev) \
- (WaCANCELLED(ev) && ev->event_counter == 0 && !ev->mysv)
+ (WaCANCELLED(ev) && ev->refcnt == 0 && !ev->mysv)
#define EvFLAGS(ev) ((pe_event*)ev)->flags
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/Event.xs'
'/usr/tmp/mp4384.d/new/Event-0.65/Event.xs'
Index: ./Event.xs
--- ./Event.xs Fri Feb 4 17:39:18 2000
+++ ./Event.xs Mon Feb 7 15:16:44 2000
@@ -236,6 +236,7 @@ double null_loops_per_second(int sec)
#include "var.c"
#include "signal.c"
#include "tied.c"
+#include "group.c"
#include "queue.c"
MODULE = Event PACKAGE = Event
@@ -256,6 +257,7 @@ BOOT:
boot_var();
boot_tied();
boot_signal();
+ boot_group();
boot_queue();
{
struct EventAPI *api;
@@ -534,7 +536,14 @@ DESTROY(ref)
int
pe_watcher::pending()
CODE:
- RETVAL = THIS->event_counter;
+{
+ pe_ring *lk = &THIS->events;
+ RETVAL = 0;
+ while (lk->next->self) { /* should not be too wasteful */
+ ++RETVAL;
+ lk = lk->next;
+ }
+}
OUTPUT:
RETVAL
@@ -857,4 +866,35 @@ pe_watcher::signal(...)
PPCODE:
PUTBACK;
_signal_signal(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
+ SPAGAIN;
+
+MODULE = Event PACKAGE = Event::group
+
+void
+allocate(clname, temple)
+ SV *clname;
+ SV *temple;
+ PPCODE:
+ XPUSHs(watcher_2sv(pe_group_allocate(gv_stashsv(clname, 1),
+ SvRV(temple))));
+
+void
+pe_watcher::timeout(...)
+ PPCODE:
+ PUTBACK;
+ _group_timeout(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
+ SPAGAIN;
+
+void
+pe_watcher::add(...)
+ PPCODE:
+ PUTBACK;
+ _group_add(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
+ SPAGAIN;
+
+void
+pe_watcher::del(...)
+ PPCODE:
+ PUTBACK;
+ _group_del(THIS, items == 2? sv_mortalcopy(ST(1)) : 0);
SPAGAIN;
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/MANIFEST'
'/usr/tmp/mp4384.d/new/Event-0.65/MANIFEST'
Index: ./MANIFEST
--- ./MANIFEST Thu Feb 3 16:36:05 2000
+++ ./MANIFEST Mon Feb 7 16:21:03 2000
@@ -9,6 +9,7 @@ Makefile.PL
README
TODO
c/ev.c
+c/group.c
c/hook.c
c/idle.c
c/io.c
@@ -23,6 +24,7 @@ c/var.c
c/watcher.c
demo/in.pl
demo/inactivity.t
+demo/group.t
demo/process.pm
demo/readline.t
demo/spin_io.t
@@ -32,6 +34,7 @@ lib/Event.pod
lib/Event/EventAPI.h
lib/Event/MakeMaker.pm
lib/Event/Watcher.pm
+lib/Event/group.pm
lib/Event/idle.pm
lib/Event/inactivity.pm
lib/Event/io.pm
@@ -47,6 +50,7 @@ t/bored.t
t/callback.t
t/delete.t
t/eval.t
+t/fifo.t
t/hook.t
t/hup.t
t/idle.t
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/TODO'
'/usr/tmp/mp4384.d/new/Event-0.65/TODO'
Index: ./TODO
--- ./TODO Thu Feb 3 16:32:58 2000
+++ ./TODO Mon Feb 7 16:29:35 2000
@@ -1,10 +1,11 @@
+deprecate inactivity completely?
+
+add timeout for var watchers?
+
increase the number of priority levels?
ASYNC 0 1 2 3 4 5 6 7 8 9 IDLE
HIGH NORM
-rethink
- pe_check_recovery & ENTER/LEAVE points
-
find owner for Win32 port
documentation
@@ -18,13 +19,8 @@ optimization
queue events from both sides?
try to hoist system calls from the inner loop
-inactivity
- For a single watcher, a simple timeout would surely have the same
- effect. But if there would be a watcher grouping feature (as you
- indicated), watching groups of watchers could provide a new dimension
- of flexibility.
-
-add timeout for var watchers?
+rethink
+ pe_check_recovery & ENTER/LEAVE points
[EMAIL PROTECTED] signal discussion:
The API rsignal overrides the current signal handler. If the signal
@@ -39,9 +35,6 @@ there seems to be some sort of bug in th
> Use of uninitialized value during global destruction.
> Explicit blessing to '' (assuming package main) during global
> destruction.
-
-If I install a watcher and delay the call of loop(), what about
-events arriving in the meantime?
loop
StarvePrio?
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/ev.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/ev.c'
Index: ./c/ev.c
--- ./c/ev.c Thu Feb 3 08:48:26 2000
+++ ./c/ev.c Mon Feb 7 13:26:55 2000
@@ -11,7 +11,7 @@ pe_event_vtbl event_vtbl, ioevent_vtbl;
static void pe_anyevent_init(pe_event *ev, pe_watcher *wa) {
assert(wa);
ev->up = wa;
- ++wa->event_counter;
+ ++wa->refcnt;
ev->mysv = 0;
PE_RING_INIT(&ev->peer, ev);
PE_RING_UNSHIFT(&ev->peer, &wa->events);
@@ -36,7 +36,7 @@ static void pe_anyevent_dtor(pe_event *e
ev->callback = 0;
PE_RING_DETACH(&ev->peer);
PE_RING_DETACH(&ev->que);
- --wa->event_counter;
+ --wa->refcnt;
if (WaCANDESTROY(wa)) /* running */
(*wa->vtbl->dtor)(wa);
}
gdiff -up /dev/null '/usr/tmp/mp4384.d/new/Event-0.65/c/group.c'
Index: ./c/group.c
--- ./c/group.c Wed Dec 31 19:00:00 1969
+++ ./c/group.c Mon Feb 7 16:17:11 2000
@@ -0,0 +1,153 @@
+static struct pe_watcher_vtbl pe_group_vtbl;
+
+static pe_watcher *pe_group_allocate(HV *stash, SV *temple) {
+ pe_group *ev;
+ EvNew(12, ev, 1, pe_group);
+ ev->base.vtbl = &pe_group_vtbl;
+ PE_RING_INIT(&ev->tm.ring, ev);
+ ev->tm.at = 0;
+ ev->timeout = &PL_sv_undef;
+ ev->members = 3;
+ EvNew(13, ev->member, ev->members, pe_watcher*);
+ Zero(ev->member, ev->members, pe_watcher*);
+ pe_watcher_init(&ev->base, stash, temple);
+ WaREPEAT_on(ev);
+ return (pe_watcher*) ev;
+}
+
+static void pe_group_dtor(pe_watcher *ev) {
+ int xx;
+ pe_group *gp = (pe_group*) ev;
+ SvREFCNT_dec(gp->timeout);
+ for (xx=0; xx < gp->members; xx++) {
+ pe_watcher *mb = gp->member[xx];
+ if (mb)
+ --mb->refcnt;
+ }
+ EvFree(13, gp->member);
+ pe_watcher_dtor(ev);
+ EvFree(12, ev);
+}
+
+static char *pe_group_start(pe_watcher *ev, int repeat) {
+ pe_group *gp = (pe_group*) ev;
+ double timeout;
+
+ if (!ev->callback)
+ return "without callback";
+ if (!sv_2interval(gp->timeout, &timeout))
+ return "repeating group has no timeout";
+
+ gp->since = WaHARD(ev)? gp->tm.at : NVtime();
+ gp->tm.at = timeout + gp->since;
+ pe_timeable_start(&gp->tm);
+ return 0;
+}
+
+static void pe_group_stop(pe_watcher *ev)
+{ pe_timeable_stop(&((pe_group*)ev)->tm); }
+
+static void pe_group_alarm(pe_watcher *wa, pe_timeable *tm) {
+ STRLEN n_a;
+ pe_group *gp = (pe_group*) wa;
+ double timeout;
+ double remaining;
+ double now = NVtime();
+ int xx;
+ for (xx=0; xx < gp->members; xx++) {
+ pe_watcher *mb = gp->member[xx];
+ if (!mb) continue;
+ if (gp->since < mb->cbtime) {
+ gp->since = mb->cbtime;
+ }
+ }
+
+ if (!sv_2interval(gp->timeout, &timeout))
+ croak("Event: can't extract timeout"); /* impossible */
+
+ remaining = gp->since + timeout - now;
+ if (remaining > IntervalEpsilon) {
+ gp->tm.at = now + remaining;
+ pe_timeable_start(&gp->tm);
+ } else {
+ pe_event *ev = (*wa->vtbl->new_event)(wa);
+ ++ev->hits;
+ queueEvent(ev);
+ }
+}
+
+/* publish C API XXX */
+static void pe_group_add(pe_group *gp, pe_watcher *wa) {
+ int ok=0;
+ int xx;
+ if (gp == (pe_group*) wa) {
+ STRLEN n_a;
+ croak("Event: can't add group '%s' to itself",
+ SvPV(gp->base.desc, n_a));
+ }
+ ++wa->refcnt;
+ for (xx=0; xx < gp->members; xx++) {
+ if (!gp->member[xx]) {
+ gp->member[xx] = wa;
+ ok=1; break;
+ }
+ }
+ if (!ok) { /* expand array */
+ pe_watcher **ary;
+ EvNew(13, ary, gp->members*2, pe_watcher*);
+ Copy(gp->member, ary, gp->members, sizeof(pe_watcher*));
+ EvFree(13, gp->member);
+ gp->member = ary;
+ gp->member[gp->members] = wa;
+ gp->members *= 2;
+ }
+}
+
+static void pe_group_del(pe_group *gp, pe_watcher *target) {
+ int xx;
+ for (xx=0; xx < gp->members; xx++) {
+ if (gp->member[xx] != target)
+ continue;
+ --target->refcnt;
+ gp->member[xx] = 0;
+ break;
+ }
+}
+
+WKEYMETH(_group_timeout) {
+ pe_group *gp = (pe_group*)ev;
+ if (!nval) {
+ dSP;
+ XPUSHs(gp->timeout);
+ PUTBACK;
+ } else {
+ SV *old = gp->timeout;
+ gp->timeout = SvREFCNT_inc(nval);
+ SvREFCNT_dec(old);
+ /* recalc expiration XXX */
+ }
+}
+
+WKEYMETH(_group_add) {
+ pe_group *gp = (pe_group*)ev;
+ if (!nval)
+ return;
+ pe_group_add(gp, sv_2watcher(nval));
+}
+
+WKEYMETH(_group_del) {
+ pe_group *gp = (pe_group*)ev;
+ if (!nval)
+ return;
+ pe_group_del(gp, sv_2watcher(nval));
+}
+
+static void boot_group() {
+ pe_watcher_vtbl *vt = &pe_group_vtbl;
+ memcpy(vt, &pe_watcher_base_vtbl, sizeof(pe_watcher_base_vtbl));
+ vt->dtor = pe_group_dtor;
+ vt->start = pe_group_start;
+ vt->stop = pe_group_stop;
+ vt->alarm = pe_group_alarm;
+ pe_register_vtbl(vt, gv_stashpv("Event::group",1), &event_vtbl);
+}
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/idle.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/idle.c'
Index: ./c/idle.c
--- ./c/idle.c Tue Feb 1 12:26:44 2000
+++ ./c/idle.c Mon Feb 7 10:15:08 2000
@@ -28,6 +28,8 @@ static char *pe_idle_start(pe_watcher *e
double now;
double min,max;
pe_idle *ip = (pe_idle*) ev;
+ if (!ev->callback)
+ return "without callback";
if (SvOK(ip->min_interval) || SvOK(ip->max_interval))
WaCBTIME_on(ev);
else
@@ -48,7 +50,7 @@ static char *pe_idle_start(pe_watcher *e
pe_timeable_start(&ip->tm);
}
}
- return 0; /* always succeeds */
+ return 0;
}
static void pe_idle_alarm(pe_watcher *wa, pe_timeable *_ignore) {
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/io.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/io.c'
Index: ./c/io.c
--- ./c/io.c Tue Feb 1 12:33:58 2000
+++ ./c/io.c Mon Feb 7 10:17:15 2000
@@ -44,12 +44,16 @@ static char *pe_io_start(pe_watcher *_ev
officially supported but maybe it is too unix specific. */
if (ev->fd >= 0) {
+ if (!ev->base.callback)
+ return "Without io callback";
PE_RING_UNSHIFT(&ev->ioring, &IOWatch);
++IOWatchCount;
IOWatch_OK = 0;
++ok;
}
if (ev->timeout) {
+ if (!ev->base.callback && !ev->tm_callback)
+ return "without timeout callback";
WaCBTIME_on(ev);
ev->poll |= PE_T;
ev->tm.at = NVtime() + ev->timeout; /* too early okay */
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/signal.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/signal.c'
Index: ./c/signal.c
--- ./c/signal.c Tue Feb 1 12:30:27 2000
+++ ./c/signal.c Mon Feb 7 10:17:55 2000
@@ -49,8 +49,10 @@ static void pe_signal_dtor(pe_watcher *e
static char *pe_signal_start(pe_watcher *_ev, int repeat) {
pe_signal *ev = (pe_signal*) _ev;
int sig = ev->signal;
+ if (!_ev->callback)
+ return "without callback";
if (sig == 0)
- return "no signal";
+ return "without signal";
if (PE_RING_EMPTY(&Sigring[sig]))
rsignal(sig, process_sighandler);
PE_RING_UNSHIFT(&ev->sring, &Sigring[sig]);
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/timer.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/timer.c'
Index: ./c/timer.c
--- ./c/timer.c Tue Feb 1 12:28:04 2000
+++ ./c/timer.c Mon Feb 7 13:24:54 2000
@@ -22,6 +22,8 @@ static void pe_timer_dtor(pe_watcher *ev
static char *pe_timer_start(pe_watcher *ev, int repeat) {
STRLEN n_a;
pe_timer *tm = (pe_timer*) ev;
+ if (!ev->callback)
+ return "without callback";
if (repeat) {
/* We just finished the callback and need to re-insert at
the appropriate time increment. */
@@ -29,8 +31,6 @@ static char *pe_timer_start(pe_watcher *
if (!sv_2interval(tm->interval, &interval))
return "repeating timer has no interval";
- if (interval <= 0)
- return "non-positive interval";
tm->tm.at = interval + (WaHARD(ev)? tm->tm.at : NVtime());
}
@@ -74,6 +74,7 @@ WKEYMETH(_timer_interval) {
SV *old = tp->interval;
tp->interval = SvREFCNT_inc(nval);
SvREFCNT_dec(old);
+ /* recalc expiration XXX */
}
}
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/typemap.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/typemap.c'
Index: ./c/typemap.c
--- ./c/typemap.c Thu Jan 20 13:50:53 2000
+++ ./c/typemap.c Mon Feb 7 13:25:24 2000
@@ -104,19 +104,20 @@ static int sv_2interval(SV *in, double *
sv = SvRV(sv);
if (SvNOK(sv)) {
*out = SvNVX(sv);
- return 1;
- }
- if (SvIOK(sv)) {
+ } else if (SvIOK(sv)) {
*out = SvIVX(sv);
- return 1;
- }
- if (looks_like_number(sv)) {
+ } else if (looks_like_number(sv)) {
*out = SvNV(sv);
- return 1;
+ } else {
+ sv_dump(in);
+ croak("Interval must be a number of reference to a number");
+ return 0;
+ }
+ if (*out < 0) {
+ warn("Event: negative timeout (%.2f) clipped to zero", *out);
+ *out = 0;
}
- sv_dump(in);
- croak("Interval must be a number of reference to a number");
- return 0;
+ return 1;
}
static SV* events_mask_2sv(int mask) {
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/var.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/var.c'
Index: ./c/var.c
--- ./c/var.c Thu Feb 3 16:09:09 2000
+++ ./c/var.c Mon Feb 7 10:18:42 2000
@@ -60,10 +60,12 @@ static char *pe_var_start(pe_watcher *_e
pe_var *ev = (pe_var*) _ev;
SV *sv = ev->variable;
+ if (!_ev->callback)
+ return "without callback";
if (!sv || !SvOK(sv))
return "watching what?";
if (!ev->events)
- return "no poll events specified";
+ return "without poll events specified";
sv = SvRV(sv);
if (SvREADONLY(sv))
return "cannot trace read-only variable";
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/c/watcher.c'
'/usr/tmp/mp4384.d/new/Event-0.65/c/watcher.c'
Index: ./c/watcher.c
--- ./c/watcher.c Tue Feb 1 12:31:51 2000
+++ ./c/watcher.c Mon Feb 7 13:26:35 2000
@@ -34,7 +34,7 @@ static void pe_watcher_init(pe_watcher *
WaREENTRANT_on(ev);
ev->FALLBACK = 0;
NextID = (NextID+1) & 0x7fff; /* make it look like the kernel :-, */
- ev->event_counter = 0;
+ ev->refcnt = 0;
ev->desc = newSVpvn("??",2);
ev->running = 0;
ev->max_cb_tm = 1; /* make default configurable? */
gdiff -up /dev/null '/usr/tmp/mp4384.d/new/Event-0.65/demo/group.t'
Index: ./demo/group.t
--- ./demo/group.t Wed Dec 31 19:00:00 1969
+++ ./demo/group.t Mon Feb 7 16:20:44 2000
@@ -0,0 +1,25 @@
+#!./perl -w
+
+use strict;
+use Test; plan test => 6;
+use Event qw(time);
+require Event::group;
+
+my $g = Event->group(parked=>1, timeout => 1.95, cb => sub {
+ my $e = shift;
+ warn "timeout at ".$e->w->cbtime;
+ },
+ add => Event->timer(desc => '1', interval => 2,
+ cb => sub {
+ my $e = shift;
+ warn "boink #1 at ".$e->w->cbtime
+ }),
+ add => Event->timer(desc => '2', interval => 2.5,
+ cb => sub {
+ my $e = shift;
+ warn "boink #2 at ".$e->w->cbtime
+ }),
+ );
+$g->start;
+
+Event::loop();
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/lib/Event.pm'
'/usr/tmp/mp4384.d/new/Event-0.65/lib/Event.pm'
Index: ./lib/Event.pm
--- ./lib/Event.pm Fri Feb 4 17:42:44 2000
+++ ./lib/Event.pm Mon Feb 7 16:22:05 2000
@@ -13,7 +13,7 @@ use Carp;
eval { require Carp::Heavy; }; # work around perl_call_pv bug XXX
use vars qw($VERSION @EXPORT_OK
$API $DebugLevel $Eval $DIED $Now);
-$VERSION = '0.64';
+$VERSION = '0.65';
# If we inherit DynaLoader then we inherit AutoLoader; Bletch!
require DynaLoader;
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/lib/Event.pod'
'/usr/tmp/mp4384.d/new/Event-0.65/lib/Event.pod'
Index: ./lib/Event.pod
--- ./lib/Event.pod Fri Feb 4 17:39:18 2000
+++ ./lib/Event.pod Mon Feb 7 13:08:50 2000
@@ -181,8 +181,8 @@ Reports whether the C<$watcher> is suspe
=item $watcher->pending
-Returns how many events this watcher has with the callback still pending
-in the event queue.
+Returns whether this watcher has any events pending in the event
+queue.
=back
@@ -211,7 +211,7 @@ Otherwise, they might be deprecated.
=item var
-Extra attributes: var => \$var, poll => 'rw', got => 'rw',
+Extra attributes: var => \$var, poll => 'rw'
Var watchers generate events when the given variable is read from or
written to.
@@ -237,7 +237,7 @@ calculated relative to the current time
=item io
-Extra attributes: fd => $fd, poll => 'rwe', got => 'rwet',
+Extra attributes: fd => $fd, poll => 'rwe'
[timeout => $seconds, hard => $bool, timeout_cb => \&code]
The callback is invoked when the file descriptor, C<fd>, has data to
@@ -269,7 +269,8 @@ Not yet implemented.
Priority is used to sort the event queue. Meaningful priorities range
from -1 to 6 inclusive. Lower numbers mean higher priority (-1 is the
highest priority and 6 is the lowest). If multiple events get queued,
-the ones with the highest priority are serviced first.
+the ones with the highest priority are serviced first. Events with
+equal priority are serviced in first-in-first-out order.
use Event qw(PRIO_HIGH PRIO_NORMAL); # some constants
@@ -485,7 +486,7 @@ A reference to the variable being watche
C<got> is available in the callback of watchers with C<poll>.
C<got> is in the same format as C<poll> except that it gives what
kind of event actually happened. In contrast, C<poll> is just an
-expression of interest.
+indication of interest.
=item hits => $int
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/lib/Event/EventAPI.h'
'/usr/tmp/mp4384.d/new/Event-0.65/lib/Event/EventAPI.h'
Index: ./lib/Event/EventAPI.h
--- ./lib/Event/EventAPI.h Tue Feb 1 12:18:15 2000
+++ ./lib/Event/EventAPI.h Mon Feb 7 13:28:45 2000
@@ -28,7 +28,7 @@ struct pe_watcher {
pe_ring all; /* all watchers */
pe_ring events; /* this watcher's queued events */
HV *FALLBACK;
- I16 event_counter; /* refcnt? XXX */
+ I16 refcnt; /* internal to Event; not perl related */
I16 prio;
I16 max_cb_tm;
};
@@ -146,6 +146,16 @@ struct pe_var {
pe_watcher base;
SV *variable;
U16 events;
+};
+
+typedef struct pe_group pe_group;
+struct pe_group {
+ pe_watcher base;
+ double since;
+ pe_timeable tm;
+ SV *timeout;
+ int members;
+ pe_watcher **member;
};
typedef struct pe_event_stats_vtbl pe_event_stats_vtbl;
gdiff -up /dev/null '/usr/tmp/mp4384.d/new/Event-0.65/lib/Event/group.pm'
Index: ./lib/Event/group.pm
--- ./lib/Event/group.pm Wed Dec 31 19:00:00 1969
+++ ./lib/Event/group.pm Mon Feb 7 16:15:17 2000
@@ -0,0 +1,30 @@
+use strict;
+package Event::group;
+use Carp;
+use base 'Event::Watcher';
+use vars qw(@ATTRIBUTE);
+
+@ATTRIBUTE = qw(timeout);
+
+'Event::Watcher'->register;
+
+sub new {
+ my $class = shift;
+ my %arg;
+ my @add;
+ while (my ($k,$v) = splice(@_, 0, 2)) {
+ if ($k eq 'add') {
+ push @add, $v;
+ } elsif ($k eq 'del') {
+ carp "del in constructor (ignored)";
+ } else {
+ $arg{$k} = $v;
+ }
+ }
+ my $o = allocate($class, delete $arg{attach_to} || {});
+ $o->init(\%arg);
+ $o->add($_) for @add;
+ $o;
+}
+
+1;
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/t/attach_to.t'
'/usr/tmp/mp4384.d/new/Event-0.65/t/attach_to.t'
Index: ./t/attach_to.t
--- ./t/attach_to.t Fri Feb 4 08:14:42 2000
+++ ./t/attach_to.t Mon Feb 7 15:23:15 2000
@@ -6,9 +6,9 @@ use Event 0.53;
# $Event::DebugLevel = 3;
-my $array = Event->timer(attach_to => [0,1,2], after => 1);
+my $array = Event->timer(attach_to => [0,1,2], after => 1, cb => \&die);
ok $array->[2], 2;
ok $array->interval, 1;
-eval { Event->timer(attach_to => bless([]), after => 1); };
+eval { Event->timer(attach_to => bless([]), after => 1, cb => \&die); };
ok $@, '/blessed/';
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/t/bored.t'
'/usr/tmp/mp4384.d/new/Event-0.65/t/bored.t'
Index: ./t/bored.t
--- ./t/bored.t Fri Feb 4 08:14:49 2000
+++ ./t/bored.t Mon Feb 7 15:24:26 2000
@@ -5,17 +5,18 @@ use Event;
# $Event::DebugLevel = 3;
my $really_bored;
-my $e;
-$e = Event->timer(after => .5);
-ok !defined $e->cb;
-$e->cb(sub {
+my $w;
+$w = Event->timer(after => .5, parked => 1);
+ok !defined $w->cb;
+$w->cb(sub {
if (!$really_bored) {
- $e->again;
+ $w->again;
$really_bored='yes';
} else {
ok 1;
}
});
-ok ref $e->cb, 'CODE';
+ok ref $w->cb, 'CODE';
+$w->start;
ok !defined Event::loop();
gdiff -up /dev/null '/usr/tmp/mp4384.d/new/Event-0.65/t/fifo.t'
Index: ./t/fifo.t
--- ./t/fifo.t Wed Dec 31 19:00:00 1969
+++ ./t/fifo.t Mon Feb 7 15:26:14 2000
@@ -0,0 +1,29 @@
+#!./perl -w
+# check FIFO dispatch of equal priority events
+
+use Test; plan test => 1;
+use Event;
+
+my @hit;
+sub cb {
+ my ($e) = @_;
+ push @hit, $e->w->desc;
+}
+
+my $t1 = Event->timer(desc => 1, after => 10, cb => \&cb);
+my $t2 = Event->timer(desc => 2, after => 10, cb => \&cb);
+my $t3 = Event->timer(desc => 3, after => 10, cb => \&cb);
+my $h4 = Event->timer(desc => 4, nice => -1, after => 10, cb => \&cb);
+my $h5 = Event->timer(desc => 5, nice => -1, after => 10, cb => \&cb);
+
+$t2->now;
+$h4->now;
+$t1->now;
+$t1->now;
+$t3->now;
+$h5->now;
+$t2->now;
+$t1->now;
+
+Event::loop();
+ok join('', @hit), '45211321';
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/t/leak.t'
'/usr/tmp/mp4384.d/new/Event-0.65/t/leak.t'
Index: ./t/leak.t
--- ./t/leak.t Fri Feb 4 08:15:58 2000
+++ ./t/leak.t Mon Feb 7 15:27:22 2000
@@ -8,12 +8,12 @@ ok @e, 0;
ok @e, 0;
sub thrash {
- Event->idle()->cancel;
+ Event->idle(parked=>1)->cancel;
Event->io(parked => 1)->cancel;
- Event->signal(signal => 'INT')->cancel;
- Event->timer(at => time)->cancel;
+ Event->signal(parked=>1)->cancel;
+ Event->timer(parked=>1)->cancel;
my $var = 1;
- Event->var(var => \$var)->cancel;
+ Event->var(parked=>1)->cancel;
}
for (1..2) { thrash(); }
gdiff -up '/usr/tmp/mp4384.d/old/Event-0.64/t/unconfigured.t'
'/usr/tmp/mp4384.d/new/Event-0.65/t/unconfigured.t'
Index: ./t/unconfigured.t
--- ./t/unconfigured.t Fri Feb 4 08:17:57 2000
+++ ./t/unconfigured.t Mon Feb 7 15:32:13 2000
@@ -1,28 +1,27 @@
#!./perl -w
use strict;
-use Test; plan test => 7;
+use Test; plan test => 6;
use Event;
-eval { Event->io };
+my @p = (cb=>\&die);
+
+eval { Event->io(@p) };
ok $@, '/unconfigured/';
-eval { Event->signal };
-ok $@, '/no signal/';
+eval { Event->signal(@p) };
+ok $@, '/without signal/';
-eval { Event->timer };
+eval { Event->timer(@p) };
ok $@, '/unset/';
-eval { Event->timer(parked => 1, interval => -1)->again };
-ok $@, '/non\-positive/';
-
-eval { Event->var };
+eval { Event->var(@p) };
ok $@, '/watching what/';
my $var = 1;
-eval { Event->var(poll => 0, var => \$var) };
-ok $@, '/no poll events/';
+eval { Event->var(@p, poll => 0, var => \$var) };
+ok $@, '/without poll events/';
-eval { Event->var(var => \$1) };
+eval { Event->var(@p, var => \$1) };
ok $@, '/read\-only/';
#### End of Patch data ####
#### ApplyPatch data follows ####
# Data version : 1.0
# Date generated : Mon Feb 7 16:30:13 2000
# Generated by : makepatch 2.00 (2.0BETA)
# Recurse directories : Yes
# p 'ChangeLog' 21762 949958518 0100444
# p 'Event.h' 4576 949954758 0100444
# p 'Event.xs' 17402 949954604 0100444
# p 'MANIFEST' 845 949958463 0100444
# p 'TODO' 1921 949958975 0100444
# p 'c/ev.c' 7871 949948015 0100444
# c 'c/group.c' 0 949958231 0100444
# p 'c/idle.c' 3544 949936508 0100444
# p 'c/io.c' 5222 949936635 0100444
# p 'c/signal.c' 3788 949936675 0100444
# p 'c/timer.c' 2150 949947894 0100444
# p 'c/typemap.c' 3806 949947924 0100444
# p 'c/var.c' 4082 949936722 0100444
# p 'c/watcher.c' 8955 949947995 0100444
# c 'demo/group.t' 0 949958444 0100444
# p 'lib/Event.pm' 4254 949958525 0100444
# p 'lib/Event.pod' 21895 949946930 0100444
# p 'lib/Event/EventAPI.h' 5379 949948125 0100444
# c 'lib/Event/group.pm' 0 949958117 0100444
# p 't/attach_to.t' 280 949954995 0100444
# p 't/bored.t' 339 949955066 0100444
# c 't/fifo.t' 0 949955174 0100444
# p 't/leak.t' 659 949955242 0100444
# p 't/unconfigured.t' 476 949955533 0100444
#### End of ApplyPatch data ####
#### End of Patch kit [created: Mon Feb 7 16:30:13 2000] ####
#### Checksum: 896 25763 48850 ####
--
"May the best description of competition prevail."
via, but not speaking for Deutsche Bank