event.3 17 KB

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