{
    "content": [
        {
            "type": "text",
            "text": "# event (man)\n\n## NAME\n\nEvent - Event loop processing\n\n## SYNOPSIS\n\nuse Event qw(loop unloop);\n# initialize application\nEvent->flavor(attribute => value, ...);\nmy $ret = loop();\n# and some callback will call\nunloop('ok');\n\n## DESCRIPTION\n\nALERT: Marc Lehmann may have taken over the future of event loops in Perl. Check out his\nlibev library and EV Perl module. 25 Aug 2009\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **PERL API** (9 subsections)\n- **C API**\n- **BUGS**\n- **THE FUTURE**\n- **ALSO SEE**\n- **SUPPORT**\n- **AUTHOR**\n- **ACKNOWLEDGMENT**\n- **COPYRIGHT**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "event",
        "section": "",
        "mode": "man",
        "summary": "Event - Event loop processing",
        "synopsis": "use Event qw(loop unloop);\n# initialize application\nEvent->flavor(attribute => value, ...);\nmy $ret = loop();\n# and some callback will call\nunloop('ok');",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 10,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 40,
                "subsections": []
            },
            {
                "name": "PERL API",
                "lines": 48,
                "subsections": [
                    {
                        "name": "all_watchers()",
                        "lines": 2
                    },
                    {
                        "name": "all_running()",
                        "lines": 3
                    },
                    {
                        "name": "all_idle()",
                        "lines": 5
                    },
                    {
                        "name": "queue_pending()",
                        "lines": 8
                    },
                    {
                        "name": "Event Watcher Constructors",
                        "lines": 18
                    },
                    {
                        "name": "Shared Watcher Attributes",
                        "lines": 10
                    },
                    {
                        "name": "Shared Watcher Methods",
                        "lines": 70
                    },
                    {
                        "name": "Watcher Types",
                        "lines": 262
                    },
                    {
                        "name": "Customization and Exceptions",
                        "lines": 43
                    }
                ]
            },
            {
                "name": "C API",
                "lines": 59,
                "subsections": []
            },
            {
                "name": "BUGS",
                "lines": 15,
                "subsections": []
            },
            {
                "name": "THE FUTURE",
                "lines": 7,
                "subsections": []
            },
            {
                "name": "ALSO SEE",
                "lines": 16,
                "subsections": []
            },
            {
                "name": "SUPPORT",
                "lines": 4,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "ACKNOWLEDGMENT",
                "lines": 9,
                "subsections": []
            },
            {
                "name": "COPYRIGHT",
                "lines": 8,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "Event - Event loop processing\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use Event qw(loop unloop);\n\n# initialize application\nEvent->flavor(attribute => value, ...);\n\nmy $ret = loop();\n\n# and some callback will call\nunloop('ok');\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "ALERT: Marc Lehmann may have taken over the future of event loops in Perl. Check out his\nlibev library and EV Perl module. 25 Aug 2009\n\nThe Event module provide a central facility to watch for various types of events and invoke a\ncallback when these events occur.  The idea is to delay the handling of events so that they\nmay be dispatched in priority order when it is safe for callbacks to execute.\n\nEvents (in the ordinary sense of the word) are detected by watchers, which reify them as\nevents (in the special Event module sense).  For clarity, the former type of events may be\ncalled \"source events\", and the latter \"target events\".  Source events, such as signals\narriving, happen whether or not they are being watched.  If a source event occurs which a\nwatcher is actively watching then the watcher generates a corresponding target event.  Target\nevents are only created by watchers.  If several watchers are interested in the same source\nevent then each will generate their own target event.  Hence, any particular source event may\nresult in zero, one, two, or any number of target events: the same as the number of watchers\nwhich were actively watching for it.\n\nTarget events are queued to be processed in priority order (priority being determined by the\ncreating watcher) and in FIFO order among events of the same priority.  Queued (\"pending\")\nevents can, in some cases, be cancelled before being processed.  A queued event is processed\nby being passed to the callback function (or method on a particular object or class) which\nwas specified to the watcher.\n\nA watcher, once created, operates autonomously without the Event user having to retain any\nreference to it.  However, keeping a reference makes it possible to modify most of the\nwatcher's characteristics.  A watcher can be switched between active and inactive states.\nWhen inactive, it does not generate target events.\n\nSome types of source event are not reified as target events immediately.  Signals received,\nfor example, are counted initially. The counted signals are reified at certain execution\npoints.  Hence, signal events may be processed out of order, and if handled carelessly, on\nthe wrong side of a state change in event handling.  A useful way to view this is that\noccurrence of the source event is not actually the arrival of the signal but is triggered by\nthe counting of the signal.\n\nReification can be forced when necessary.  The schedule on which some other events are\ncreated is non-obvious.  This is especially the case with watchers that watch for a condition\nrather than an event.  In some cases, target events are generated on a schedule that depends\non the operation of the event loop.\n",
                "subsections": []
            },
            "PERL API": {
                "content": "Events (the occurrence of such) are noticed and queued by 'event watchers'.  The creation and\nconfiguration of event watchers is the primary topic of the rest of this document.\n\nThe following functions control or interrogate the event loop as a whole:\n\n$result = loop([$timeout])\nWill  enter  a loop that calls oneevent() until unloop() is called.  The argument passed\nto unloop() is the return value of loop().  Loops can be nested.\n\nunloop($result)\nMake the inner-most loop() return with $result.\n\nunloopall($result)\nCause all pending loop()s to return immediately.  This is not implemented with \"die\".  It\nis works as if unloop($result) were called for all nested loops.\n\nsweep([$maxprio])\nQueue all pending events and dispatch any with priority strictly less than $maxprio (the\nhighest priority is 0).  The default is to process all events except idle events.  (While\nidle events are ignored by sweep, idle watchers are not ignored.  If you  want  to  avoid\ntriggering an idle watcher then set \"max\" to \"undef\" or stop() it.)\n\noneevent([$timeout])\nIf  any  events  are  outstanding  then  invoke the corresponding callback of the highest\npriority event.  If there are no events available, block forever or until $timeout.   Use\nof  this API is not recommended because it is not efficient and does not trap exceptions.\nHowever, you might wish to understand how it works:\n\n1.  Queue asyncronous events (signals, etc).  That is,  previously  recorded  events  are\nreified.\n\n2.  If  there  are  any  events with priority 5 or less (see StarvePrio) then service the\nnext one and return.\n\n3.  Calculate the maximum wait time (minimum time till the  next  timer  expiration)  and\npass control to the poll/select system call.  Upon return, queue all pending events.\n\n4.  Queue asyncronous events again.\n\n5.  If there are any events then service the next one and return.\n\n6.  Service the next idle watcher.\n\nStarvePrio  is  the  priority  level  for  which events are dispatched during step 2.  It\ncannot be changed without a recompile.  In the rare case that an event is always  pending\nat  step  2  then I/O watchers will starve.  However, this is highly unlikely since async\nwatchers should never queue events so rapidly.\n",
                "subsections": [
                    {
                        "name": "all_watchers()",
                        "content": "Returns a list of all watchers (including stopped watchers).\n"
                    },
                    {
                        "name": "all_running()",
                        "content": "Returns a list of all watchers with actively running callbacks.  Watchers are returned in\norder of most recent to least recent.\n"
                    },
                    {
                        "name": "all_idle()",
                        "content": "Returns a list of all the idle watchers.  If the event queue is very busy, all  the  idle\nwatchers  will  sit  on the idle queue waiting to run.  However, be aware that if an idle\nwatcher has the \"max\" attribute set then it will queue a normal event when its \"max\" wait\ntime is exceeded.\n"
                    },
                    {
                        "name": "queue_pending()",
                        "content": "Examines asynchronous source events (timers & signals) and reifies them as target events.\nqueuepending() is  only  called  implicitly  by  sweep()  and  oneevent().   Otherwise,\nqueuepending() is not called implicitly.\n\nNOTE:  Signal  watchers  generate target events according to which watchers are active at\nthe time that queuepending() is called rather than according to the time the  signal  is\nreceived.  This is best explained by example.  See the file \"demo/queuepending.t\".\n"
                    },
                    {
                        "name": "Event Watcher Constructors",
                        "content": "All watchers are constructed in one of the following ways:\n\n$w = Event->flavor( [attr1 => $value,]... );\n\n$w = Event::flavor($Class, [attr1 => $value,]...);\n\n$w = Event::flavor->new([attr1 => $value,]...);\n\nWhere  flavor  is  substituted  with  the  kind of watcher.  Built-in types include idle, io,\nsignal, timer, and var.\n\nNew watchers (hopefully) have reasonable defaults and can also be customized by passing extra\nattributes to the constructor.  When created, watcher objects are \"started\" and  are  waiting\nfor events (see \"$event->start\" below).\n\nNetServer::Portal can display watchers in real-time, formatted similarly to the popular \"top\"\nprogram.  You may find this a useful aide for debugging.\n"
                    },
                    {
                        "name": "Shared Watcher Attributes",
                        "content": "Watchers are configured with attributes (also known as properties).  For example:\n\n$watcher->cb(\\&somecode);   # set callback\n\nwarn $event->w->desc.\": \".$event->hits.\" events happened; Wow!\";\n\nAll  watchers  support  the  following  attributes: cb, cbtime, debug, desc, prio, maxcbtm,\nreentrant, and repeat.  Watcher constructors accept the preceding and additionally: async and\nnice.  Moreover, watchers also offer extra attributes according to their specialty.\n"
                    },
                    {
                        "name": "Shared Watcher Methods",
                        "content": "The following methods are available for all watchers:\n\n$watcher->start\nActivate the watcher.   Watchers  refuse  to  start()  without  sufficient  configuration\ninformation   to   generate  events.   Constructors  always  invoke  start()  unless  the\n\"parked=>1\" option is requested.   You  will  need  to  set  the  parked  option  if  you\npreallocate unconfigured watchers.\n\nNote: If there are any unreified asynchronous events that are of interest to the watcher,\nit  will  see these events even though they happened before it was started.  This affects\nsignal watchers, but there will only be existing unreified signal  events  if  Event  was\nalready  handling the signal, which it would only do if there were another active watcher\nfor the same signal.  If this situation might occur, and it would be a  problem  for  the\nnew watcher to see older events, call queuepending() immediately before starting the new\nwatcher  in order to reify any outstanding events.  This explanation may be more clear if\nread along with \"demo/queuepending.t\".\n\n$watcher->again\nThis is the same as the \"start\" except if a watcher has  special  repeat  behavior.   For\nexample, repeating timers recalculate their alarm time using the \"interval\" parameter.\n\n$watcher->now\nCause  the  watcher to generate an event, even if it is stopped.  The callback may or may\nnot run immediately depending upon the event's priority.   If  you  must  unconditionally\ninvoke the callback, consider something like\n\n$w->cb->($w);\n\n$watcher->stop\nDon't  look  for  events  any  more.   Running events are allowed to complete but pending\nevents are cancelled.  Note that a stopped watcher can  be  reactivated  by  calling  the\n\"start\" or \"again\" methods.\n\nWatchers  are  stopped implicitly if their new configuration deprives them of the ability\nto generate events.  For instance:\n\nmy $iowatcher = Event->io(timeout => 1);  # started\n$iowatcher->timeout(undef);               # stopped implicitly\n$iowatcher->timeout(1);                   # still stopped\n$iowatcher->start;                        # restarted\n\n$watcher->cancel\nStop and destroy $watcher.  Running events are allowed to complete but pending events are\ncancelled.  Cancelled watchers are no longer valid except for read-only operations.   For\nexample, prio() can return the watcher's priority, but start() will fail.\n\n$watcher->iscancelled\nReports whether the $watcher has been cancelled.\n\n$watcher->isactive\nReports  whether  the  $watcher  has  been  started.  The return value is not affected by\nsuspend.\n\n$watcher->isrunning\nZero if the callback is not running.  Otherwise, the number of levels that  the  callback\nhas  been entered.  This can be greater than one if a \"reentrant\" callback invokes \"loop\"\n(or \"sweep\", with lesser probability).\n\n$watcher->issuspended\nReports whether the $watcher is suspended.  Suspension is a debugging  feature;  see  the\ndiscussion of the \"suspend\" attribute below.\n\n$watcher->pending\nIn  scalar  context,  returns  a  boolean  indicating whether this watcher has any events\npending in the event queue.  In array context,  returns  a  list  of  all  the  watcher's\npending events.\n\nNote  that  this  does not check for unreified asynchronous events.  Call queuepending()\nfirst if you want to see signals received since the last operation of the event loop.\n"
                    },
                    {
                        "name": "Watcher Types",
                        "content": "idle\nExtra attributes: min => $seconds, max => $seconds\n\nWatches for the Event system to be idle, i.e., to have no events pending.  If the  system\nis  never  idle, an event will be generated at least every \"max\" seconds.  While Event is\nidle, events will be generated not more often than \"min\" seconds.\n\nIf neither \"min\" nor \"max\" is specified,  the  watcher  defaults  to  one-shot  behaviour\n(\"repeat\" false), otherwise it defaults to repeating.  In either case, the default can be\noverridden  by  specifying  a  \"repeat\"  attribute.   \"min\"  defaults  to 0.01, and \"max\"\ndefaults to infinity.\n\nvar Extra attributes: var => \\$var, poll => 'rw'\n\nVar watchers generate events when the given variable is  read  from  or  written  to,  as\nspecified by \"poll\".  \"poll\" defaults to \"w\".\n\nAs  perl  is a concise language, it is often difficult to predict when a variable will be\nread.  For this reason, variable watchers should poll only for  writes  unless  you  know\nwhat you are doing.\n\ntimer\nExtra attributes: at => $time, after => $sec, interval => $sec, hard => $bool\n\nGenerate  events  at  particular  times.   The $time and $sec are in seconds.  Fractional\nseconds may be  used  if  Time::HiRes  is  available.   \"at\"  and  \"after\"  are  mutually\nexclusive.\n\n\"at\"  or  \"after\" specify the initial time that the event will trigger.  Subsequent timer\nevents occur  at  intervals  specified  by  \"interval\"  or  \"after\"  (in  that  order  of\npreference)  if  either  was  supplied.   The  timer  defaults  to  one-shot behaviour if\n\"interval\" was not specified, or repeating behaviour  if  \"interval\"  was  specified;  in\neither case this can be overridden by providing \"repeat\" explicitly.\n\nYou  need  to  know  the  time  at  the start of today if you are trying to set timers to\ntrigger at day relative times.  You can find it with:\n\nuse Time::Local;\nmy $TodaySeconds = int timelocal(0,0,0,(localtime)[3,4,5]);\n\nThis calculation may seem a little heavy weight.  If you want  to  use  UTC  rather  than\nlocal time then you can use this instead:\n\nmy $TodaySeconds = time - time % 86400;\n\nBeware  that, due to lags in the event loop, the \"interval\" timeout may already be in the\npast.  If the \"hard\" flag is set, the event will be queued for execution relative to  the\nlast  time the callback was invoked.  However, if \"hard\" is false the new timeout will be\ncalculated relative to the current time.  \"hard\" defaults to false.\n\nio  Extra attributes: fd =>  $fd,  poll  =>  'rwe'  [timeout  =>  $seconds,  hard  =>  $bool,\ntimeoutcb => \\&code]\n\nThe  callback is invoked when the file descriptor, \"fd\", has data to be read, written, or\npending exceptions.  \"fd\" can be a GLOB, an IO::Handle object, or  a  file  number  (file\ndescriptor).  \"poll\" defaults to \"r\".\n\nNote that it is your option whether to have multiple watchers per file handle or to use a\nsingle watcher for all event conditions.\n\nIf  \"timeout\"  is set, events are also generated regularly if no actual I/O event occurs.\nIf \"timeoutcb\" is set then timeouts use this alternate  callback  instead  of  the  main\ncallback.\n\nsignal\nExtra attribute: signal => $str\n\nGenerates  events  based  on  signal  arrival.   The  events  are  not actually generated\nimmediately when the  signal  arrives:  signals  received  are  counted  and  reified  by\nqueuepending()  or  implicitly  by oneevent().  Several signals of the same type may be\nmerged into a single event. In such cases, the number of signals represented by a  single\nevent is stored in the \"hits\" attribute.\n\nPRIORITY\nPriority  is  used  to  sort  the  event  queue.   Meaningful  priorities  range from -1 to 6\ninclusive.  Lower numbers mean higher priority (-1 is the  highest  priority  and  6  is  the\nlowest).   If  multiple  events  get  queued, the ones with the highest priority are serviced\nfirst.  Events with equal priority are serviced in first-in-first-out order.\n\nuse Event qw(PRIOHIGH PRIONORMAL);   # some constants\n\nLEVELS: -1      0      1      2      3      4      5      6\n----------------------+-------------+---------------\nPRIOHIGH     PRIONORMAL\n\nA negative priority causes the callback to be invoked immediately upon event occurrence.  Use\nthis with caution.  While it may seem advantageous to use negative  priorities,  they  bypass\nthe whole point of having an event queue.\n\nEach watcher has a default priority, assigned by its constructor:\n\nio       PRIONORMAL\nsignal   PRIOHIGH\ntimer    PRIONORMAL\nvar      PRIONORMAL\n\nDefault  priorities  are  stored  in  ${\"Event::${type}::DefaultPriority\"}.   If  the default\npriority is not satisfactory for your purposes, the constructor options \"nice\",  \"async\",  or\n\"prio\"  can  be  used  to  adjust  it.  \"nice\" specifies an offset from the default priority;\n\"async\" forces the priority to -1; and \"prio\" assigns a given priority of  your  choice.   If\nmore than one of these options are given then \"prio\" overrides \"async\" overrides \"nice\".\n\nWATCHER CONSTRUCTOR ATTRIBUTES\nThese options are only supported as constructor arguments.\n\nafter => $seconds\nSee the discussion of the timer watcher.\n\nasync => $bool\nIf $bool then the watcher priority is set to -1.\n\nnice => $offset\nOffset from the default priority.\n\nparked => $yes\nBy  default,  watcher constructors automatically invoke the start() method.  If you don't\nwant the watcher started then request \"parked=>1\".\n\nWATCHER ATTRIBUTES\nat => $time\nThe expiration time in the same units as the  system  clock.   For  a  timer,  \"at\"  will\nusually be in the future.\n\ncb => \\&code\ncb => [$classorobject, $methodname]\nThe function or method to call when an event is dispatched.  The callback is invoked with\n$event as its only argument.\n\nPerhaps  you  are  wondering  what happens if something goes wrong and an untrapped \"die\"\noccurs within your callback?  $Event::DIED is  just  for  this  purpose.   See  the  full\ndescription of \"DIED\" below.\n\ncbtime => $time\nWhen the callback was invoked most recently.\n\ndata => $anything\nThe data() method associates arbitrary data with a watcher.\n\nThis  method  is  not  intended  for implementers of watchers.  If you are subclassing or\nimplementing a watcher, consider the private() method.\n\ndebug => $bool\nDebugging can be activated globally or per watcher.  When  debugging  is  enabled  for  a\nparticular  watcher, $Event::DebugLevel is treated as two levels higher.  Levels of 1, 2,\n3, or 4 give progressively more diagnostics on STDERR.\n\ndesc => $string\nAn identifying name.  If this is not passed explicitly to the  constructor,  it  will  be\ninitialized with a string that attempts to identify the location in the source code where\nthe watcher was constructed.\n\nfd => $filehandle\nThis  attribute  can  accept either a perl-esque filehandle or a system call derived file\ndescriptor number.\n\nhard => $bool\nDetermines how repeating timers (or timeouts) are recalculated.  The timer  is  restarted\neither  before  or  after  the  callback  depending  on  whether  it  is  true  or false,\nrespectively.  In long-running callbacks this can make a significant difference.\n\ninterval => $seconds\nHow long between repeating timeouts.  The \"at\" attribute is recalculated using \"interval\"\nupon callback return.\n\nmax => $seconds\nThe maximum number of seconds to wait before  triggering  the  callback.   Similar  to  a\n\"timeout\".\n\nmaxcbtm => $seconds\nThe  maximum number of seconds to spend in a callback.  If a callback uses more time then\nit is aborted.  Defaults to 1 sec.  This feature is normally disabled.  See Event::Stats.\n\nmin => $seconds\nEnforce a minimum number of seconds between triggering events.\n\npoll => $bits\nDetermines which kinds of events are of interest.  This attribute can be set with  either\nstrings or bit constants.  The bit constants are available via 'use Event::Watcher qw(R W\nE T);'.\n\nstring constant description\n------ -------- ---------------\n'r'     R      read\n'w'     W      write\n'e'     E      exception\n't'     T      timeout\n\nThus, both of these statements enable interest in read:\n\n$w->poll($w->poll . 'r');\n$w->poll($w->poll | R);\n\nA given type of watcher may support all or a subset of the available events.\n\nprio => $level\nChanges the watcher's priority to the given level.  Events generated by a watcher usually\ninherit the priority of the watcher.\n\nprivate => $anything\nUse  the  private()  method  to  associate arbitrary data with a watcher.  This method is\nintended for implementers of watchers  or  watcher  subclasses.   Each  caller's  package\naccesses its own private attribute.\n\nreentrant => $bool\nBy  default,  callbacks  are allowed to invoke \"sweep\" or \"loop\" which in turn may invoke\nthe same callback again recursively.  This can be  useful  but  can  also  be  confusing.\nMoreover,  if  you  keep  reentering  callbacks  you will quickly run out of stack space.\nDisable this feature per watcher by setting reentrant to  false.   This  will  cause  the\nwatcher to be suspended during recursive calls to \"sweep\" or \"loop\".\n\nrepeat => $bool\nThe  repeat  flag  controls  whether  the  callback should either be one-shot or continue\nwaiting for new events.  The default setting depends on the type of watcher.  io, signal,\nand var default to true.\n\nsignal => $str\nThe callback is invoked after the specified signal is received.  The $str  string  should\nbe something like 'INT' or 'QUIT'.  Also see the documentation for %SIG.\n\nA  given  signal  can  be handled by %SIG or Event, but not both at the same time.  Event\nhandles the signal as long as there is at least one active watcher. If all  watchers  for\nthe signal are cancelled or stopped then Event sets the signal handler to SIGDFL.\n\nsuspend => $bool\nStop  looking  for events.  Running events are allowed to complete, but queued events are\ncancelled.\n\nSuspend is for debugging.  If you suspend all watchers in an  application  then  you  can\nexamine the complete state unchanged for as long as you like without worrying about timer\nexpirations.  If you actually wish to stop a watcher then use the stop() method.\n\ntimeout => $seconds\nThe number of seconds before a watcher times out.\n\ntimeoutcb => \\&code\ntimeoutcb => [$classorobject, $methodname]\nThis  is  an optional attribute for use when it is desired that timeouts be serviced in a\nseparate code path than normal events.   When  this  attribute  is  unset,  timeouts  are\nserviced by \"cb\".\n\nvar => $ref\nA reference to the variable being watched.\n\nEVENT ATTRIBUTES\ngot => $bits\n\"got\"  is available in the callback of watchers with \"poll\".  \"got\" is in the same format\nas \"poll\" except that it gives what kind of event actually happened.  In contrast, \"poll\"\nis just an indication of interest.\n\nhits => $int\nSignals in quick succession can be clumped into a single event.  The  number  of  signals\nclumped  together  is  indicated  by  this attribute.  This is always one for event types\nwhich don't clump.\n\nprio => $level\nBe aware that this priority can differ from the watcher's  priority.  For  instance,  the\nwatcher's  priority  may  have  changed  since  the event was generated.  Moreover, the C\nextension API offers the freedom to queue events of arbitrary priority.\n\nw => $watcher\nThis method return the event's watcher.  It is read-only.\n"
                    },
                    {
                        "name": "Customization and Exceptions",
                        "content": "•   $Event::DebugLevel\n\nEnables progressively more debugging output.   Meaningful  levels  range  from  1  (least\noutput) to 5 (most output). Also see \"debug\".\n\n•   $Event::DIED\n\nWhen \"loop\" or \"sweep\" is called, an exception context is established for the duration of\nevent  processing. If an exception is detected then $Event::DIED is invoked.  The default\nhook uses \"warn\" to output the  exception.   After  the  DIED  handler  completes,  event\nprocessing continues as if nothing happened.\n\nIf you'd like more detailed output you can install the verbose handler:\n\n$Event::DIED = \\&Event::verboseexceptionhandler;\n\nOr you can write your own.  The handler is invoked like this:\n\n$Event::DIED->($event, $@);\n\nIf you do not want to continue looping after an error, you can do something like this:\n\n$Event::DIED = sub {\nEvent::verboseexceptionhandler(@);\nEvent::unloopall();\n};\n\n•   Event->addhooks(key => sub { ... }, ...);\n\nThe  bulk  of  Event's  implementation  is in C for maximum performance.  The \"addhooks\"\nmethod allows insertion of perl code at key points  in  the  optimized  event  processing\ncore.    While  flexible,  this  can  hurt  performance  *significantly*.   If  you  want\ncustomization *and* performance, please see the C API.\n\nCurrently support hooks are detailed as follows:\n\nhook          purpose\n------------- ----------------------------------------------\nprepare       returns minimum time to block (timeable)\ncheck         assess state after normal return from select/poll\nasynccheck    check for signals, etc\ncallback      invoked before each event callback\n"
                    }
                ]
            },
            "C API": {
                "content": "Event also has a direct API for callbacks written exclusively in C.  See Event::MakeMaker.\n\nWHAT ABOUT THREADS?\nEvent loops and threads are  two  different  solutions  to  the  same  problem:  asynchronous\nprocessing.   Event  loops  have been around since the beginning of computing.  They are well\nunderstood and proven to be a good solution for many applications.\n\nWhile  event  loops  make  use  of  basic  operating  system  services,  the  bulk  of  their\nimplementation  is  usually  outside  the  kernel.  While an event loop may appear to do many\nthings in parallel, it does  not,  even  on  multiprocessor  hardware.   Actions  are  always\ndispatched  sequentially.   This  implies that long running callbacks must be avoided because\notherwise event processing is halted.\n\nEvent loops work well when actions are short and to the point.  Long-running  tasks  must  be\nbroken into short steps and scheduled for execution.  Some sort of a state machine is usually\nrequired.   While  a  big,  complex  application  server is usually simpler to implement in a\nmultithreaded fashion, a web browser can easily get by without threads.  Consider a JPEG file\ndownload and render.  When some new bytes are available they are sorted to the right place on\nthe screen.  Only a little state must be kept to keep track of how much has been rendered and\nto process subsequent incoming bytes.\n\nThreads can either substitute for an event loop or complement it.   Threads  are  similar  to\nprocesses  in  that  the  operating  system  manages  task  switching  for you.  However, the\ndifference is that all threads share the same address space.  This is good and  bad.   Higher\nperformance  can  be  achieved but since data is shared between threads, extreme care must be\ntaken to access or modify global data.  The operating system can switch threads at any moment\nor can execute multiple threads simultaneously.   I  hope  this  sounds  dangerous!   It  is!\nThreads can introduce maddeningly complicated and hard to debug synchronization problems.\n\nThreads  are  like  rocket  fuel.   They  are  essential  when  you really need them but most\napplications would be better off with a simple event loop.  Even  if  threads  are  genuinely\nneeded,  consider  confining  them  to  the  parts  of  an  application  where truly scalable\nperformance is really worth the difficulty of a multithreaded implementation.   For  example,\nmost GUIs applications do not need threads and most scientific compute intensive problems can\nbe  isolated from event dispatching.  On the other hand, high performance transaction servers\ngenerally do mandate a truly multithreaded approach.\n\nAnother consideration is that threads are not quite  as  widely  available  as  event  loops.\nWhile  a  few  forward-thinking  operating  systems have offered threads since the beginning,\ntheir addition to many popular operating systems is much more recent and some still offer  no\nthreads  support.   If  portability  is a requirement, one must check that threads support is\navailable and also carefully test a particular  threads  implementation  to  see  whether  it\nsupports  the  features  you  need.   It  is  likely  that  all  platforms  will have a solid\nimplementation soon but at this point in history it is best to double check.\n\nMany suggestions by Mark Mielke <Mark.Mielke.markm@nt.com>\n\nWHAT ABOUT NON-PREEMPTIVE THREADS?\nThe Java language is oriented to use non-preemptive threads, yet even Java uses an event-loop\nfor Swing (AFAIK). That  is  one  of  the  reasons  I  don't  use  Java  for  network-centric\napplications.  My belief is that the benefit of multi-threading is the gain in performance on\nSMP hardware.  In my view, non-preemptive  threads  (java  green-threads)  are  usually  poor\ndesign.   I  find them harder to work with, harder to debug, and slower for a rather marginal\ngain in readability. I really like working with a state machine.  I find  it  leads  to  more\nstable  and  better  code.  It  also  has  the benefit of abstracting away how concurrency is\nachieved.\n\nContributed by artur@vogon-solutions.com, 12 Jul 1999.\n",
                "subsections": []
            },
            "BUGS": {
                "content": "No support for epoll, or better, libevent.\n\nThe scope of events is pretty strange compared to most other perl objects.  I'm not  sure  if\nthis  is  a bug or a feature (OK, probably it was a mistake).  We'll probably want to re-work\nthings for Perl6.\n\nThe meaning of $io->timeout(0) might change.  Use \"undef\" to unset the timeout.\n\nThere seems to be some sort of bug in the global destruction phase:\n\nAttempt to free unreferenced scalar during global destruction.\nUse of uninitialized value during global destruction.\nExplicit blessing to '' (assuming package main) during global\ndestruction.\n",
                "subsections": []
            },
            "THE FUTURE": {
                "content": "Even if this module does not end up being the One and True Event Loop, the author will insure\nthat it is source compatible with its successor, or arrange for gradual migration.   Back  in\nthe  early  days, the Event programming API was changing at every release.  Care was taken to\nallow the old API to continue to work, and the transition was eased by printing out  lots  of\nwarnings  about the new usage.  So you shouldn't sit on your hands in anticipation of the One\nand True Event Loop.  Just start coding!\n",
                "subsections": []
            },
            "ALSO SEE": {
                "content": "•   Useful and Fun\n\nTime::HiRes, NetServer::Portal, Time::Warp\n\n•   Message Passing\n\nCOPE, IPC::LDT, Event-tcp\n\n•   GUI\n\nWhile Tk does not yet support Event, PerlQt does.\n\n•   C API\n\nInline\n",
                "subsections": []
            },
            "SUPPORT": {
                "content": "If you have insights or complaints then please subscribe to the mailing list!  Send email to:\n\nperl-loop-subscribe@perl.org\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Joshua N. Pritikin <jpritikin@pobox.com>\n",
                "subsections": []
            },
            "ACKNOWLEDGMENT": {
                "content": "Initial 0.01 implementation by Graham Barr <gbarr@pobox.com>.  Other contributors include  at\nleast those lists below and folks mentioned in the ChangeLog.\n\nGisle Aas <gisle@aas.no>\nUri Guttman <uri@sysarch.com>\nNick Ing-Simmons <nick@ni-s.u-net.com> (Tk)\nSarathy <gsar@engin.umich.edu>\nJochen Stenzel <perl@jochen-stenzel.de>\n",
                "subsections": []
            },
            "COPYRIGHT": {
                "content": "Copyright © 1997 Joshua Nathaniel Pritikin & Graham Barr\n\nCopyright © 1998, 1999, 2000, 2001, 2002, 2003, 2004 Joshua Nathaniel Pritikin\n\nAll rights reserved.  This program is free software; you can redistribute it and/or modify it\nunder the same terms as Perl itself.\n\nperl v5.38.2                                 2024-04-01                                   Event(3pm)",
                "subsections": []
            }
        }
    }
}