1.\" $OpenBSD: event.3,v 1.56 2022/03/31 17:27:17 naddy Exp $ 2.\" 3.\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org> 4.\" All rights reserved. 5.\" 6.\" Redistribution and use in source and binary forms, with or without 7.\" modification, are permitted provided that the following conditions 8.\" are met: 9.\" 10.\" 1. Redistributions of source code must retain the above copyright 11.\" notice, this list of conditions and the following disclaimer. 12.\" 2. The name of the author may not be used to endorse or promote products 13.\" derived from this software without specific prior written permission. 14.\" 15.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 16.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 17.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 18.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 21.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25.\" 26.Dd $Mdocdate: March 31 2022 $ 27.Dt EVENT_INIT 3 28.Os 29.Sh NAME 30.Nm event_init , 31.Nm event_dispatch , 32.Nm event_set , 33.Nm event_add , 34.Nm event_del , 35.Nm event_pending , 36.Nm event_initialized , 37.Nm evtimer_set , 38.Nm evtimer_add , 39.Nm evtimer_del , 40.Nm evtimer_pending , 41.Nm evtimer_initialized , 42.Nm signal_set , 43.Nm signal_add , 44.Nm signal_del , 45.Nm signal_pending , 46.Nm signal_initialized , 47.Nm event_once , 48.Nm event_loop , 49.Nm event_loopexit , 50.Nm event_loopbreak , 51.Nm event_asr_run , 52.Nm event_asr_abort , 53.Nm event_priority_init , 54.Nm event_priority_set , 55.Nm event_base_dispatch , 56.Nm event_base_loop , 57.Nm event_base_loopexit , 58.Nm event_base_loopbreak , 59.Nm event_base_set , 60.Nm event_base_once , 61.Nm event_base_free , 62.Nm bufferevent_base_set , 63.Nm bufferevent_new , 64.Nm bufferevent_free , 65.Nm bufferevent_write , 66.Nm bufferevent_write_buffer , 67.Nm bufferevent_read , 68.Nm bufferevent_enable , 69.Nm bufferevent_disable , 70.Nm bufferevent_settimeout , 71.Nm bufferevent_setwatermark , 72.Nm EVBUFFER_INPUT , 73.Nm EVBUFFER_OUTPUT 74.Nd execute a function when a specific event occurs 75.Sh SYNOPSIS 76.In sys/time.h 77.In event.h 78.Ft "struct event_base *" 79.Fn "event_init" "void" 80.Ft int 81.Fn "event_dispatch" "void" 82.Ft void 83.Fn "event_set" "struct event *ev" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" 84.Ft int 85.Fn "event_add" "struct event *ev" "const struct timeval *tv" 86.Ft int 87.Fn "event_del" "struct event *ev" 88.Ft int 89.Fn "event_pending" "struct event *ev" "short event" "struct timeval *tv" 90.Ft int 91.Fn "event_initialized" "struct event *ev" 92.Ft void 93.Fn "evtimer_set" "struct event *ev" "void (*fn)(int, short, void *)" "void *arg" 94.Ft void 95.Fn "evtimer_add" "struct event *ev" "const struct timeval *tv" 96.Ft void 97.Fn "evtimer_del" "struct event *ev" 98.Ft int 99.Fn "evtimer_pending" "struct event *ev" "struct timeval *tv" 100.Ft int 101.Fn "evtimer_initialized" "struct event *ev" 102.Ft void 103.Fn "signal_set" "struct event *ev" "int signal" "void (*fn)(int, short, void *)" "void *arg" 104.Ft void 105.Fn "signal_add" "struct event *ev" "const struct timeval *tv" 106.Ft void 107.Fn "signal_del" "struct event *ev" 108.Ft int 109.Fn "signal_pending" "struct event *ev" "struct timeval *tv" 110.Ft int 111.Fn "signal_initialized" "struct event *ev" 112.Ft int 113.Fn "event_once" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "const struct timeval *tv" 114.Ft int 115.Fn "event_loop" "int flags" 116.Ft int 117.Fn "event_loopexit" "const struct timeval *tv" 118.Ft int 119.Fn "event_loopbreak" "void" 120.Ft "struct event_asr *" 121.Fn event_asr_run "struct asr_query *aq" "void (*fn)(struct asr_result *, void *)" "void *arg" 122.Ft "void" 123.Fn event_asr_abort "struct event_asr *eva" 124.Ft int 125.Fn "event_priority_init" "int npriorities" 126.Ft int 127.Fn "event_priority_set" "struct event *ev" "int priority" 128.Ft int 129.Fn "event_base_dispatch" "struct event_base *base" 130.Ft int 131.Fn "event_base_loop" "struct event_base *base" "int flags" 132.Ft int 133.Fn "event_base_loopexit" "struct event_base *base" "const struct timeval *tv" 134.Ft int 135.Fn "event_base_loopbreak" "struct event_base *base" 136.Ft int 137.Fn "event_base_set" "struct event_base *base" "struct event *ev" 138.Ft int 139.Fn "event_base_once" "struct event_base *base" "int fd" "short event" "void (*fn)(int, short, void *)" "void *arg" "const struct timeval *tv" 140.Ft void 141.Fn "event_base_free" "struct event_base *base" 142.Ft int 143.Fn "bufferevent_base_set" "struct event_base *base" "struct bufferevent *bufev" 144.Ft "struct bufferevent *" 145.Fn "bufferevent_new" "int fd" "evbuffercb readcb" "evbuffercb writecb" "everrorcb errorcb" "void *cbarg" 146.Ft void 147.Fn "bufferevent_free" "struct bufferevent *bufev" 148.Ft int 149.Fn "bufferevent_write" "struct bufferevent *bufev" "const void *data" "size_t size" 150.Ft int 151.Fn "bufferevent_write_buffer" "struct bufferevent *bufev" "struct evbuffer *buf" 152.Ft size_t 153.Fn "bufferevent_read" "struct bufferevent *bufev" "void *data" "size_t size" 154.Ft int 155.Fn "bufferevent_enable" "struct bufferevent *bufev" "short event" 156.Ft int 157.Fn "bufferevent_disable" "struct bufferevent *bufev" "short event" 158.Ft void 159.Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int timeout_write" 160.Ft void 161.Fn "bufferevent_setwatermark" "struct bufferevent *bufev" "short events" "size_t lowmark" "size_t highmark" 162.Ft "struct evbuffer *" 163.Fn "EVBUFFER_INPUT" "struct bufferevent *bufev" 164.Ft "struct evbuffer *" 165.Fn "EVBUFFER_OUTPUT" "struct bufferevent *bufev" 166.Sh DESCRIPTION 167The 168.Nm event 169API provides a mechanism to execute a function when a specific event 170on a file descriptor occurs or after a given time has passed. 171.Pp 172The 173.Nm event 174API needs to be initialized with 175.Fn event_init 176before it can be used. 177.Pp 178In order to process events, an application needs to call 179.Fn event_dispatch . 180This function only returns on error, and should replace the event core 181of the application program. 182.Pp 183The function 184.Fn event_set 185prepares the event structure 186.Fa ev 187to be used in future calls to 188.Fn event_add 189and 190.Fn event_del . 191The event will be prepared to call the function specified by the 192.Fa fn 193argument with an 194.Fa int 195argument indicating the file descriptor, a 196.Fa short 197argument indicating the type of event, and a 198.Fa void * 199argument given in the 200.Fa arg 201argument. 202The 203.Fa fd 204indicates the file descriptor that should be monitored for events. 205The events can be either 206.Va EV_READ , 207.Va EV_WRITE , 208or both, 209indicating that an application can read or write from the file descriptor 210respectively without blocking. 211.Pp 212The function 213.Fa fn 214will be called with the file descriptor that triggered the event and 215the type of event which will be either 216.Va EV_TIMEOUT , 217.Va EV_SIGNAL , 218.Va EV_READ , 219or 220.Va EV_WRITE . 221Additionally, an event which has registered interest in more than one of the 222preceding events, via bitwise-OR to 223.Fn event_set , 224can provide its callback function with a bitwise-OR of more than one triggered 225event. 226The additional flag 227.Va EV_PERSIST 228makes an 229.Fn event_add 230persistent until 231.Fn event_del 232has been called. 233.Pp 234Once initialized, the 235.Fa ev 236structure can be used repeatedly with 237.Fn event_add 238and 239.Fn event_del 240and does not need to be reinitialized unless the function called and/or 241the argument to it are to be changed. 242However, when an 243.Fa ev 244structure has been added to libevent using 245.Fn event_add 246the structure must persist until the event occurs (assuming 247.Fa EV_PERSIST 248is not set) or is removed 249using 250.Fn event_del . 251You may not reuse the same 252.Fa ev 253structure for multiple monitored descriptors; each descriptor 254needs its own 255.Fa ev . 256.Pp 257The function 258.Fn event_add 259schedules the execution of the 260.Fa ev 261event when the event specified in 262.Fn event_set 263occurs or in at least the time specified in the 264.Fa tv . 265If 266.Fa tv 267is 268.Dv NULL , 269no timeout occurs and the function will only be called 270if a matching event occurs on the file descriptor. 271The event in the 272.Fa ev 273argument must be already initialized by 274.Fn event_set 275and may not be used in calls to 276.Fn event_set 277until it has timed out or been removed with 278.Fn event_del . 279If the event in the 280.Fa ev 281argument already has a scheduled timeout, the old timeout will be 282replaced by the new one. 283.Pp 284The function 285.Fn event_del 286will cancel the event in the argument 287.Fa ev . 288If the event has already executed or has never been added, 289the call will have no effect. 290.Pp 291The functions 292.Fn evtimer_set , 293.Fn evtimer_add , 294.Fn evtimer_del , 295.Fn evtimer_initialized , 296and 297.Fn evtimer_pending 298are abbreviations for common situations where only a timeout is required. 299The file descriptor passed will be \-1, and the event type will be 300.Va EV_TIMEOUT . 301.Pp 302The functions 303.Fn signal_set , 304.Fn signal_add , 305.Fn signal_del , 306.Fn signal_initialized , 307and 308.Fn signal_pending 309are abbreviations. 310The event type will be a persistent 311.Va EV_SIGNAL . 312That means 313.Fn signal_set 314adds 315.Va EV_PERSIST . 316.Pp 317The function 318.Fn event_once 319is similar to 320.Fn event_set . 321However, it schedules a callback to be called exactly once and does not 322require the caller to prepare an 323.Fa event 324structure. 325This function supports 326.Fa EV_TIMEOUT , 327.Fa EV_READ , 328and 329.Fa EV_WRITE . 330.Pp 331The 332.Fn event_pending 333function can be used to check if the event specified by 334.Fa event 335is pending to run. 336If 337.Va EV_TIMEOUT 338was specified and 339.Fa tv 340is not 341.Dv NULL , 342the expiration time of the event will be returned in 343.Fa tv . 344.Pp 345The 346.Fn event_initialized 347macro can be used to check if an event has been initialized. 348.Pp 349The 350.Nm event_loop 351function provides an interface for single pass execution of pending 352events. 353The flags 354.Va EVLOOP_ONCE 355and 356.Va EVLOOP_NONBLOCK 357are recognized. 358The 359.Nm event_loopexit 360function exits from the event loop. 361The next 362.Fn event_loop 363iteration after the 364given timer expires will complete normally (handling all queued events) then 365exit without blocking for events again. 366Subsequent invocations of 367.Fn event_loop 368will proceed normally. 369The 370.Nm event_loopbreak 371function exits from the event loop immediately. 372.Fn event_loop 373will abort after the next event is completed; 374.Fn event_loopbreak 375is typically invoked from this event's callback. 376This behavior is analogous to the "break;" statement. 377Subsequent invocations of 378.Fn event_loop 379will proceed normally. 380.Pp 381It is the responsibility of the caller to provide these functions with 382pre-allocated event structures. 383.Pp 384The 385.Fn event_asr_run 386function is used to schedule the asynchronous resolver query 387.Ar aq 388to run within a libevent event loop, and call the 389.Ar fn 390callback when the result is available. 391The extra 392.Ar arg 393parameter is passed to the callback. 394The user does not need to set up an event structure for using this function. 395It returns an opaque handle representing the running query. 396This handle becomes invalid before the callback is run. 397It can be cancelled by calling the 398.Fn event_asr_abort 399function. 400See 401.Xr asr_run 3 402for details on constructing asynchronous resolver queries. 403.Sh EVENT PRIORITIES 404By default 405.Nm libevent 406schedules all active events with the same priority. 407However, sometimes it is desirable to process some events with a higher 408priority than others. 409For that reason, 410.Nm libevent 411supports strict priority queues. 412Active events with a lower priority are always processed before events 413with a higher priority. 414.Pp 415The number of different priorities can be set initially with the 416.Fn event_priority_init 417function. 418This function should be called before the first call to 419.Fn event_dispatch . 420The 421.Fn event_priority_set 422function can be used to assign a priority to an event. 423By default, 424.Nm libevent 425assigns the middle priority to all events unless their priority 426is explicitly set. 427.Sh THREAD SAFE EVENTS 428The 429.Nm event 430API has experimental support for thread-safe events. 431When initializing the library via 432.Fn event_init , 433an event base is returned. 434This event base can be used in conjunction with calls to 435.Fn event_base_set , 436.Fn event_base_dispatch , 437.Fn event_base_loop , 438.Fn event_base_loopexit , 439.Fn bufferevent_base_set 440and 441.Fn event_base_free . 442.Fn event_base_set 443should be called after preparing an event with 444.Fn event_set , 445as 446.Fn event_set 447assigns the provided event to the most recently created event base. 448.Fn bufferevent_base_set 449should be called after preparing a bufferevent with 450.Fn bufferevent_new . 451.Fn event_base_free 452should be used to free memory associated with the event base 453when it is no longer needed. 454.Sh BUFFERED EVENTS 455The 456.Nm event 457API provides an abstraction on top of the regular event callbacks. 458This abstraction is called a 459.Va "buffered event" . 460A buffered event provides input and output buffers that get filled 461and drained automatically. 462The user of a buffered event no longer deals directly with the IO, 463but instead is reading from input and writing to output buffers. 464.Pp 465A new bufferevent is created by 466.Fn bufferevent_new . 467The parameter 468.Fa fd 469specifies the file descriptor from which data is read and written to. 470This file descriptor is not allowed to be a 471.Xr pipe 2 . 472The next three parameters are callbacks. 473The read and write callback have the following form: 474.Ft void 475.Fn "(*cb)" "struct bufferevent *bufev" "void *arg" . 476The error callback has the following form: 477.Ft void 478.Fn "(*cb)" "struct bufferevent *bufev" "short what" "void *arg" . 479The argument is specified by the fourth parameter 480.Fa "cbarg" . 481A 482.Fa bufferevent struct 483pointer is returned on success, NULL on error. 484Both the read and the write callback may be NULL. 485The error callback has to be always provided. 486.Pp 487Once initialized, the bufferevent structure can be used repeatedly with 488.Fn bufferevent_enable 489and 490.Fn bufferevent_disable . 491The flags parameter can be a combination of 492.Va EV_READ 493and 494.Va EV_WRITE . 495When read enabled, the bufferevent will try to read from the file 496descriptor and call the read callback. 497The write callback is executed 498whenever the output buffer is drained below the write low watermark, 499which is 500.Va 0 501by default. 502.Pp 503The 504.Fn bufferevent_setwatermark 505function can set the low and high watermarks 506for read and write events. 507The 508.Fa events 509can be either 510.Va EV_READ , 511.Va EV_WRITE 512or both. 513When used with 514.Va EV_READ , 515a bufferevent does not invoke the user read callback 516unless there is at least 517.Fa lowmark 518data in the buffer. 519If the read buffer is beyond 520.Fa highmark , 521the bufferevent stops reading from the file descriptor. 522When used with 523.Va EV_WRITE , 524the user write callback is invoked whenever the buffered data 525falls below 526.Fa lowmark . 527.Pp 528The 529.Fn bufferevent_write 530function can be used to write data to the file descriptor. 531The data is appended to the output buffer and written to the descriptor 532automatically as it becomes available for writing. 533.Fn bufferevent_write 534returns 0 on success or \-1 on failure. 535The 536.Fn bufferevent_read 537function is used to read data from the input buffer, 538returning the amount of data read. 539.Pp 540If multiple bases are in use, 541.Fn bufferevent_base_set 542must be called before 543enabling the bufferevent for the first time. 544.Pp 545The 546.Fn EVBUFFER_INPUT 547and 548.Fn EVBUFFER_OUTPUT 549macros return a pointer to evbuffer 550.Fa input 551and 552.Fa output 553respectively for the specified bufferevent 554.Fa bufev . 555.Sh ADDITIONAL NOTES 556It is possible to disable support for 557.Va kqueue , poll 558or 559.Va select 560by setting the environment variable 561.Va EVENT_NOKQUEUE , EVENT_NOPOLL 562or 563.Va EVENT_NOSELECT , 564respectively. 565By setting the environment variable 566.Va EVENT_SHOW_METHOD , 567.Nm libevent 568displays the kernel notification method that it uses. 569.Sh RETURN VALUES 570Upon successful completion 571.Fn event_add 572and 573.Fn event_del 574return 0. 575Otherwise, \-1 is returned and the global variable errno is 576set to indicate the error. 577.Sh SEE ALSO 578.Xr kqueue 2 , 579.Xr poll 2 , 580.Xr select 2 , 581.Xr asr_run 3 , 582.Xr evbuffer_new 3 , 583.Xr timeout 9 584.Sh HISTORY 585The 586.Nm event 587API manpage is based on the 588.Xr timeout 9 589manpage by Artur Grabowski. 590Support for real-time signals was added by Taral. 591.Sh AUTHORS 592The 593.Nm event 594library was written by 595.An Niels Provos . 596