Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Move Philip Gwyn's signals test to POE::Test::Loops, so it can

exercise everyone's event loops.
  • Loading branch information...
commit 364246096c8de24e9ff51e83343407a8b2faa5d4 1 parent a88bc2c
@rcaputo authored
Showing with 4 additions and 43,249 deletions.
  1. +2 −1  poe-test-loops/MANIFEST
  2. +2 −0  poe/t/90_regression/leolo-poe-wheel-run.t → poe-test-loops/lib/POE/Test/Loops/z_leolo_wheel_run.pm
  3. +0 −464 poe/HISTORY
  4. +0 −153 poe/MANIFEST
  5. +0 −30 poe/MANIFEST.SKIP
  6. +0 −78 poe/Makefile.PL
  7. +0 −94 poe/README
  8. +0 −20 poe/TODO
  9. +0 −17 poe/docs/Makefile
  10. +0 −55 poe/docs/POE-HINTS.outline
  11. +0 −1,856 poe/docs/POE-TODO.outline
  12. +0 −357 poe/docs/out-out.perl
  13. +0 −3  poe/examples/README.samples
  14. +0 −229 poe/examples/create.perl
  15. +0 −177 poe/examples/fakelogin.perl
  16. +0 −186 poe/examples/forkbomb.perl
  17. +0 −323 poe/examples/names.perl
  18. +0 −143 poe/examples/objmaps.perl
  19. +0 −137 poe/examples/objsessions.perl
  20. +0 −125 poe/examples/packagesessions.perl
  21. +0 −145 poe/examples/queue.perl
  22. +0 −378 poe/examples/selects.perl
  23. +0 −212 poe/examples/sessions.perl
  24. +0 −121 poe/examples/signals.perl
  25. +0 −162 poe/examples/tcp_watermarks.perl
  26. +0 −470 poe/examples/thrash.perl
  27. +0 −199 poe/examples/watermarks.perl
  28. +0 −160 poe/examples/wheels2.perl
  29. +0 −689 poe/lib/POE.pm
  30. +0 −121 poe/lib/POE/Component.pm
  31. +0 −806 poe/lib/POE/Component/Client/TCP.pm
  32. +0 −1,375 poe/lib/POE/Component/Server/TCP.pm
  33. +0 −169 poe/lib/POE/Driver.pm
  34. +0 −255 poe/lib/POE/Driver/SysRW.pm
  35. +0 −367 poe/lib/POE/Filter.pm
  36. +0 −282 poe/lib/POE/Filter/Block.pm
  37. +0 −237 poe/lib/POE/Filter/Grep.pm
  38. +0 −539 poe/lib/POE/Filter/HTTPD.pm
  39. +0 −380 poe/lib/POE/Filter/Line.pm
  40. +0 −243 poe/lib/POE/Filter/Map.pm
  41. +0 −225 poe/lib/POE/Filter/RecordBlock.pm
  42. +0 −400 poe/lib/POE/Filter/Reference.pm
  43. +0 −379 poe/lib/POE/Filter/Stackable.pm
  44. +0 −131 poe/lib/POE/Filter/Stream.pm
  45. +0 −5,374 poe/lib/POE/Kernel.pm
  46. +0 −92 poe/lib/POE/Loader.pm
  47. +0 −574 poe/lib/POE/Loop.pm
  48. +0 −247 poe/lib/POE/Loop/Event.pm
  49. +0 −356 poe/lib/POE/Loop/Gtk.pm
  50. +0 −427 poe/lib/POE/Loop/IO_Poll.pm
  51. +0 −204 poe/lib/POE/Loop/PerlSignals.pm
  52. +0 −374 poe/lib/POE/Loop/Select.pm
  53. +0 −241 poe/lib/POE/Loop/Tk.pm
  54. +0 −291 poe/lib/POE/Loop/TkActiveState.pm
  55. +0 −193 poe/lib/POE/Loop/TkCommon.pm
  56. +0 −1,092 poe/lib/POE/NFA.pm
  57. +0 −292 poe/lib/POE/Pipe.pm
  58. +0 −205 poe/lib/POE/Pipe/OneWay.pm
  59. +0 −220 poe/lib/POE/Pipe/TwoWay.pm
  60. +0 −310 poe/lib/POE/Queue.pm
  61. +0 −470 poe/lib/POE/Queue/Array.pm
  62. +0 −84 poe/lib/POE/Resource.pm
  63. +0 −174 poe/lib/POE/Resource/Aliases.pm
  64. +0 −333 poe/lib/POE/Resource/Events.pm
  65. +0 −214 poe/lib/POE/Resource/Extrefs.pm
  66. +0 −876 poe/lib/POE/Resource/FileHandles.pm
  67. +0 −125 poe/lib/POE/Resource/SIDs.pm
  68. +0 −579 poe/lib/POE/Resource/Sessions.pm
  69. +0 −917 poe/lib/POE/Resource/Signals.pm
  70. +0 −334 poe/lib/POE/Resource/Statistics.pm
  71. +0 −87 poe/lib/POE/Resources.pm
  72. +0 −1,735 poe/lib/POE/Session.pm
  73. +0 −334 poe/lib/POE/Wheel.pm
  74. +0 −250 poe/lib/POE/Wheel/Curses.pm
  75. +0 −821 poe/lib/POE/Wheel/FollowTail.pm
  76. +0 −357 poe/lib/POE/Wheel/ListenAccept.pm
  77. +0 −3,558 poe/lib/POE/Wheel/ReadLine.pm
  78. +0 −1,180 poe/lib/POE/Wheel/ReadWrite.pm
  79. +0 −1,792 poe/lib/POE/Wheel/Run.pm
  80. +0 −1,603 poe/lib/POE/Wheel/SocketFactory.pm
  81. +0 −47 poe/mylib/Devel/Null.pm
  82. +0 −71 poe/mylib/Makefile-5004.pm
  83. +0 −144 poe/mylib/Makefile-5005.pm
  84. +0 −44 poe/mylib/MyOtherFreezer.pm
  85. +0 −106 poe/mylib/PoeBuildInfo.pm
  86. +0 −115 poe/mylib/coverage.perl
  87. +0 −179 poe/mylib/cpan-test.perl
  88. +0 −79 poe/mylib/events_per_second.pl
  89. +0 −46 poe/mylib/gen-meta.perl
  90. +0 −119 poe/mylib/gen-tests.perl
  91. +0 −14 poe/mylib/preprocessor.perl
  92. +0 −339 poe/mylib/svn-log.perl
  93. +0 −9 poe/t/00_info.t
  94. +0 −7 poe/t/10_units/01_pod/01_pod.t
  95. +0 −68 poe/t/10_units/01_pod/02_pod_coverage.t
  96. +0 −9 poe/t/10_units/02_pipes/01_base.t
  97. +0 −56 poe/t/10_units/02_pipes/02_oneway.t
  98. +0 −80 poe/t/10_units/02_pipes/03_twoway.t
  99. +0 −40 poe/t/10_units/03_base/01_poe.t
  100. +0 −11 poe/t/10_units/03_base/03_component.t
  101. +0 −15 poe/t/10_units/03_base/04_driver.t
  102. +0 −15 poe/t/10_units/03_base/05_filter.t
  103. +0 −11 poe/t/10_units/03_base/06_loop.t
  104. +0 −15 poe/t/10_units/03_base/07_queue.t
  105. +0 −11 poe/t/10_units/03_base/08_resource.t
  106. +0 −98 poe/t/10_units/03_base/09_resources.t
  107. +0 −33 poe/t/10_units/03_base/10_wheel.t
  108. +0 −451 poe/t/10_units/03_base/11_assert_usage.t
  109. +0 −165 poe/t/10_units/03_base/12_assert_retval.t
  110. +0 −68 poe/t/10_units/03_base/13_assert_data.t
  111. +0 −35 poe/t/10_units/03_base/14_kernel.t
  112. +0 −88 poe/t/10_units/03_base/15_kernel_internal.t
  113. +0 −8 poe/t/10_units/03_base/16_explicit_loop.t
  114. +0 −14 poe/t/10_units/03_base/17_explicit_loop_fail.t
  115. +0 −64 poe/t/10_units/03_base/18_nfa_usage.t
  116. +0 −296 poe/t/10_units/04_drivers/01_sysrw.t
  117. +0 −142 poe/t/10_units/05_filters/01_block.t
  118. +0 −110 poe/t/10_units/05_filters/02_grep.t
  119. +0 −446 poe/t/10_units/05_filters/03_http.t
  120. +0 −195 poe/t/10_units/05_filters/04_line.t
  121. +0 −68 poe/t/10_units/05_filters/05_map.t
  122. +0 −110 poe/t/10_units/05_filters/06_recordblock.t
