{
    "mode": "perldoc",
    "parameter": "Event",
    "section": "",
    "url": "https://www.chedong.com/phpMan.php/perldoc/Event/json",
    "generated": "2026-06-12T04:02:13Z",
    "synopsis": "use Event qw(loop unloop);\n# initialize application\nEvent->flavor(attribute => value, ...);\nmy $ret = loop();\n# and some callback will call\nunloop('ok');",
    "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 libev\nlibrary 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 may\nbe 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 events\n(in the special Event module sense). For clarity, the former type of events may be called\n\"source events\", and the latter \"target events\". Source events, such as signals arriving, happen\nwhether or not they are being watched. If a source event occurs which a watcher is actively\nwatching then the watcher generates a corresponding target event. Target events are only created\nby watchers. If several watchers are interested in the same source event then each will generate\ntheir own target event. Hence, any particular source event may result in zero, one, two, or any\nnumber of target events: the same as the number of watchers which 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\") events\ncan, in some cases, be cancelled before being processed. A queued event is processed by being\npassed to the callback function (or method on a particular object or class) which was specified\nto 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 watcher's\ncharacteristics. A watcher can be switched between active and inactive states. When inactive, it\ndoes not generate target events.\n\nSome types of source event are not reified as target events immediately. Signals received, for\nexample, are counted initially. The counted signals are reified at certain execution points.\nHence, signal events may be processed out of order, and if handled carelessly, on the wrong side\nof a state change in event handling. A useful way to view this is that occurrence of the source\nevent is not actually the arrival of the signal but is triggered by the counting of the signal.\n\nReification can be forced when necessary. The schedule on which some other events are created is\nnon-obvious. This is especially the case with watchers that watch for a condition rather than an\nevent. In some cases, target events are generated on a schedule that depends on the operation of\nthe 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 to\nunloop() is the return value of loop(). Loops can be nested.\n",
            "subsections": [
                {
                    "name": "unloop",
                    "content": "Make the inner-most loop() return with $result.\n"
                },
                {
                    "name": "unloop_all",
                    "content": "Cause all pending loop()s to return immediately. This is not implemented with \"die\". It is\nworks as if \"unloop($result)\" were called for all nested loops.\n"
                },
                {
                    "name": "sweep",
                    "content": "Queue 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 idle\nevents are ignored by sweep, idle watchers are not ignored. If you want to avoid triggering\nan idle watcher then set \"max\" to \"undef\" or \"stop()\" it.)\n"
                },
                {
                    "name": "one_event",
                    "content": "If any events are outstanding then invoke the corresponding callback of the highest priority\nevent. If there are no events available, block forever or until $timeout. Use of this API is\nnot recommended because it is not efficient and does not trap exceptions. However, you might\nwish 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 next\none and return.\n\n3   Calculate the maximum wait time (minimum time till the next timer expiration) and pass\ncontrol 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 cannot be\nchanged without a recompile. In the rare case that an event is always pending at step 2 then\nI/O watchers will starve. However, this is highly unlikely since async watchers should never\nqueue events so rapidly.\n"
                },
                {
                    "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.\n\"queuepending()\" is only called implicitly by \"sweep()\" and \"oneevent()\". Otherwise,\n\"queuepending()\" is not called implicitly.\n\nNOTE: Signal watchers generate target events according to which watchers are active at the\ntime 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, signal,\ntimer, 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 for\nevents (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 \"parked=>1\"\noption is requested. You will need to set the parked option if you preallocate unconfigured\nwatchers.\n\nNote: If there are any unreified asynchronous events that are of interest to the watcher, it\nwill see these events even though they happened before it was started. This affects signal\nwatchers, but there will only be existing unreified signal events if Event was already\nhandling the signal, which it would only do if there were another active watcher for the\nsame signal. If this situation might occur, and it would be a problem for the new watcher to\nsee older events, call \"queuepending()\" immediately before starting the new watcher in\norder to reify any outstanding events. This explanation may be more clear if read along with\n\"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 not\nrun immediately depending upon the event's priority. If you must unconditionally invoke the\ncallback, 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 events\nare cancelled. Note that a stopped watcher can be reactivated by calling the \"start\" or\n\"again\" methods.\n\nWatchers are stopped implicitly if their new configuration deprives them of the ability to\ngenerate 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 suspend.\n\n$watcher->isrunning\nZero if the callback is not running. Otherwise, the number of levels that the callback has\nbeen entered. This can be greater than one if a \"reentrant\" callback invokes \"loop\" (or\n\"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 pending\nin the event queue. In array context, returns a list of all the watcher's pending 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 is\nnever idle, an event will be generated at least every \"max\" seconds. While Event is idle,\nevents 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\" defaults to\ninfinity.\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 what\nyou 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 seconds\nmay be used if Time::HiRes is available. \"at\" and \"after\" are mutually exclusive.\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 preference)\nif either was supplied. The timer defaults to one-shot behaviour if \"interval\" was not\nspecified, or repeating behaviour if \"interval\" was specified; in either case this can be\noverridden by providing \"repeat\" explicitly.\n\nYou need to know the time at the start of today if you are trying to set timers to trigger\nat 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 local\ntime 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 last\ntime 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, timeoutcb\n=> \\&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. If\n\"timeoutcb\" is set then timeouts use this alternate callback instead of the main callback.\n\nsignal\nExtra attribute: signal => $str\n\nGenerates events based on signal arrival. The events are not actually generated immediately\nwhen the signal arrives: signals received are counted and reified by \"queuepending()\" or\nimplicitly by \"oneevent()\". Several signals of the same type may be merged into a single\nevent. In such cases, the number of signals represented by a single event is stored in the\n\"hits\" attribute.\n\nPRIORITY\nPriority is used to sort the event queue. Meaningful priorities range from -1 to 6 inclusive.\nLower numbers mean higher priority (-1 is the highest priority and 6 is the lowest). If multiple\nevents get queued, the ones with the highest priority are serviced first. Events with equal\npriority 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 the\nwhole 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 priority\nis not satisfactory for your purposes, the constructor options \"nice\", \"async\", or \"prio\" can be\nused to adjust it. \"nice\" specifies an offset from the default priority; \"async\" forces the\npriority to -1; and \"prio\" assigns a given priority of your choice. If more than one of these\noptions 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 usually be\nin 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\" occurs\nwithin your callback? $Event::DIED is just for this purpose. See the full description of\n\"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, 3,\nor 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, respectively.\nIn 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 it\nis 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 E\nT);'.\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 accesses\nits own private attribute.\n\nreentrant => $bool\nBy default, callbacks are allowed to invoke \"sweep\" or \"loop\" which in turn may invoke the\nsame callback again recursively. This can be useful but can also be confusing. Moreover, if\nyou keep reentering callbacks you will quickly run out of stack space. Disable this feature\nper watcher by setting reentrant to false. This will cause the watcher to be suspended\nduring recursive calls to \"sweep\" or \"loop\".\n\nrepeat => $bool\nThe repeat flag controls whether the callback should either be one-shot or continue waiting\nfor new events. The default setting depends on the type of watcher. *io*, *signal*, and\n*var* default to true.\n\nsignal => $str\nThe callback is invoked after the specified signal is received. The $str string should be\nsomething 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 handles\nthe signal as long as there is at least one active watcher. If all watchers for the signal\nare 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 examine\nthe 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 serviced\nby \"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 as\n\"poll\" except that it gives what kind of event actually happened. In contrast, \"poll\" is\njust 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 which\ndon'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 extension\nAPI 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 output)\nto 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 hook\nuses \"warn\" to output the exception. After the DIED handler completes, event processing\ncontinues 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\" method\nallows insertion of perl code at key points in the optimized event processing core. While\nflexible, this can hurt performance *significantly*. If you want customization *and*\nperformance, 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 implementation\nis usually outside the kernel. While an event loop may appear to do many things in parallel, it\ndoes not, even on multiprocessor hardware. Actions are always dispatched sequentially. This\nimplies that long running callbacks must be avoided because otherwise event processing is\nhalted.\n\nEvent loops work well when actions are short and to the point. Long-running tasks must be broken\ninto short steps and scheduled for execution. Some sort of a state machine is usually required.\nWhile a big, complex application server is usually simpler to implement in a multithreaded\nfashion, a web browser can easily get by without threads. Consider a JPEG file download and\nrender. When some new bytes are available they are sorted to the right place on the screen. Only\na little state must be kept to keep track of how much has been rendered and to process\nsubsequent 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 difference\nis that all threads share the same address space. This is good and bad. Higher performance can\nbe achieved but since data is shared between threads, extreme care must be taken to access or\nmodify global data. The operating system can switch threads at any moment or can execute\nmultiple threads simultaneously. I hope this sounds dangerous! It is! Threads can introduce\nmaddeningly complicated and hard to debug synchronization problems.\n\nThreads are like rocket fuel. They are essential when you really need them but most applications\nwould be better off with a simple event loop. Even if threads are genuinely needed, consider\nconfining them to the parts of an application where truly scalable performance is really worth\nthe difficulty of a multithreaded implementation. For example, most GUIs applications do not\nneed threads and most scientific compute intensive problems can be isolated from event\ndispatching. On the other hand, high performance transaction servers generally do mandate a\ntruly multithreaded approach.\n\nAnother consideration is that threads are not quite as widely available as event loops. While a\nfew forward-thinking operating systems have offered threads since the beginning, their addition\nto many popular operating systems is much more recent and some still offer no threads support.\nIf portability is a requirement, one must check that threads support is available and also\ncarefully test a particular threads implementation to see whether it supports the features you\nneed. It is likely that all platforms will have a solid implementation soon but at this point in\nhistory 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 applications.\nMy belief is that the benefit of multi-threading is the gain in performance on SMP hardware. In\nmy view, non-preemptive threads (java green-threads) are usually poor design. I find them harder\nto work with, harder to debug, and slower for a rather marginal gain in readability. I really\nlike working with a state machine. I find it leads to more stable and better code. It also has\nthe benefit of abstracting away how concurrency is achieved.\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 this\nis a bug or a feature (OK, probably it was a mistake). We'll probably want to re-work things for\nPerl6.\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 the\nearly days, the Event programming API was changing at every release. Care was taken to allow the\nold API to continue to work, and the transition was eased by printing out lots of warnings about\nthe new usage. So you shouldn't sit on your hands in anticipation of the One and True Event\nLoop. 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",
            "subsections": []
        }
    },
    "summary": "Event - Event loop processing",
    "flags": [],
    "examples": [],
    "see_also": []
}