Fwd: CPAN Upload: JPRIT/Event-0.65.tar.gz
[email protected] (Joshua N Pritikin)
| Newsgroups | perl.loop |
|---|---|
| Message-ID | <[email protected]> |
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