Sorry, we could not display the entire diff because it was too big.
View
3  poe-test-loops/MANIFEST
@@ -31,8 +31,9 @@ lib/POE/Test/Loops/wheel_sf_udp.pm
lib/POE/Test/Loops/wheel_sf_unix.pm
lib/POE/Test/Loops/wheel_tail.pm
lib/POE/Test/Loops/z_kogman_sig_order.pm
+lib/POE/Test/Loops/z_leolo_wheel_run.pm
lib/POE/Test/Loops/z_merijn_sigchld_system.pm
-# TODO - Why does this segfault for others: lib/POE/Test/Loops/z_rt39872_sigchld.pm
+lib/POE/Test/Loops/z_rt39872_sigchld.pm
lib/POE/Test/Loops/z_rt39872_sigchld_stop.pm
lib/POE/Test/Loops/z_steinert_signal_integrity.pm
t/01_no_tests.t
View
2  poe/t/90_regression/leolo-poe-wheel-run.t → ...s/lib/POE/Test/Loops/z_leolo_wheel_run.pm
@@ -117,3 +117,5 @@ sub spawn
}
);
}
+
+1;
View
464 poe/HISTORY
@@ -1,464 +0,0 @@
-$Id$
-
-A brief, pointless history of POE's evolution.
-
--------------------------------------------------------------------------------
-
-Received: from sinistar.idle.com (sinistar.idle.com [198.109.160.36])
- by anshar.shadow.net (8.7.3/8.7.3) with ESMTP id JAA05315
- for <troc@shadow.net>; Fri, 7 Feb 1997 09:59:05 -0500 (EST)
-Received: (from slist@localhost) by sinistar.idle.com (8.7.5/8.7.3)
- id JAA12501; Fri, 7 Feb 1997 09:00:15 -0500 (EST)
-Resent-Date: Fri, 7 Feb 1997 09:00:15 -0500 (EST)
-Message-Id: <199702071400.JAA00295@anshar.shadow.net>
-From: "Rocco Caputo" <troc@shadow.net>
-To: "Felix Gallo" <fgallo@wellspring.us.dg.com>,
- "perl5-porters@perl.org" <perl5-porters@perl.org>
-Date: Fri, 07 Feb 97 08:54:23 -0400
-Reply-To: "Rocco Caputo" <troc@shadow.net>
-Priority: Normal
-Subject: portable multithreading
-Resent-Message-ID: <"O2kshC.A.W5C.lTz-y"@sinistar>
-Resent-From: perl5-porters@perl.org
-X-Mailing-List: <perl5-porters@perl.org> archive/latest/135
-X-Loop: perl5-porters@perl.org
-Precedence: list
-Resent-Sender: perl5-porters-request@perl.org
-Content-Type: text
-Content-Length: 3989
-Status:
-
-On Thu, 06 Feb 1997 12:52:56 +0000, Felix Gallo wrote:
-
->Felix's Perl-related Metaproblems:
->
->1. Perl is not event-driven, so programs which wish
->to make objects available to the network must manually
->interrupt their control flow to determine if a remote
->object transaction request is pending.
-
-I'm writing a MUD in perl. The object language faces
-some of the same issues as perl, but I think there are
-ways around them (in the MUD language and in perl). In
-the MUD server, objects' methods must be compiled into
-perl bytecode. They must be multitasked/multithreaded
-so that bad code won't hang the server, and object
-authors usually should not have to think about events.
-
-For example, this "bad" MUD code will be legal. Don't
-worry, I move on to perl in just a minute.
-
- count = 10000000
- while count--
- say "hello, world! enter some text: "
- getline some_text
- if some_text eq 'quit'
- last
- endif
- endwhile
- say "\ngoodbye, world!\n"
-
-This needs to be compiled to perl bytecode at runtime.
-The MUD bytecode compiler first parses and syntax
-checks an object's source. If everything passes, it
-builds a perl sub definition in a string. This
-sub-in-a-string is treated as an assembly language for
-perl bytecode. The server runs eval() to assemble the
-string-o-perl into bytecodes, and then the resulting sub
-can be called over and over without additional eval()
-overhead. (Thanks, Silmaril!)
-
-Making that bad loop work in an event-driven server is
-a little harder than making bytecodes. The MUD compiler
-will build perl assembly as event-driven state machines.
-It can do this by noting the locations of branch
-destinations and returns from blocking calls. Each of
-these locations starts a new atomic "state", and an
-"instruction pointer" determines which state to run next.
-
-Here's the event-driven perl "assembly" for that sample
-MUD code. It's not very efficient, but it serves for
-illustration.
-
- sub aaaaa {
- # assumes the existence of a tasking/event kernel
- my $task = shift;
- my $namespace = $task->{"namespace"};
- my $ip = $task->{'instruction pointer'}; # state
-
- # initial entry point
- if ($ip == 0) {
- $namespace->{'count'} = 10000000 ;
- $task->{'instruction pointer'} = 1;
- }
- # top of while loop
- elsif ($ip == 1) {
- if ( $namespace->{'count'} -- ) {
- $task->say( qq(hello, world! enter some text: ) ) ;
- # soft block on 'getline'
- $task->{'blocking'} = 'getline';
- $task->{'instruction pointer'} = 2;
- }
- else {
- $task->{'instruction pointer'} = 3;
- }
- }
- # "return" from getline
- elsif ($ip == 2) {
- $namespace->{'some_text'} = $task->getline();
- if ( $namespace->{'some_text'} eq q(quit) ) {
- $task->{'instruction pointer'} = 3;
- }
- else {
- $task->{'instruction pointer'} = 1;
- }
- }
- # after endwhile
- elsif ($ip == 3) {
- $task->say( qq(\ngoodbye, world!\n) ) ;
- $task->{'instruction pointer'} = -1; # signals end
- }
- }
-
-The main select/event loop would have some code to run tasks
-round-robin. Something like this, but probably including code
-to deal with priorities.
-
- if ($next = shift(@task_queue)) {
- if (($next->{'blocking'}) || ($next->run() != -1)) {
- push(@task_queue, $next);
- }
- else {
- undef $next;
- }
- }
-
-And starting a new task might look like this:
-
- $task = new Task($tasking_kernel, "count = ... world!\n");
- if ($task->has_errors()) {
- $task->display_errors();
- undef $task;
- }
- # otherwise the task has been compiled and registered
- # with the $tasking_kernel
-
-Anyway, that's how I'm writing portable multitasking for a
-syntactically simple MUD language. To make this work for
-perl, there would be a standard tasking package, and perl's
-bytecode compiler would need to modify its output to work
-with the package. Sort of like how the perl debugger works.
-
-Just some ideas to ponder.
-
-Rocco
-<troc@shadow.net>
-
--------------------------------------------------------------------------------
-
-Received: from sinistar.idle.com ([198.109.160.36])
- by anshar.shadow.net (8.8.5/8.7.3) with ESMTP id VAA13861
- for <troc@shadow.net>; Mon, 14 Apr 1997 21:04:07 -0400 (EDT)
-Received: (from slist@localhost) by sinistar.idle.com (8.7.5/8.7.3)
- id UAA24149; Mon, 14 Apr 1997 20:37:16 -0400 (EDT)
-Resent-Date: Mon, 14 Apr 1997 20:37:16 -0400 (EDT)
-Message-Id: <199704150040.UAA11517@anshar.shadow.net>
-From: "Rocco Caputo" <troc@shadow.net>
-To: "Gary Howland" <gary@systemics.com>,
- "Tom Christiansen" <tchrist@jhereg.perl.com>
-Cc: "Gary Howland" <gary@systemics.com>, "Hugo van der Sanden" <hv@iii.co.uk>,
- "hv@tyree.iii.co.uk" <hv@tyree.iii.co.uk>,
- "perl5-porters@perl.org" <perl5-porters@perl.org>
-Date: Mon, 14 Apr 97 20:34:01 -0500
-Reply-To: "Rocco Caputo" <troc@shadow.net>
-Priority: Normal
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: Re: Perl5.005 wish list (event loop)
-Resent-Message-ID: <"99mWD.A.PzF.i0sUz"@sinistar>
-Resent-From: perl5-porters@idle.com
-X-Mailing-List: <perl5-porters@idle.com> archive/latest/6171
-X-Loop: perl5-porters@idle.com
-Precedence: list
-Resent-Sender: perl5-porters-request@idle.com
-Content-Type: text/plain; charset="iso-8859-1"
-Content-Length: 1119
-Status:
-
-Gary, et al,
-
-Almost a year ago, I quietly announced something called "Serv + Face".
-Maybe my announcement was a little too quiet.
-
-Serv is a fork-less, select-based framework of event server classes.
-It provides a high level interface to select(), and a very high level
-interface to TCP client and server socket operations. It does not fork.
-
-Face is the start of a curses-based UI framework that can run alone
-or use Serv as its main loop.
-
-The code and a rough draft of the documentation are available from
-<http://www.shadow.net/~troc/perlstuff.html>. If this code is useful
-to anyone, I'd sure like to know.
-
-Rocco
-<troc@shadow.net>
-
-On Tue, 15 Apr 1997 01:36:35 +0200, Gary Howland wrote:
->
->Select is fine. What we (the "event evangelists") want is a "level above"
->select. When we have a chunk of data to send to x streams, we don't want to
->have to call select, see which stream is ready for writing, work out how
->many bytes we can send, send those bytes, shorten our buffers by that amount
->of bytes, and loop back to select. We just want to send the data. And we
->want to do this without forking.
-
--------------------------------------------------------------------------------
-
-Received: from sinistar.idle.com (sinistar.idle.com [198.109.160.36])
- by anshar.shadow.net (8.7.3/8.7.3) with ESMTP id JAA04948
- for <troc@shadow.net>; Fri, 7 Feb 1997 09:54:31 -0500 (EST)
-Received: (from slist@localhost) by sinistar.idle.com (8.7.5/8.7.3)
- id JAA12519; Fri, 7 Feb 1997 09:00:19 -0500 (EST)
-Resent-Date: Fri, 7 Feb 1997 09:00:19 -0500 (EST)
-Message-Id: <199702071400.JAA00339@anshar.shadow.net>
-From: "Rocco Caputo" <troc@shadow.net>
-To: "Felix Gallo" <fgallo@wellspring.us.dg.com>,
- "perl5-porters@perl.org" <perl5-porters@perl.org>
-Date: Fri, 07 Feb 97 08:54:31 -0400
-Reply-To: "Rocco Caputo" <troc@shadow.net>
-Priority: Normal
-Subject: polytheistic perl references
-Resent-Message-ID: <"1y3hHB.A.w5C.sTz-y"@sinistar>
-Resent-From: perl5-porters@perl.org
-X-Mailing-List: <perl5-porters@perl.org> archive/latest/136
-X-Loop: perl5-porters@perl.org
-Precedence: list
-Resent-Sender: perl5-porters-request@perl.org
-Content-Type: text
-Content-Length: 1502
-Status:
-
-On Thu, 06 Feb 1997 12:52:56 +0000, Felix Gallo wrote:
-
->Felix's Perl-related Metaproblems:
->
->3. Perl references are monotheistic. One fancies that saying
->$x = \{ http://perl.com/myperlobject }; would do the right thing,
->but the established structure of Perl seems to make this difficult.
-
-There are tied hash packages that implement object naming
-and message passing between named objects within the same
-process. The packages allow invocations like:
-
- $msg{'desktop,paint'} = 1;
- $msg{'name entry,value'} = 'J. K. Cohen';
- $active_flag = $msg{'active checkbox,value'};
-
-The packages also do broadcasting to subsets of the object
-dictionary. Hash stores and fetches are sent to or taken
-from all the objects that match the supplied name. So to
-clear the value of all objects that have 'entry' in their
-names:
-
- $msg{'entry,value'} = '';
-
-That clears 'name entry' and 'age entry' and 'salary entry'
-and ....
-
-Anyway, the names could be extended to work across sockets
-in the presence of a standard select/event loop:
-
- $gnats_queue = $msg{'//somewhere.com:4242/stickynote/gnat?count'};
- print "gnat has $gnats_queue unread sticky notes.\n";
-
- $message = 'hello, world!';
- $msg{'//somewhere.org:4242/stickynote/merlyn?queue'} = $message;
-
-Man pages for ObjDict::Names and ObjDict::Messages are
-on-line at <http://www.nexi.com/troc>. The code is inside
-a larger package, Serv+Face, at
-<http://www.shadow.net/~troc/perlstuff.html>.
-
-Just some ideas to ponder.
-
-Rocco
-<troc@shadow.net>
-
--------------------------------------------------------------------------------
-
-This is a header from a program I was writing before I discovered Perl.
-
-// =========================================================================
-// UBERSYS.H
-// UberSys definitions and classes.
-// =========================================================================
-
-#include <io.h>
-#include <dir.h>
-#include <dos.h>
-#include <math.h>
-#include <time.h>
-#include <alloc.h>
-#include <conio.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <share.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <values.h>
-#include <fstream.h>
-#include <iomanip.h>
-#include <iostream.h>
-#include <sys\stat.h>
-
-// -------------------------------------------------------------------------
-// Constants, limits, and the like.
-
-#define SIZE_UID 9 // including NULL terminator
-#define SIZE_PWD 26 // including NULL terminator
-#define SIZE_MAXSTR 0x1000 // 4k string sizes (max)
-#define SIZE_MAXPATH 0x0050 // 160 chars for max path
-#define SIZE_MAXLINE 0x00A0 // 160 characters per line
-#define COUNT_LINES 0x0200 // 512 editor lines
-
-#define USREV 0x0200 // version 02.00
-
-#define DRV "D:" // drive it runs on
-
-// -------------------------------------------------------------------------
-// Helper macros.
- // build a 20-bit address from segoff
-#define A20(x) (((ULI)FP_SEG(x)<<4)+(ULI)FP_OFF(x))
- // make a normalized pointer from A20
-#define A32(x) MK_FP((UINT)((x)>>4), (UINT)((x)&0x0F))
- // normalize a far pointer using A20
-#define NORM(x) A32(A20(x))
- // maximum of two values
-template <class T>
-T max(T x, T y)
-{
- return((x>y)?x:y);
-};
- // minimum of two values
-template <class T>
-T min(T x, T y)
-{
- return((x<y)?x:y);
-};
- // inline assembly shorthand
-#define I asm
-
-#define FATAL fatalerr(thisFile,__LINE__)
-#define FATALH(x) fatalerr(x,__LINE__)
-
-#if defined(DEBUG)
-# define ERRS if(errorstream)*errorstream<<setiosflags(ios::uppercase)<<hex
-# define CRV(x) if((x)==RV_FAILURE)FATAL
-# define CNE(x) if((x)==-1)FATAL
-# define CZE(x) if(!(x))FATAL
-# define FLINE ,thisFile,__LINE__
-# define FLINC thisFile,__LINE__
-# define FLINP , char *file, int line
-# define FLINQ char *file, int line
-# define FLINI ,file,line
-# define FLINJ file,line
-# define FLINS thisFile,__LINE__,
-# define FLINT char *file, int line,
-# define FLI dec<<");\t\t// f:"<<setw(12)<<file<<" @ l:"<<setw(4)<<line
-# define BOTH(x) A20(x)<<" ["<<A20(*(x))<<"]"
-# define DEB(x) x
-# define DEB2(x,y) x,y
-# define NEW ERRS<<dec<<"\nCall to new.\t\t\t\t\t// f:"<<setw(12)<<thisFile<<" @ l:"<<setw(4)<<__LINE__;
-# define DEL ERRS<<dec<<"\nCall to delete.\t\t\t\t\t// f:"<<setw(12)<<thisFile<<" @ l:"<<setw(4)<<__LINE__;
-# define WHEREAMI ERRS<<dec<<"\nInside file "<<thisFile<<" @ line "<<__LINE__;
-# define ORPHANS { ERRS<<dec<<"\nOrphan check in "<<thisFile<<" @ line "<<__LINE__<<". "; CRV(aOrphans(FLINC)); }
-# define VALID(dp) CZE(aValid(aHeader(dp)));
-# define DUMP aDump(FLINC);
-#else
-# define ERRS cerr
-# define CRV(x) x
-# define CNE(x) x
-# define FLINE
-# define FLINC
-# define FLINP
-# define FLINQ void
-# define FLINI
-# define FLINJ
-# define FLINS
-# define FLINT
-# define DEB(x)
-# define DEB2(x,y)
-# define NEW
-# define DEL
-# define WHEREAMI
-# define ORPHANS
-# define VALID(dp)
-# define DUMP
-#endif
-
-#define FALSE 0
-#define TRUE (~FALSE)
-
-// -------------------------------------------------------------------------
-
-void fatalerr(char *file, int line);
-
-extern char *buildbuf;
-
-// -------------------------------------------------------------------------
- // Paradox Engine header
-#include "pxengine.h"
- // Error stream if debugging.
-DEB(extern ofstream *errorstream;)
- // Message file header.
-#include "general.h"
- // Type definitions.
-#include "mytypes.h"
- // Database functions.
-#include "pxe.h"
-#include "users.h"
-#include "ipx.h"
- // Code groups.
-#include "pcodes.h"
-#include "gsbl.h"
-#include "arena.h"
-#include "interrup.h"
-#include "port.h"
-#include "msgfile.h"
-#include "task.h"
-#include "tam.h"
-#include "qualpath.h"
-#include "xmm.h"
-#include "var.h"
-#include "safepxi.h"
-#include "template.h"
-#include "token.h"
-#include "stack.h"
-#include "objfile.h"
-#include "ofm.h"
-#include "srcfile.h"
-#include "pmachine.h"
- // BBS modules.
-#include "hangup.h"
-#include "idle.h"
-#include "login.h"
-#include "editor.h"
-#include "cmdline.h"
-#include "console.h"
-#include "dirlist.h"
-#include "compiler.h"
-#include "disasm.h"
-#include "runtime.h"
-
-// -------------------------------------------------------------------------
-
-extern TAM *tam;
-
--------------------------------------------------------------------------------
-
-Light was let be.
View
153 poe/MANIFEST
@@ -1,153 +0,0 @@
-CHANGES
-HISTORY
-lib/POE.pm
-lib/POE/Component.pm
-lib/POE/Component/Client/TCP.pm
-lib/POE/Component/Server/TCP.pm
-lib/POE/Driver.pm
-lib/POE/Driver/SysRW.pm
-lib/POE/Filter.pm
-lib/POE/Filter/Block.pm
-lib/POE/Filter/Grep.pm
-lib/POE/Filter/HTTPD.pm
-lib/POE/Filter/Line.pm
-lib/POE/Filter/Map.pm
-lib/POE/Filter/RecordBlock.pm
-lib/POE/Filter/Reference.pm
-lib/POE/Filter/Stackable.pm
-lib/POE/Filter/Stream.pm
-lib/POE/Kernel.pm
-lib/POE/Loop.pm
-lib/POE/Loop/Event.pm
-lib/POE/Loop/Gtk.pm
-lib/POE/Loop/IO_Poll.pm
-lib/POE/Loop/PerlSignals.pm
-lib/POE/Loop/Select.pm
-lib/POE/Loop/Tk.pm
-lib/POE/Loop/TkActiveState.pm
-lib/POE/Loop/TkCommon.pm
-lib/POE/NFA.pm
-lib/POE/Pipe.pm
-lib/POE/Pipe/OneWay.pm
-lib/POE/Pipe/TwoWay.pm
-lib/POE/Queue.pm
-lib/POE/Queue/Array.pm
-lib/POE/Resource.pm
-lib/POE/Resource/Aliases.pm
-lib/POE/Resource/Events.pm
-lib/POE/Resource/Extrefs.pm
-lib/POE/Resource/FileHandles.pm
-lib/POE/Resource/Sessions.pm
-lib/POE/Resource/SIDs.pm
-lib/POE/Resource/Signals.pm
-lib/POE/Resource/Statistics.pm
-lib/POE/Resources.pm
-lib/POE/Session.pm
-lib/POE/Wheel.pm
-lib/POE/Wheel/Curses.pm
-lib/POE/Wheel/FollowTail.pm
-lib/POE/Wheel/ListenAccept.pm
-lib/POE/Wheel/ReadLine.pm
-lib/POE/Wheel/ReadWrite.pm
-lib/POE/Wheel/Run.pm
-lib/POE/Wheel/SocketFactory.pm
-Makefile.PL
-MANIFEST This list of files
-MANIFEST.SKIP
-META.yml
-mylib/coverage.perl
-mylib/cpan-test.perl
-mylib/Devel/Null.pm
-mylib/events_per_second.pl
-mylib/gen-meta.perl
-mylib/gen-tests.perl
-mylib/Makefile-5004.pm
-mylib/Makefile-5005.pm
-mylib/MyOtherFreezer.pm
-mylib/PoeBuildInfo.pm
-mylib/svn-log.perl
-README
-examples/create.perl
-examples/fakelogin.perl
-examples/forkbomb.perl
-examples/names.perl
-examples/objmaps.perl
-examples/objsessions.perl
-examples/packagesessions.perl
-examples/queue.perl
-examples/README.samples
-examples/selects.perl
-examples/sessions.perl
-examples/signals.perl
-examples/tcp_watermarks.perl
-examples/thrash.perl
-examples/watermarks.perl
-examples/wheels2.perl
-t/00_info.t
-t/10_units/01_pod/01_pod.t
-t/10_units/01_pod/02_pod_coverage.t
-t/10_units/02_pipes/01_base.t
-t/10_units/02_pipes/02_oneway.t
-t/10_units/02_pipes/03_twoway.t
-t/10_units/03_base/01_poe.t
-t/10_units/03_base/03_component.t
-t/10_units/03_base/04_driver.t
-t/10_units/03_base/05_filter.t
-t/10_units/03_base/06_loop.t
-t/10_units/03_base/07_queue.t
-t/10_units/03_base/08_resource.t
-t/10_units/03_base/09_resources.t
-t/10_units/03_base/10_wheel.t
-t/10_units/03_base/11_assert_usage.t
-t/10_units/03_base/12_assert_retval.t
-t/10_units/03_base/13_assert_data.t
-t/10_units/03_base/14_kernel.t
-t/10_units/03_base/15_kernel_internal.t
-t/10_units/03_base/16_explicit_loop.t
-t/10_units/03_base/17_explicit_loop_fail.t
-t/10_units/03_base/18_nfa_usage.t
-t/10_units/04_drivers/01_sysrw.t
-t/10_units/05_filters/01_block.t
-t/10_units/05_filters/02_grep.t
-t/10_units/05_filters/03_http.t
-t/10_units/05_filters/04_line.t
-t/10_units/05_filters/05_map.t
-t/10_units/05_filters/06_recordblock.t
-t/10_units/05_filters/07_reference.t
-t/10_units/05_filters/08_stream.t
-t/10_units/05_filters/50_stackable.t
-t/10_units/05_filters/99_filterchange.t
-t/10_units/05_filters/TestFilter.pm
-t/10_units/06_queues/01_array.t
-t/10_units/07_exceptions/01_normal.t
-t/10_units/07_exceptions/02_turn_off.t
-t/10_units/07_exceptions/03_not_handled.t
-t/20_resources/00_base/aliases.pm
-t/20_resources/00_base/caller_state.pm
-t/20_resources/00_base/events.pm
-t/20_resources/00_base/extrefs.pm
-t/20_resources/00_base/extrefs_gc.pm
-t/20_resources/00_base/filehandles.pm
-t/20_resources/00_base/sessions.pm
-t/20_resources/00_base/sids.pm
-t/20_resources/00_base/signals.pm
-t/20_resources/00_base/statistics.pm
-t/90_regression/agaran-filter-httpd.t
-t/90_regression/averell-callback-ret.t
-t/90_regression/bingos-followtail.t
-t/90_regression/broeren-win32-nbio.t
-t/90_regression/cfedde-filter-httpd.t
-t/90_regression/ferrari-server-unix.t
-t/90_regression/neyuki_detach.t
-t/90_regression/rt14444-arg1.t
-t/90_regression/rt1648-tied-stderr.t
-t/90_regression/rt19908-merlyn-stop.t
-t/90_regression/rt23181-sigchld-rc.t
-t/90_regression/rt47966-sigchld.t
-t/90_regression/somni-poco-server-tcp.t
-t/90_regression/steinert-passed-wheel.t
-t/90_regression/suzman_windows.t
-t/90_regression/ton-stop-corruption.t
-t/90_regression/whelan-dieprop.t
-t/90_regression/whjackson-followtail.t
-TODO
View
30 poe/MANIFEST.SKIP
@@ -1,30 +0,0 @@
-CVS
-\.\#
-\.bak$
-\.cvsignore
-\.gz$
-\.orig$
-\.patch$
-\.ppd$
-\.rej$
-\.rej$
-\.svn
-\.swo$
-\.swp$
-^Makefile$
-^Makefile\.old$
-^POE.ppd$
-^\.
-^_Inline
-^_build
-^blib/
-^comptest
-^cover_db
-^coverage\.report$
-^docs
-^pm_to_blib$
-^poe_report\.xml$
-run_network_tests
-test-output\.err$
-t/[23]0_.*\.t
-~$
View
78 poe/Makefile.PL
@@ -1,78 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use ExtUtils::MakeMaker;
-use Config;
-
-# Switch to default behavior if STDIN isn't a tty.
-
-unless (-t STDIN) {
- warn(
- "\n",
- "=============================================\n\n",
- "STDIN is not a terminal. Assuming --default.\n\n",
- "=============================================\n\n",
- );
- push @ARGV, "--default";
-}
-
-# Remind the user she can use --default.
-
-unless (grep /^--default$/, @ARGV) {
- warn(
- "\n",
- "=============================================\n\n",
- "Prompts may be bypassed by running:\n",
- " $^X $0 --default\n\n",
- "=============================================\n\n",
- );
-}
-
-# Should we skip the network tests?
-
-my $prompt = (
- "Some of POE's tests require a functional network.\n" .
- "You can skip these tests if you'd like.\n\n" .
- "Would you like to skip the network tests?"
-);
-
-my $ret = "n";
-if (grep /^--default$/, @ARGV) {
- print $prompt, " [$ret] $ret\n\n";
-}
-else {
- $ret = prompt($prompt, "n");
-}
-
-my $marker = 'run_network_tests';
-unlink $marker;
-unless ($ret =~ /^Y$/i) {
- open(TOUCH,"+>$marker") and close TOUCH;
-}
-
-print "\n";
-
-# Which kind of makefile should we build?
-
-if ($] < 5.005004) {
- warn(
- "\n",
- "===============================================================\n",
- "\n",
- "Please upgrade Perl to avoid lapses in support. Perl 5.005_04\n",
- "or newer is preferred. Support for older versions will be\n",
- "phased out in the future.\n",
- "\n",
- "Thank you.\n",
- "\n",
- "===============================================================\n",
- "\n",
- );
-
- require "./mylib/Makefile-5004.pm";
-}
-else {
- require "./mylib/Makefile-5005.pm";
-}
-
-1;
View
94 poe/README
@@ -1,94 +0,0 @@
-$Id$
-
---------------------
-Detailed Information
---------------------
-
-POE is bigger than this README. Please see http://poe.perl.org/ for
-more information.
-
----------------------
-Documentation Roadmap
----------------------
-
-POE includes a lot of documentation. The main POE man page includes
-references to everything else.
-
-POE has been around for a while. The CHANGES file has been limited to
-changes in the past year to help keep the distribution size down.
-POE's web site includes a complete change history broken down by
-release.
-
---------------
-Installing POE
---------------
-
-POE can be installed through the CPAN or CPANPLUS shell in the usual
-manner.
-
- % perl -MCPAN -e shell
- cpan> install POE
-
-Or
-
- % cpan -i POE
-
-http://poe.perl.org/?Where_to_Get_POE explains other options for
-obtaining POE, including anonymous Subversion access.
-
-------------
-Test Results
-------------
-
-The CPAN Testers are a group of volunteers who test new CPAN
-distributions on a number of platforms. You can see their test
-results at: http://testers.cpan.org/search?request=dist&dist=POE
-
-POE's ongoing improvement relies on your feedback. You file bug
-reports, feature requests, and even success stories by e-mailing
-<bug-POE@rt.cpan.org>.
-
--------------
-Test Coverage
--------------
-
-POE's tests cover a significant portion of the distribution. A
-thumbnail sketch of POE's test coverage is available, but do not use
-it as an accurate gauge of quality.
-
- http://poe.perl.org/?POE%27s_test_coverage_report
-
------------
-What POE Is
------------
-
-POE is an event-driven networking and multitasking framework for Perl.
-It has been in active development since 1996, with its first open
-release in 1998. O'Reilly's "The Perl Conference" (now OSCON's Perl
-track) named POE "Best New Module" in 1999.
-
-POE has been used in mission-critical systems such as internetworked
-financial markets, file systems, commerce and application servers. It
-has been used in projects ranging from a few lines of code to tens of
-thousands.
-
-POE is compatible with perl versions as old as 5.005_03. This may
-change as it becomes harder to support old versions of Perl over time.
-
-POE includes an evolving component framework. Components are
-high-level, modular, reusable pieces of programs. Several components
-have been published on the CPAN, and more are listed on POE's web
-site. See: http://search.cpan.org/search?query=POE&mode=dist
-
-POE includes components and libraries for making quick work of network
-clients, servers, and peers. A simple stand-alone web application
-takes about 30 lines of code, most of which is your own custom logic.
-
-----
-Bye!
-----
-
-Thanks for reading!
-
---
-Rocco Caputo / rcaputo@cpan.org / http://poe.perl.org/
View
20 poe/TODO
@@ -1,20 +0,0 @@
-$Id$
-
-------------------
-Where Did This Go?
-------------------
-
-The contents of this file have moved to the 'web. You can find them
-at <http://poe.perl.org/?POE_RFCs>.
-
-POE's web site is live editable by nearly everyone. Readers can
-quickly patch errors or omissions on the site rather than wait for
-their comments to percolate through e-mail and a maintainer's
-schedule.
-
-Please see <http://poe.perl.org/> for information on acquiring an
-account on the site and setting your editing and viewing preferences.
-
----------------------------
-EOF: Thank you for reading.
----------------------------
View
17 poe/docs/Makefile
@@ -1,17 +0,0 @@
-#
-## Build POD docs from emacs outlines.
-## $Id$
-
-all: ../POE.pod ../POE-TODO.pod ../POE-HINTS.pod
-
-../POE.pod: ./POE.outline
- ./out-out.perl pod ./POE.outline > ../POE.pod
- ./out-out.perl html ./POE.outline > ../POE.html
-
-../POE-TODO.pod: ./POE-TODO.outline
- ./out-out.perl pod ./POE-TODO.outline > ../POE-TODO.pod
- ./out-out.perl html ./POE-TODO.outline > ../POE-TODO.html
-
-../POE-HINTS.pod: ./POE-HINTS.outline
- ./out-out.perl pod ./POE-HINTS.outline > ../POE-HINTS.pod
- ./out-out.perl html ./POE-HINTS.outline > ../POE-HINTS.html
View
55 poe/docs/POE-HINTS.outline
@@ -1,55 +0,0 @@
-*NAME #� -*- outline -*- �
-POE-HINTS - POE Hints
-*DESCRIPTION
-These are hints for using POE. It's sort of like a faq, only without
-the questions.
-
-**Events and Things
-Events and event-like things can be confusing. Here are some gotchas
-people have noted.
-
-***Event Names vs. Code References
-The difference between code references and event names may at first be
-confusing. There have been reports of people trying to use them
-interchangeably, causing lots of mental pain when it doesn't work.
-
-Just about the only time a code reference is needed is when states are
-defined. After that, states should almost always be referenced by
-event name.
-
-Uh, this doesn't sound very convincing. I should probably go into it
-in a little more detail in the next revision.
-**Session Resources
-Session resources are things that the session and/or kernel manage
-with high-level functions. These include alarms, selects and aliases.
-
-Wheels are also considered session resources, because they use
-first-order resources internally.
-
-***Notes About Session Resources
-B�Don't cross the streams. It would be bad.�
-
-Session resources are not designed to be manipulated from outside the
-sessions that own them. One session may not set or remove alarms in
-another. Nor may sessions set selects on behalf of others.
-
-In the case of wheels, one session may not directly call another's
-wheel's methods. $some_other_sessions_wheel->put(...) will not work
-as expected. Internally, the wheel will call &Kernel::select_write;
-this turns on/off a write select in the currently active session--
-which is the caller's session.
-
-The workaround for this is to create a "put" state in the wheel
-owner's session and &Kernel::post or &Kernel::call to that state. The
-post or call changes the active session to the wheel owner. The
-&Wheel::put call will then work as expected.
-
-Breaking session encapsulation was not considered during POE's design.
-*AUTHORS
-This document is the result of feedback from POE users. If you have
-questions or comments that aren't covered by this hints file, please
-contact the author. Even better, subscribe to the POE mailing list.
-
-This document is Copyright 1999 Rocco Caputo <troc@netrus.net>. All
-rights reserved. This document is free text; you may redistribute it
-and/or modify it under the same terms as Perl itself.
View
1,856 poe/docs/POE-TODO.outline
@@ -1,1856 +0,0 @@
-* NAME #� -*- outline -*- �
-
-POE-TODO - To-Do List for POE
-
-* DESCRIPTION
-
-Random requests, suggestions and ideas.
-
-People who want to implement something for POE should check the latest
-version of this list (to see if anyone has claimed it already), and
-let Rocco know (so they can be added to the list).
-
-Also see the POE mailing list, which tends to be pretty quiet.
-
-* PROBLEMS
-
-** Infinite Loops
-
-The real world has multiple inconsistent event loops, all blocking.
-POE's loop cannot coexist with the others.
-
-Tk and POE could be made to half-cooperate by breaking POE's event
-loop open and allowing polled mode. POE would register a
-Tk_DoWhenIdle callback, and some other ugliness.
-
-** Blocking
-
-Blocking procedural code is useful, even in an event driven world.
-How to say:
-
- $line = readline($term);
-
-* MAJOR RESTRUCTURING
-
-I'm considering moving things around in a Big Way.
-
-** New Interface
-
-*** POE::Kernel
-
-In version 0.07, POE::Kernel holds the event queue and manages
-resources that it uses.
-
-The current Kernel's main responsibility is to manage resources.
-Sessions are resources, along with selects, alarms, aliases, signals
-and other things. The current Kernel also holds POE's event loop.
-
-As more people use POE, the desire to use it for other purposes
-increases. POE's Kernel, however, was designed for a particular task
-and is too rigid to be used for some things.
-
-There are two main problems with the current kernel. First, the
-functions that make its programmer interface are too rigid. It's
-really hard to change them, or to add new functions, because the
-Kernel class is a monolith. Second, its event queue is hard-coded, so
-it's really difficult to cooperate with something like Tk.
-
-So first, let's make POE::Kernel a generic resource manager:
-
- package POE::Kernel;
- use strict;
-
- my @resources;
- my @sessions;
-
- sub RES_NAME () { 0 }
- sub RES_FLAGS () { 1 }
- sub RES_RECORD () { 2 }
-
- # Allocate a resource. That is, let the Kernel know it should
- # manage the "session uses resource" association for this resource.
- # It is up to the resource to manage the "resource is used by
- # session" association.
-
- sub resource_alloc {
- my $resource_name = shift;
- # -><- lock @resources here
- push @resources, [ $resource_name, \@_, {} ];
- my $new_resource_id = @resources;
- # -><- unlock @resources here
- my $resource_record = $resources[$new_resource_id]->[RES_RECORD];
- $resources{$resource_record} = $new_resource_id;
- ( 'resource allocated okay', # status
- $new_resource_id, # resource index
- $resources[$new_resource_id]->[RES_RECORD] # resource record
- );
- }
-
- # Free a resource. This occurs when the program ends. It ensures
- # that session destructors have already cleaned up the references
- # for each managed resources.
-
- sub resource_free {
- my ($resource_id) = @_;
- my $resource = $resources[$resource_id];
-
- if (keys %{$resource->[RES_RECORD]}) {
- carp "leak in $resource->[RES_RECORD]->[RES_NAME] resource";
- }
-
- # -><- lock @resources here
- $resources[$resource_id] = undef;
- # -><- unlock @resources here
- }
-
- # Register a resource instance. This lets the kernel know that a
- # particular session uses a specific resource.
-
- sub resource_associate {
- my ($resource_id, $resource
-
-**** POE::Resource::Select
-
-The Select resource is somewhat equivalent to the current Kernel's
-select_* functions, but it has different semantics as a "resource"
-instead of a "function library".
-
- package POE::Resource::Select;
-
- use strict;
- use POE::Kernel;
-
- my $resource_serial = 0;
- my $resource_record = undef;
-
- ($status, $resource_record) = &POE::Kernel::resource_alloc( RES_SELECT );
- die $status unless (defined $resource_record);
-
- END {
- # test $resource_record for leaks
- }
-
- sub new {
- my ($package, %params) = @_;
- my $current_session = &stupid_caller_trick();
- my $self = $resource_serial++;
- $self = bless \$self, $package;
- &POE::Kernel::session_use($current_session, $self);
- $resource_record->{$self} = [ $current_session ];
- }
-
- sub DESTROY {
- my $self = shift;
- &POE::Kernel::session_free($self);
- delete $resource_record{$self};
- }
-
- package main;
-
- use POE;
- use POE::Resource::Select;
-
- sub state_start {
- $id = new POE::Resource::Select(
- Handle => $handle,
- ReadState => $read_state,
- WriteState => $write_state,
- ExpediteState => $expedite_state,
- );
- }
-
- $id->state( Read => undef, # Undef turns it off.
- Write => '', # '' turns it on, using last state
- Expedite => $new_state # scalar changes the state
- );
-
-
-
-**** POE::Kernel as Resource Manager
-
- package POE::Kernel;
-
- @resources;
-
-
-**** POE::K
-
-** Current Interface
-
-*** POE::Kernel
-
-The program's event loop and resource management stuff.
-
- $k = new POE::Kernel();
-
- $k->sig($signal, $state);
- $k->signal($session, $signal);
-
- $k->run();
-
- $k->post($session, $state, @etc);
- $k->yield($state, @etc);
- $k->call($session, $state, @etc);
-
- $k->alarm($state, $time, @etc);
- $k->delay($state, $delay, @etc);
-
- $k->select($handle, $state_r, $state_w, $state_e);
- $k->select_read($handle, $state);
- $k->select_write($handle, $state);
- $k->select_expedite($handle, $state);
-
- $k->alias_set($name);
- $k->alias_remove($name);
- $k->alias_resolve($name);
-
- $k->state($state, $code);
-
-*** POE::Session
-
-A unit of execution in POE.
-
- new POE::Session( ... );
- create POE::Session( ... );
-
- $s->option( ... );
-
-*** Sample Usage
-
- use POE;
-
- sub state_start {
- $_[KERNEL]->yield('do_something');
- }
-
- sub state_something {
- print "hello, world!\n";
- }
-
- new POE::Session( _start => \&state_start,
- do_something => \&state_something
- );
-
- $poe_kernel->run();
- exit;
-
-** Proposed Interface (being taken apart for parts)
-
-Live document defining next major step in POE's interface.
-
-*** POE::Session
-
-A unit of execution in POE.
-
- new POE::Session( ... );
- create POE::Session( ... );
- $s->option( ... );
-
-** POE::Queue
-
-A pure virtual class that defines a generic queue interface.
-
- $q = new POE::Queue::???( ... );
- $q->post($session, $state, @etc);
-
-*** POE::Queue::Select
-
-A select-based queue. Follows the POE::Queue interface.
-
-*** POE::Queue::Event
-
-An Event-based queue. Follows the POE::Queue interface.
-
-*** POE::Queue::Tk
-
-A Tk-based queue. Follows the POE::Queue interface.
-
-** POE::Alarm
-
-Alarm resources.
-
- my $alarm = new POE::Alarm($time, $event, @etc);
- $alarm->adjust($seconds_to_adjust);
- $alarm->set($new_absolute_time);
- undef $alarm;
- my $alarm = new POE::Delay($seconds, $event, @etc);
-
-** POE::Delay
-
-Delay resources.
-
- my $delay = new POE::Delay($seconds, $event, @etc);
- $delay->adjust($seconds_to_adjust);
- $delay->reset($seconds_from_now);
-
-
-** POE::Select
-
-Select resources.
-
-** POE::Alias
-
-Alias resources.
-
-* TUTORIALS, PAPERS AND OTHER DOCUMENTATION
-
-** Tutorials
-
-POE can be difficult for people to pick up, especially if they're not
-familiar with Perl references and objects. A "gradual" introduction
-to state machines and POE is half written. It discusses things
-through Kernel and Session, but it doesn't go into Wheels or the
-Object Layer yet.
-
-Freeside suggests:
-
- "here's an event-driven application domain."
- "here's how people usually do it with select(,,,)."
- "here's how you might want to do it in POE."
- "here are some other cool things POE makes easy."
-
-** Papers
-
-*** Coroutines
-
-It is possible to model coroutines in POE. Coroutines are a hot
-topic, and this would make a nice paper topic.
-
-*** Call With Current Continuation (callcc)
-
-Likewise, it was once lamented that Perl has no callcc (call with
-current continuation) function. POE can simulate callcc, which in
-turn can simulate coroutines, threads, and all sorts of things.
-
-** Other Documentation
-
-Crimson suggested that I write a book about POE, using the PCB Q&A
-format. Maybe when POE's design settles down?
-
-Golly, I *hope*, POE's design settles down.
-
-* SUPPORT OTHER SYSTEMS
-
-POE uses a lot of POSIX to be portable, but some systems don't seem to
-be POSIX enough.
-
-** MacOS support
-
-I contacted someone about this on Pudge's recommendation, but they
-never returned my e-mail. As far as I can tell, MacOS support is
-stillborn. If anyone would like to pick this up, let me know. It's
-all POSIX-y inside, so how hard could it be?
-
-** Win32 support
-
-Sean Puckett started work on a Win32 port then switched to Linux. Now
-he's gone missing. If anyone would like to pick this up, let me know.
-
-* PROGRAMS USING POE
-
-** tail + grep
-
-Someone (I've forgotten who) wants a program that combines the
-features of /usr/bin/grep and /usr/bin/tail.
-
-** POE::Simple
-
-Philip Gwyn would like to see a POE::Simple::(Client|Server|Proxy)
-that combines a lot of default behavior into an extremely-high-level
-module for writing quick network programs.
-
-He says, "Contrast LWP::Simple with the other modules." Fair enough.
-
-* DEVELOPMENT METHODOLOGY CHANGES
-
-** CVS
-
-Development is now running out of a local CVS repository. It's on my
-dialed-up machine, so the address changes all the time.
-
-The next step is to open the CVS server for anonymous updates,
-possibly moving it somewhere that doesn't move around all the time.
-
-After anonymous updates are working for a while, it should be okay to
-start giving authorship rights to some of the more dedicated POE
-kernel hackers.
-
-** Event
-
-Event.pm is destined to become Perl's standard event queue. POE
-should probably cooperate with or use it at some point.
-
-While I've heard that Event cooperates with Tk, there doesn't seem to
-be anything in the source or documentation about this. Perhaps Tk
-will use it if it's present?
-
-Event is supposed to make perl's signals safe. If true, that's a big
-win.
-
-Event has multiple queues and priorities. That could be useful.
-
-Event has a C API. While it's subject to incompatible changes every
-time Event or perl is upgraded, it's supposed to be faster than the
-Perl API. No wonder, there's one less level of indirection.
-
-Migration to Event. It may be better to wait for Event to reach 1.00
-before going ahead with this, but it's good to keep in mind.
-
-*** Wrap Event's C API
-
-Some of the Event things don't work the way I'd like. Function calls
-are slow, so fetching event attributes with them is extra overhead.
-Passing them to states as another parameter (array reference) and
-accessing them with offset constants might be faster.
-
-*** Replace POE::Kernel Event Guts
-
-This will lighten POE a lot, at the expense of requiring a bundle of
-modules including some C. Plus POE will have XS to interface Event's,
-and then POE may be incompatibly outdated whenever perl or Event
-changes. Blargh.
-
-** Namespaces
-
-*** Components
-
-Artur suggested reservinig a slice of the POE namespace for
-contributed and third-party modules. This slice eventually became the
-POE::Component namespace.
-
-POE::Component things should be stand-alone daemon-able sessions that
-talk via call/post to some public states. These would be "black box"
-sessions, like Visual Age or Digital Smalltalk "parts", or Java
-"beans". See POE::Component::IRC, for example.
-
-Sean Puckett suggests that POE::Components have some facility for
-other sessions to query and grok their public interfaces. This would
-be similar to CORBA, COM or SOM objects. Sounds neat; I hope it's
-doable. See the CORBA notes.
-
-*** Stand-Alone Programs
-
-Stand-alone programs (or "applications" or "apps" as they're called in
-some circles) don't need a special namespace. If someone wants to
-write a whole program as an object, and have meta-programs manipulate
-things through an object interface, and they really need the object's
-package to starte with POE, then they can use POE::App.
-
-For example, uh, POE::App::Poepopper would be a POP3 daemon
-implemented as an object, with some public methods to tweak its
-configuration.
-
-This is not a recommendation.
-
-*** Core Contributions
-
-Filters, Drivers, Wheels and whatever. Where do they go? As long as
-there are corresponding test programs, I can absorb them into POE's
-core distribution. Big ones may need to stay separate.
-
-With CVS fully implemented, people could maintain their bits in the
-core. That could be real nice, except that huge, monolithic
-distributions tend to suck.
-
-* DESIGN CONSIDERATIONS
-
-** Minor Interface Nits
-
-Some functions only check for undef. These should really check for
-undef or @_==1, since the second parameter may be missing.
-
-If a wheel has no ErrorState, the default behavior should be to issue
-a warning with $!.
-
-Consolidate FailureState and ErrorState, so people don't have to
-remember when to use one or the other.
-
-Add 'DEFAULT' and 'IGNORE' as special event handlers for
-POE::Kernel::sig().
-
-Make the Session::option(default) value mean things. ($value & 1)
-would determine whether POE displaed internal events; ($value & 2)
-would determine if dropped user events were displayed.
-
-** Major Nits
-
-It's becoming unfun to run samples/*.perl before each release. POE
-badly needs some sort of automated test suite.
-
-SocketFactory doesn't support connectionless sockets.
-
-Wheels need to be able to stack things.
-
-Swapping wheels requires that old ones be deleted before new ones are
-created, otherwise selects are cleared improperly. This is bad, I
-don't like it, and I don't have time to fix it right now. Grrrr!
-
-** Cascaded States
-
-Cherem <joeo@suninternet.com> wants this for NIRC.
-
-I think building a cascading mechanism can be useful for non-POE
-programs, so building it into POE would limit its use. Since POE
-states are just Perl subs, the mechanism should focus on cascading
-subs instead of states.
-
-As I interpret cascading, it is the ability to call a sequence of subs
-to handle a single call. Each sub in the sequence can decide whether
-or not co continue the cascade to the next sub. Here are a couple
-cascading sub examples to start things:
-
- sub user_kick {
- &do_cascade(@_) if ($needs_to_cascade_before_work);
- # ... do some work ...
- &do_cascade(@_) if ($needs_to_cascade_amidst_work);
- # ... do more work ...
- &do_cascade(@_) if ($needs_to_cascade_after_work);
- }
-
- sub user_join {
- # ... do some work ...
- &stop_cascade() if ($this_should_be_the_last_state_called);
- # ... do some work ...
- }
-
-The cascader continues the sequence of subs by default. However,
-&do_cascade() and &stop_cascade() will set a flag indicating that the
-current sub has already cascaded. This will prevent the cascader from
-calling the next sub once the current one returns.
-
-Now for cascader instantiation:
-
- my $cascader = new Cascader(
- kick => [ \&default_kick ],
- join => [ \&default_join ],
- );
-
-The cascader uses AUTOLOAD to resolve cascades from their names. For
-example, $cascader->kick() is mapped to the 'kick' sequence through
-AUTOLOAD. Manipulating the Cascader package's symbol table is not
-recommended, because the symbol table is shared among all instances.
-
-Cascader lists can be manipulated with push and pop methods. To add a
-new sub to the 'kick' cascade:
-
- $cascader->push( 'kick', \&user_kick );
-
-To remove the last pushed sub:
-
- $cascader->pop( 'kick' );
-
-Push would allow multiple subs. If one of the subs is \&stop_cascade,
-then the cascade is stopped unconditionally at that point:
-
- $cascader->push( 'join', \&user_join, \&stop_cascade );
-
-And finally, integration with POE via object states:
-
- new POE::Session( _start => \&state_start,
- $cascader => [ 'kick', 'join' ]
- );
-
-The 'kick' event will go to $cascader->kick(), and 'join' is sent to
-$cascader->join(). AUTOLOAD fires off the proper cascade for each
-meta-method.
-
-This has evolved out of the scope of POE proper, and so I've delegated
-any further work to Cherem.
-
-** Reorganize Wheels
-
-I think the Wheels abstraction should be reorganized into a new
-taxonomy:
-
-*** Stream
-
-Streams are read and written in whatever chunks they receive.
-POE::Filter::Lecks would probably exist here.
-
-*** Block
-
-Blocks would be subdivided:
-
-**** Separated
-
-Blocks that are identified by separators. POE::Filter::Line goes
-here.
-
-**** Enumerated
-
-Blocks that are identified by length. This includes fixed-width
-records and variable-width records that begin with a length marker.
-POE::Filter::Reference belongs here.
-
-*** Form
-
-Forms are read/written as anonymous hashrefs:
-
- { Headers => { $header_1 => $value_1,
- $header_2 => $value_2,
- ...
- },
- Fields => { $field_1 => $value_1,
- $field_2 => $value_2,
- ...
- },
- }
-
-It would be up to the specific Form filters to figure out a way to
-render forms. Perhaps one of the Headers could contain meta-layout
-information.
-
-POE::Filter::HTTPD goes here. As would a new filter for screen
-widgets. The nice thing about this scheme is that sessions wouldn't
-need to know what sort of form interface they're using. It could be
-Tk widgets, Face widgets or CGI.
-
-** Self-Knowledgeable Components
-
-Fairytale stuff. It's here so I don't forget it.
-
-What if the Filter::Reference is chained off Filter::Line instead of
-Filter::Block?
-
-The "chaining" could be made internal to Filter::Reference, so it
-automagically brings in Filter::Block. That would prevent people from
-chaining incompatible filters together, but it would limit their
-flexibility.
-
-Or components (wheels, filters and drivers) could be made aware of the
-other components they're working with. That would give them an
-opportunity to verify that they're working with compatible components.
-It might also allow components to alter their default behaviors. For
-example, Filter::Reference might make sure to escape/unescape newline
-characters if it's working with a Filter::Line. It might even go so
-far as to query the Filter::Line about the newline characters it needs
-to escape.
-
-** Tie %SIG
-
-Tom Christiansen says it's bad news to tie %SIG, but he didn't explain
-it. I'll have to try it at least once to see why.
-
-Assume tied %SIG is bad. Make it %SIGNAL instead.
-
-Storing to %SIGNAL would seem to work exactly like Perl's %SIG does
-now. Internally, it would either register the state name or create a
-state for the coderef being stored. For example:
-
- $SIGNAL{HUP} = \&sighup_state;
- $SIGNAL{HUP} = 'sighup_state';
-
-And 'DEFAULT' and 'IGNORE' would do the right things, too.
-
-** Fix Signals
-
-Write an XS that polls signals in the relative safety of C. Use POSIX
-signal functions to block signals until a critical section of C code.
-Unblock them there, and the signals should hit in the C code. That'll
-prevent them from corrupting perl, I hope.
-
-SIGPIPE can be faked. Block it entirely, and simulate it when a file
-operation catches EPIPE. No OS signals involved, and wheels can post
-signals to the appropriate sessions-- even in Concurrent POE with
-multiple kernels.
-
-SIGCH?LD can be faked. Use SysV semaphores, SysV shared memory, pipes
-or sockets. Lock files, maybe. Or perhaps poll for children instead
-of waiting for the signal, as Sean Puckett suggests.
-
-** Fix Alarm Semantics
-
-There are three ways this could go:
-
-*** New Kernel Functions
-
-Depreciate &Kernel::alarm and &Kernel::delay. Add these functions to
-replace them:
-
- $alarm_id = $kernel->alarm_set($time, $event, @etc);
- $kernel->alarm_adjust($alarm_id, $seconds_to_adjust);
- $kernel->alarm_remove($alarm_id);
- $alarm_id = $kernel->delay_set($seconds, $event, @etc);
-
-*** New Session Functions
-
-Alarms should really belong to sessions. What if the Kernel is only
-used indirectly? For that matter, what if all Session resources are
-manipulated with Session methods?
-
- $alarm_id = $session->alarm_set($time, $event, @etc);
- $session->alarm_adjust($alarm_id, $seconds_to_adjust);
- $session->alarm_remove($alarm_id);
- $alarm_id = $session->delay_set($seconds, $event, @etc);
-
-*** Resource Classes
-
-I'm preferring resource classes more and more. Rather than manipulate
-resources with Kernel or Session methods, create them as their own
-objects:
-
- my $alarm = new POE::Alarm($time, $event, @etc);
- $alarm->adjust($seconds_to_adjust);
- undef $alarm; # Calls DESTROY, which replaces alarm_remove()
- my $alarm = new POE::Delay($seconds, $event, @etc);
-
-Resources would be proxy objects: blessed scalars containing the
-resource ID. Their object methods would call the appropriate Kernel
-or Session functions to actually manipulate things. Only the resource
-creator would have a reference to the object.
-
-** Break Session Encapsulation
-
-There is a growing need to manipulate remote sessions with
-Kernel::signal(), ::alarm(), and :state(). This seems to break the
-barriers between sessions in uncomfortable ways, but it appears to
-have its uses.
-
-While I can't justify remote signal() and state(), remote alarm() is
-harmless enough. But who gets the $alarm_id when the alarm semantics
-change?
-
-** Daemonify a Process
-
-Add a Kernel function to make the whole process go daemon. From
-_Advanced Programming in the UNIX Environment_ by W. Richard Stevens:
-
- fork() && exit;
- setsid();
- chdir('/');
- umask(0);
- close(STDIN); close(STDOUT); close(STDERR); # if necessary
-
-** "Morphing" SocketFactory
-
-SocketFactory is dead weight after it's made a connection, and its
-socket is useless while it's trying to make the connection. Randal
-Schwartz suggests a SocketFactory::put() method that queues data and
-delivers it to the socket when it finally connects.
-
-A (UNIX) streams-based approach would handle this nicely. In the
-meantime, two other ideas have been considered:
-
-*** Morphing SocketFactory: First Sortie
-
-After some debate, the idea evolved into a SocketFactory that can
-"morph" into another wheel after it successfully connects.
-Furthermore, it was suggested that an option to automatically retry
-connections might be useful.
-
-Since most of the work is done in the SocketFactory constructor, here
-is a sample of what such a beast might look like:
-
- new POE::Wheel::SocketFactory
- # regular SocketFactory things
- ( SocketDomain => AF_INET,
- SocketType => SOCK_STREAM,
- SocketProtocol => 'tcp',
- RemoteAddress => $remote_address,
- RemotePort => $remote_port,
- FailureState => 'io_error',
- # here's where it gets strange
- MorphInto => 'Wheel::ReadWrite',
- MorphParameters => { Driver => new POE::Driver::SysRW,
- Filter => new POE::Filter::Line,
- InputState => 'got_a_line',
- ErrorState => 'io_error',
- },
- );
-
-You sort of need to know what you want to do ahead of time, since
-almost all the work's during initialization. Some folks will find
-this concept very strange.
-
-*** Morphing SocketFactory: Second Sortie
-
-I just like saying "sortie". It comes from long afternoons playing
-Choplifter on the Apple ][. Anyway:
-
-POE::Wheel::SocketFactory would have a put() method, and it would
-enqueue output just like the original idea. However, instead of
-playing with the SocketFactory's blessing with the OO equivalent of
-goto, provide another method (maybe dequeue_to()) that returns the
-queued data as a list. The list would be suitable for feeding back
-into another wheel's put() method.
-
-dequeue_to() might look like this inside:
-
- sub SocketFactory::dequeue_to {
- my ($self, $new_wheel) = @_;
- if (@{$self->{queue}}) {
- $new_wheel->put(@{$self->{queue}});
- $self->{queue} = [];
- }
- $new_wheel;
- }
-
-You would create a new wheel and pass its reference through the
-dequeue_to() function. This would let you create the new wheel,
-dequeue to it, and store it in one statement:
-
- sub SomeSession::connect_handler {
- my $heap = $_[HEAP];
-
- $heap->{wheel} =
- $heap->{wheel}->dequeue_to( new Wheel::ReadWrite( ... ) );
- }
-
-This seems cleaner than playing with the SocketFactory's blessing.
-
-** Kernel Statistics
-
-A function to list active sessions. A function to acquire details
-about a session. A function to acquire the kernel's and OS's load
-averages, uptime, etc.
-
-** Port Face from Serv to POE
-
-Face is a text widgets library using Curses. It's heirarchical, and
-it uses a funky slow tied-hash message passing thing. It would be
-enormously cool to revise this and make it work with POE.
-
-* RESEARCH AND DEVELOPMENT
-
-** KST
-
-Fmh suggests looking at the Knowledge Server Toolkit, at
-<http://lambda.gsfc.nasa.gov/kst/kst.html>. Apparently it is a
-socket-based application for monitor and control.
-
-** Java Application Servers
-
-Fmh says POE needs Java Application Server functionality. There's
-one, with explanation and overview and stuff, at
-<http://www.enhydra.org/>.
-
-** Object System Architecture
-
-Artur Bergman emphatically recommended the book _Object Database
-Development, Concepts and Principles_, by David W. Embley. More
-information about it may be found at
-<http://cseng.awl.com/bookdetail.qry?ISBN=0-201-25829-3&ptype=0>.
-
-<http://osm7.cs.byu.edu/~eric/allegro.html> talks about some of the
-topics in the book. Namely "OSA":
-
- OSA has concepts to formalize just about everything one needs to
- model a real world situation. Although OSA is an "integrated"
- modeling scheme, that is all the parts work together, it can
- conveniently be seen as consisting of three parts: ORM, OBM, and
- OIM.
-
- ORM = Object-Relationship Model; OBM = Object-Behavior Model;
- OIM = Object-Interaction Model
-
-** CORBA
-
-For the life of me, I can't remember who was pushing CORBA. I did
-bookmark some links they gave me:
-
- What CORBA is: <http://www.omg.org/corba/whatiscorba.html>
- Open CORBA: <http://diamant-atm.vsb.cs.uni-frankfurt.de/~mico/>
- Tutorial: <http://www.cs.wustl.edu/~schmidt/tutorials-corba.html>
-
-The one-line descriptions for the CORBA services look like a lot of
-fun. I haven't made time to look at them in detail, though. I'd like
-for the Object Layer to have CORBA capability, if it's possible.
-Perhaps something clever could be done to make certain objects
-automagically CORBA-compatible.
-
-** Serial and Terminal Device
-
-This amounts to creating pre-conditioned filehandles that the regular
-select logic can deal with. The code is mostly written already; it
-just needs to be cleaned up and made available.
-
-Stacked filters would encompass this quite easily.
-
-** State Transition Tables
-
-Crimson would like to see predefined state transition tables. It
-would seem that just adding a transition table to a session isn't
-saving much (if any) effort, because the code already knows the
-current state, new condition, and desired new state wherever post() is
-used.
-
-So, what if there was a wheel to do yacc-like things? Here's a
-preliminary design:
-
- my $yacker = new POE::Wheel::Yack
- ( $reduction_state_1 => [ [ $token_1, $token_2, $token_3 ],
- [ $token_1, $token_2 ],
- [ $token_1 ]
- ],
- $reduction_state_2 => [ [ $token_4, $token_5 ],
- [ $token_4 ]
- ],
- $reduction_state_3 => [ undef ], # undef signifies end of input
- );
-
- $yacker->shift($token_1);
- $yacker->shift($token_2);
- $yacker->shift($token_4);
- # Before $yacker shifts $token_4, it first reduces $token_1 and
- # $token_2 to:
- # $kernel->yield($reduction_state_1, 2, $token_1, $token_2);
- $yacker->shift(undef);
- # Reduction: $kernel->yield($reduction_state_2, 1, $token_4);
- # Reduction: $kernel->yield($reduction_state_3, 0);
-
-And of course, reduction states can do all sorts of things. They can
-even shift more tokens.
-
-But what good is a Yack wheel without a lexer? So how about allowing
-it to have one?
-
- my $yacker = new POE::Wheel::Yack
- ( ..., # Everything from the previous example
- Lexer => new POE::Wheel::Lecks
- ( Tokens => { $token_1 => [ qr/[a-z][a-z_]/i ],
- $token_2 => [ qq(+ - * /) ],
- $token_3 => [ qr/".*?"/ ],
- $token_4 => [ qq(keyword1 keyword2 keyword3) ],
- $token_5 => [ qr/[\d+]/ ],
- },
- Handle => $filehandle,
- Driver => new POE::Driver::SysRW()
- ),
- );
-
-Thus, the Yack wheel will use a Lecks wheel to read data from a Handle
-and parse it. Perhaps Lecks has some default tokens for data not
-recognized as one of its Tokens.
-
-** UNIX Streams-Like I/O Abstraction
-
-Randal Schwartz doesn't like the Wheels abstraction. His needs don't
-mesh with it, and he has neither the time nor inclination to write his
-own abstraction. He did take the time to look at it and suggest
-things, though.
-
-I like this idea more and more as I think about it.
-
- He needs something that has callbacks when the listen socket is
- bound. The bind callback should let him know what port was actually
- bound to, which is useful in the case of binding to any port (0).
-
- He suggests stream-ish and gram-ish sockets be separate
- Wheel/Driver/Filter groups. I like this and want to add a third
- group: form-ish.
-
- He suggests making filters work like SysV drivers. That is, have a
- low-level socket, then push protocols on top:
-
- Create a raw socket.
- Push "tcp socket with oob" on it.
- Push "line oriented protocol" on it.
- Push "irc client protocol" on it.
-
- Create a raw socket.
- Push "tcp with pre-connect buffer" on it.
- Push "line oriented protocol" on it.
- Push "ftp command channel" on it.
-
- Create a raw tty filehandle.
- Push "cooked mode".
- Push "line oriented".
- Push "irc client".
-
- So the filter-to-filter protocol must be inclusive enough from the
- start to let users write new filters.
-
-This seems to be more evolved than just chaining filters. He suggests
-reading up on "SysV pushed drivers" and "Unix streams". Eventually I
-will.
-
-*** General STREAMS Notes
-
-Streams may be symmetric. That is, put in both directions and no
-service routines. This is because the stream head is event driven,
-instead of blocking and synchronous.
-
-POE::Wheel::ReadWrite is a stream head.
-
-POE::Filter is a stream module.
-
-POE::Driver is a stream end. In some stream implementations, more
-modules can be stacked onto the stream after the end. That's how they
-support multiplexing. I'm not sure this is good.
-
-User calls into the Wheel (stream head) start a chain of calls down
-the stream towards the driver.
-
-Select events start a chain of calls up the stream towards the user.
-
-General usage:
- SocketFactory to create the socket.
- Or open() or whatever to create the file.
- Create a Stream, and give it the file handle.
-
-*** Notes From DIGITAL's Network Programmer's Guide
-
-The URL is:
-<http://www.partner.digital.com/www-swdev/pages/Home/TECH/documents/Digital_UNIX/V4.0/AA-PS2WD-TET1_html/netprog6.html>
-
-**** Module Data Structures
-
-queue init structure
- put routine (takes outgoing data)
- service routine (handles incoming data)
- open routine (called on each open)
- close routine (called on last close)
- information structure
- statistics structure
-
-module info structure
- module id number
- modlue name
- minimum packet size (developer use)
- maximum packet size (developer use)
- high-water mark (flow control)
- low-water mark (flow control)
-
-streamtab structure
- read queue init structure
- write queue init structure
- mux read queue init structure (for mux drivers)
- mux write queue init structure (for mux drivers)
-
-**** Message Data Structures
-
-Data Buffer, containing the message's binary data.
-
-message block:
- data block
- message priority (band)
- message flags
-
-**** Processing Routines for Drivers and modules
-
-Open - Similar to Filter::new
-Close - Similar to Filter::DESTROY
-
-Configuration
-
-Read side put
- Stream ends don't have this, since they receive data from the
- kernel.
-
- Downstream modules call putnext() to send to this.
- Takes pointer to read queue and message pointer.
-
-Write side put
- Called when the upstream module calls putnext().
- Takes pointer to write queue and message pointer.
-
-Read side service
-Write side service
- Service routines pull messages off the read/write queues and
- try to process them. I'm still unclear on this concept.
-
-**** Queue Synchronization
-
-Queue level. One thread can access any instance of the module or
-driver's write queue at the same time another thread is accessing a
-module's read queue. Read and write queues don't share common data
-and don't need to be synchronized.
-
-Queue pair. Read and write queues share data. Only one thread at a
-time can access them together.
-
-Module level synchronization. All code within the module or driver is
-single-threaded.
-
-Elsewhere. Something else is synchronizing things.
-
-Global. All drivers and modules in this synchronization level run in
-the same therad. No concurrency at all.
-
-*** DMR's Streams Paper
-
-A Stream Input-Output System, by Dennis M. Ritchie:
-<http://cm.bell-labs.com/cm/cs/who/dmr/st.html>
-
-**** Overview
-
-Streams overview.
-
-***** Streams
-
-Streams are full-duplex connections between a user's process and a
-device or pseudo device. It consists of a strand of modules, similar
-to a shell pipeline, but with data going in both directions. Flow
-control is something exceptional.
-
-On the process end there is a stream head. It provides a programming
-interface to the stream. On the device end is a device driver
-module-- it's not a driver, it's a "driver module". Okay! On the
-driver module end, data is sent to the device. In the receiving
-direction, data and state transitions are composed into messages and
-set towards the user's program.
-
-On open, you get two modules: a head module and a driver module.
-Intermediate modules are attached and dropped dynamically.
-
-***** Queues
-
-Each stream module has a pair of queues, read and write. A stream
-queue is a queue, plus two routines and some status information. One
-routine is the "put procedure" which is called by the neighboring
-module to send data along. The other is the "service procedure" which
-is scheduled to execute whenever there is work to do.
-
- So, put() doesn't immediately cause anything to happen. It merely
- signals the next module in the line to process something when it
- can.
-
-The status information includes a pointer to the next module, some
-flags, and some ntate information. Both queues know about each-other,
-so they can implement "echo" and stuff.
-
-***** Message Blocks
-
-Message blocks are passed between queues. They are obtained from an
-allocator. Each contains a read pointer, a write pointer, and a limit
-pointer. Respectively, they are the beginning, end and growth limit
-of the block's data.
-
-The block header specifies its type. The most common type is data.
-There are also control blocks of various kinds: data delimiters, I/O
-control requests, and special conditions (line break, or carrier
-loss).
-
-Data blocks arrive one at a time. Boundaries between them are
-insignificant. Data blocks may be coalesced; control blocks always
-remain separate.
-
-***** Scheduling
-
-Each queue module behaves like a separate process, but they're not
-real processes. The system saves no state information for a
-non-running queue module. Queue modules don't block when they can't
-continue; they must return control. When queues are enabled, the
-system will (as soon as convenient) call its service procedure. The
-service procedure removes successive blocks from the data queue,
-processes them, and places them on the next queue by calling its put
-procedure. Wher there are no more blocks to process, or when the next
-queue becomes full ,the service procedure returns to the system.
-
-Queue enabling is mostly automatic. Like, when a block is put on the
-queue, it enables like magic.
-
-***** Flow Control
-
-Each queue has a pair of numbers for flow control. A high-water mark
-limits the amount of data that may be outstanding in the queue. By
-convertions, modules don't place data on a queue above the high-water
-limit. A low-water mark is used for scheduling: When a queue has
-exceeded its high-water mark, a flag is set. Then, when the routine
-that takes blocks from a data queue notices this flag is set and that
-the queue has dropped below the low-water mark, the upstream queue is
-enabled.
-
-***** Examples
-
-A newly-opened stream device:
-
- user write ---> | stream device | ---> device out
- user read <--- | | <--- device in
-
-The top-level routines are invoked by users' read and write calls.
-The writer routine sends messages to the device driver on th eright.
-Data arriving from the device is composed of messages sent to the
-top-level reader, which returns the data to the user process when it
-executes read.
-
-Configuration after the device is open:
-
- user wr ---> tty out ---> device out
- user rd <--- tty in <--- device in
-
-An ordinary terminal connected by RS-232. Here a processing module
-(in the middle) is interposed. It performs the services necessary to
-make terminals usable; for example echoing, character-erase and
-line-kill, tab expansion as required, translation between CR and \n.
-It's possible to use one of several terminal handling modules. The
-standard one provides services like those of the Seventh Edition
-system. Another resembles the Berkeley "new tty" driver.
-
-The processing modules in a stream are thought of as a stack whose top
-(shown on the left) is next to the user program. To install the
-terminal processing module after opening a terminal device, the
-program that makes such connections executes a "push" I/O control call
-naming the stream and the desired module. Other primitives pop a
-module and determine the topmost module's name.
-
-Here is a case where terminal processing is staked on a network
-protocol (a network terminal):
-
- user wr --> tty out --> proto out --> device out
- user rd <-- tty in <-- proto in <-- device in
-
-Then there is a common configuration (not illustrated) that's used
-when the network is used for file transfers or other purposes. It
-simply omits the "tty" module and uses only the protocol module.
-
-**** Messages
-
-Most of the messages between modules contain data. The allocator that
-dispenses message blocks takes an argument specifying the smallest
-block its caller is willing to accept. The current allocator
-maintains an inventroy of blocks that are 4, 16, 64 and 1024
-characters long. Modules allocate blocks using a best guess of the
-needed size-- for example, the top level write routine requests 64- or
-1024-character blocks. The network input routine allocates 16-byte
-blocks because that's the data packet size. The smallest blocks are
-used only to carry arguments to control messages.
-
-Besides data blocks, there are also several kinds of control messages.
-
-***** Synchronous Messages
-
-Synchronous messages are queued in the stream, so they occur at the
-appropriate time in the stream.
-
-****** BREAK
-
-Break is generated by a terminal vice on detection of a line break
-signal. The standard terminal input processor turns this message into
-an interrupt request. It may also be sent to a terminal device driver
-to cause it to generate a break on the output line.
-
-****** HANGUP
-
-Generated by a device when its remote connection drops. It also marks
-the stream so further use causes an error.
-
-****** DELIM
-
-This is a data delimiter. Most of the stream I/O is prepared to
-provide true streams, in which record boundaries are insignificant,
-but there are various situations in which it is desirable to delimit
-the data. For example, terminal input is read a line at a time; is
-generated by the terminal input processor to demarcate lines.
-
-****** DELAY
-
-Tells terminal drivers to generate a real-time delay on output. It
-allows time for slow terminals to react to characters previously sent.
-
-****** IOCTL
-
-These are generated by users' ioctl() calls. The parameters are
-gathered at the top level, and if the request is not understood there,
-it and the parameters are passed down the stream as a message. The
-first module that understands a particular request acts on it and
-returns a positive ACK. Intermediate modules that don't recognize a
-particular request pass it on; stream-end modules return a negative
-NAK. The top-level routine blocks until acknowledgement, and passes
-the info to the user.
-
-***** Asynchronous Messages
-
-These are expedited up or down the stream, bypassing the queue.
-
-****** IOCACK and IOCNAK
-
-Acknowledgement messages for IOCTL. The stream head may time out if
-one of these isn't returned quickly enough.
-
-****** SIGNAL
-
-Signals are generated by the terminal processing module and cause the
-top level to generate process signals such as SIGQUIT and SIGINT.
-
-****** FLUSH
-
-Flush messages throw away data from input and output queues after a
-signal or on user request.
-
-****** STOP and START
-
-These messages are used by the terminal processor to halt and restart
-output by a device. For example, to implement the traditional
-XON/XOFF flow control mechanism.
-
-**** Queue Mechanisms and Interfaces
-
-queue structure
- flags
- put procedure
- service procedure
- link to next downstream module
- pointer to the first block on the queue
- pointer to the last block on the queue
- hi-water value
- lo-water value
- count of characters now on the queue
- pointer to private storage
-
-The flags contain several bits used by low-level routines to control
-scheduling. They show whether the downstream module wishes to read
-data, or the upstream module wishes to write, or the queue is already
-enabled. One bit is examined by the upstream module; it tells whether
-this queue is full.
-
-The first and last block pointers point to a singly-linked list of
-data that implements something of a ring buffer. Hi-water and
-lo-water are initialized when the queue is created, and they are
-compared against the character count to decide how to control flow.
-
-The private storage is used to keep characteristics governed by the
-queue module. For example, all the stty(1) things for a terminal.
-
-Stream processing modules are written in one of two flavors. In the
-simpler flavor, the queue module acts almost like a classical
-coroutine. When it's instantiated, it sets its put procedure to a
-system-supplied default routine, and supplies a service procedure.
-Its upstream module disposes of blocks by calling this module's put
-procedure, which moves a block downstream. The standard put procedure
-also enables the current module; a short time later, the current
-module's service procedure is called by the scheduler. In
-pseudo-code, a typical service routine is:
-
- while (my queue is not empty and the next queue is not full) {
- get a message block from my queue
- process the message block
- call the next queue's put() procedure to move the block along
- }
-
-That's appropriate in cases where messages can be processed
-independently of each-other. For example, it's used by the terminal
-output module. All the scheduling details are taken care of by
-standard routines.
-
-More complicated modules need finer control over scheduling. A good
-example is terminal input. Here the device module upstream produces
-characters, usually one at a time, that must be gathered into a line
-to allow for character erase and kill processing. Therefore the
-stream input module provides a put procedure to be called by the
-device driver or other module downstream from it; here is an outline
-of this routine and its accompanying service procedure:
-
- put procedure(queue, block):
- put block on my queue
- if (block contains new-line or carriage return) {
- enable my queue
- }
-
- service procedure(queue):
-
- take data from queue until new-line or carriage return, processing
- erase and kill characters
-
- call the next queue's put() procedure to move the line along
- call the next queue's put() procedure with DELIM to signify a line
-
-The put procedure generates the echo characters as promptly as
-possible; when the terminal module is attached to a device handler,
-they are created during the input interrupt from the device because
-the put procedure is called as a subroutine of the handler. On the
-other hand, line-gathering, erase and kill processing, which can be
-lengthy, are done during the service procedure at a lower priority.
-
-**** Other Stuff
-
-Pseudo-terminals act like pipe drivers. Messages that they receive
-from a master or slave PTY are passed unchanged to the other end.
-This means that streams on both sides are kept in synch.
-
- device process <--> message module <--> pty slave <--> \\
- user process <----> tty module <------> pty master <--> //
-
-The "message" module translates between messages and data, so the pty
-drivers can pass them around. In one direction, the message processor
-takes control and data messages and transforms them into data blocks.
-Data blocks start with a header giving the message type and contain
-data with the message (or data) innit. In the other direction, it
-parses the structured data messages and creates the corresponding
-control blocks. The "device process" simulates a device driver.
-
-**** Evaluation
-
-Design decisions:
-
-1. Messages hold references to data blocks, to minimize data copying.
-Modules must be prepared to coalesce and break up data.
-
-2. Modules are not proper processes (sessions) because there can be
-thousands of them. Coroutines or threads would rock.
-
-3. Put and service were necessary because of asynchrony, flow control,
-etc.
-
-Other notes:
-
-No multiplexing, fan-in or fan-out, are provided by the original
-streams interface.
-
-Streams are good for controlling opened channels, but it lacks a
-general way to establish channels between processes.
-
-*** Unread Sources
-
-SUN's STREAMS Programming Guide:
-<http://docs.sun.com/ab2/coll.156.1/STREAMS/@Ab2TocView?>
-
-Mentat Performance Networking: <http://www.mentat.com/>
-
-** New Modules
-
-*** New Filters
-
-Stacked filters would let you do neat things like IMAP through SSH.
-The mind boggles. Here are some useful filter ideas:
-
- POE::Filter::SSL
- POE::Filter::SSH
-
-For example:
-
- Create a raw socket.
- Push "tcp socket" on it.
- Push "SSH stream protocol" on it.
- Push "line oriented protocol" on it.
- Push "imap client protocol" on it.
-
-And go to town!
-
-*** Axels
-
-Axels would let wheels work together, allowing events from one wheel
-to be sent to input events in another wheel. I have no idea what this
-might be used for.
-
-*** New Components
-
-Some stand-alone components that might be useful:
-
-**** POE::Component::Cron
-
-This could automate many recurring tasks, using cron records instead
-of dorking with time math all the time. It would also have an at()
-method for completeness.
-
-Actually, it'd be kind of silly once the alarms functions were fixed,
-but whatever. :)
-
-**** POE::Component::Authenticate
-
-Artur suggests a generic API for authentication servers. I'm
-interpreting this as a new component. This component would implement
-a standard public interface. Plug-ins for various authentication
-servers would do most of the hard work.
-
-Security issues: Kernel hooks can accidentally or maliciously peek at
-authentication requests, possibly logging them or otherwise displaying
-cleartext passwords.
-
-**** Network Servers and Clients
-
-POE::Component::IRCD, SMTP, SMTPD, NNTP, NNTPD, IMAP, IMAPD, etc.
-
-Sean Puckett has a working prototype of a multi-protocol chat server.
-It accepts IRC and MUD style connections, and he spoke of adding web
-support. Everyone shares the same chat stream.
-
-Fimmtiu is the author of Net::IRC. He has been working on
-POE::Component::IRC, and the new module has entered limited beta
-testing (as of 6/4/1999).
-
-Filter::HTTP (user agent). This is the client side. Randal thinks
-there's a non-blocking way to use LWP, possibly by suppling the select
-loop logic for it, which would work nicely.
-
-**** POE::Component::Named
-
-This might be a simple Net::DNS wrapper, providing a thin interface to
-the module's non-blocking name and number lookup features.
-
-**** POE::Component::VNC
-
-VNC's home is <http://www.uk.research.att.com/vnc/>.
-
-Something on the VNC site caught my eye, but I don't remember exactly
-where it is. The site mentions that the VNC protocol doesn't really
-need a desktop behind it. Instead, stand-alone VNC servers can
-provide graphical interfaces to one or more remote clients.
-
-It sure would be interesting if POE could serve virtual desktops or
-dialogs with VNC. Interesting and scary, like a huge, mutant,
-radioactive lizard staring in your car window, wondering if maybe it
-wants a crunchy snack with a soft, gooey center. Or something.
-
-** Kernel Extensions
-
-I'd like to see the Kernel be extensible through adding new objects.
-Artur has made excellent progress with this, but his code's not ready
-for the public yet.
-
-** Exception handling
-
-Artur suggests wrapping event handler invocations in block evals.
-This would let them throw exceptions with die, or perhaps an imported
-throw function which dies internally.
-
-The caught exception would be translated into an exception event, and
-posted or called back to the session. Or maybe translated into a
-warning.
-
-** Concurrent POE (Distributed Queue)
-
-How does POE transparently thread or fork if these concurrency methods
-are available? How does it make concurrent and single-threaded modes
-compatible with each-other?
-
-Enqueue events in sessions instead of the Kernel. This change should
-also allow sessions to be frozen and thawed, since freezing them will
-also freeze their event queues. Other resources, such as files, may
-be lost, however. A work-around might be to have special _freeze and
-_thaw states that are called at appropriate times. They can clean up
-and reallocate resources.
-
-Function name conventions used in the following code snippets:
-
- sub name is public
- sub _name is friend
- sub __name is private
-
-*** Kernel Changes
-
- sub _enqueue_event {
- my ($self, $session_id, $source_id, $state, $priority, $time, $etc) = @_;
- }
-
- #----------------------------------------------------------------------------
- # Dispatch an event to the next session in the round-robin queue.
- # This also has the side-effect of testing sessions for activity; they
- # can be checked for resource starvation only when they've run out of
- # events. This should eliminate a lot of checks.
-
- sub _dispatch_next_event {
- my ($self) = @_;
-
- my $next_session = shift @{$self->[KR_SQUEUE]};
- if ($next_session->_dispatch_event()) {
- push @{$self->[KR_SQUEUE]}, $next_session;
- }
- }
-
- # Theory of operation:
- #
- # Kernel keeps a master queue. This holds active sessions in a
- # time-based "priority" queue.
- #
- # The queue's "key" is the time that a session will next need
- # attention. This is the time of the next event in the session's
- # queue.
- #
- # The queue's "value" is a reference to the session (or perhaps
- # session ID) that points to the session for dispatching.
- #
- # So:
-