Annotation of embedaddon/libpdel/util/pevent.3, revision 1.1
1.1 ! misho 1: .\" Copyright (c) 2001-2002 Packet Design, LLC.
! 2: .\" All rights reserved.
! 3: .\"
! 4: .\" Subject to the following obligations and disclaimer of warranty,
! 5: .\" use and redistribution of this software, in source or object code
! 6: .\" forms, with or without modifications are expressly permitted by
! 7: .\" Packet Design; provided, however, that:
! 8: .\"
! 9: .\" (i) Any and all reproductions of the source or object code
! 10: .\" must include the copyright notice above and the following
! 11: .\" disclaimer of warranties; and
! 12: .\" (ii) No rights are granted, in any manner or form, to use
! 13: .\" Packet Design trademarks, including the mark "PACKET DESIGN"
! 14: .\" on advertising, endorsements, or otherwise except as such
! 15: .\" appears in the above copyright notice or in the software.
! 16: .\"
! 17: .\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
! 18: .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
! 19: .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
! 20: .\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
! 21: .\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
! 22: .\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
! 23: .\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
! 24: .\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
! 25: .\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
! 26: .\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
! 27: .\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
! 28: .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
! 29: .\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
! 30: .\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
! 31: .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 32: .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
! 33: .\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
! 34: .\" THE POSSIBILITY OF SUCH DAMAGE.
! 35: .\"
! 36: .\" Author: Archie Cobbs <archie@freebsd.org>
! 37: .\"
! 38: .\" $Id: pevent.3,v 1.8 2004/06/02 17:24:39 archie Exp $
! 39: .\"
! 40: .Dd April 22, 2002
! 41: .Dt PEVENT 3
! 42: .Os
! 43: .Sh NAME
! 44: .Nm pevent
! 45: .Nd pthread event library
! 46: .Sh LIBRARY
! 47: PDEL Library (libpdel, \-lpdel)
! 48: .Sh SYNOPSIS
! 49: .In pthread.h
! 50: .In pdel/util/pevent.h
! 51: .Ft "struct pevent_ctx *"
! 52: .Fn pevent_ctx_create "const char *mtype" "const pthread_attr_t *attr"
! 53: .Ft void
! 54: .Fn pevent_ctx_destroy "struct pevent_ctx **ctxp"
! 55: .Ft u_int
! 56: .Fn pevent_ctx_count "struct pevent_ctx *ctx"
! 57: .Ft int
! 58: .Fn pevent_register "struct pevent_ctx *ctx" "struct pevent **peventp" "int flags" "pthread_mutex_t *mutex" "pevent_handler_t *handler" "void *arg" "enum pevent_type type" "..."
! 59: .Ft void
! 60: .Fn pevent_unregister "struct pevent **eventp"
! 61: .Ft void
! 62: .Fn pevent_trigger "struct pevent *event"
! 63: .Ft int
! 64: .Fn pevent_get_info "struct pevent *event" "struct pevent_info *info"
! 65: .Sh DESCRIPTION
! 66: These functions support event-driven programming.
! 67: Event-driven programming is simpler and more efficient than threaded
! 68: programming because only a single thread is created to handle all
! 69: blocking operations, rather than a new thread per operation.
! 70: However, because the thread's stack cannot be used to store information
! 71: between events, each event must be handled to completion, i.e., the
! 72: event handlers must not block before returning.
! 73: .Pp
! 74: Event handlers that block may also be used with these routines, but only
! 75: if a separate thread is spawned for the handler (see below).
! 76: .\"
! 77: .Ss Event contexts
! 78: .\"
! 79: .Fn pevent_ctx_create
! 80: creates a new event context, which is used to register events.
! 81: All events registered with the same event context will be serviced by
! 82: the single thread associated with that event context.
! 83: .Pp
! 84: The scheduling attributes contained in
! 85: .Fa "*attr"
! 86: are used when creating this thread; if
! 87: .Fa attr
! 88: is
! 89: .Dv NULL
! 90: then the default thread attributes are used.
! 91: Since
! 92: .Fn pevent_ctx_create
! 93: makes a copy of these attributes,
! 94: .Fa attr
! 95: may be discarded when
! 96: .Fn pevent_ctx_create
! 97: returns.
! 98: .Pp
! 99: .Fa mtype
! 100: is the
! 101: .Xr typed_mem 3
! 102: memory type used when allocating memory for the event context.
! 103: .Pp
! 104: .Fn pevent_ctx_destroy
! 105: destroys an event context.
! 106: Any events still registered are automatically unregistered.
! 107: Upon return,
! 108: .Fa "*ctxp"
! 109: is set to
! 110: .Dv NULL .
! 111: If
! 112: .Fa "*ctxp"
! 113: is already
! 114: .Dv NULL
! 115: when
! 116: .Fn pevent_ctx_destroy
! 117: is invoked, nothing happens.
! 118: .Pp
! 119: It is safe to call
! 120: .Fn pevent_ctx_destroy
! 121: from within an event handler function.
! 122: .Pp
! 123: .Fn pevent_ctx_count
! 124: returns the number of events currently registered with
! 125: .Fa ctx .
! 126: .\"
! 127: .Ss Events
! 128: .\"
! 129: .Fn pevent_register
! 130: creates a new event and registers it with
! 131: .Fa ctx .
! 132: If successful, zero is returned and a non-
! 133: .Dv NULL
! 134: reference to the event is stored in
! 135: .Fa "*peventp" .
! 136: When
! 137: .Fn pevent_register
! 138: is invoked,
! 139: .Fa "*peventp"
! 140: must be
! 141: .Dv NULL
! 142: or else an error will be returned with
! 143: .Va errno
! 144: set to
! 145: .Er EBUSY .
! 146: If
! 147: .Fn pevent_register
! 148: returns an error,
! 149: .Fa "*peventp"
! 150: will be unmodified.
! 151: .Pp
! 152: .Fa handler
! 153: must point to a function having this type:
! 154: .Bd -literal -offset 3n
! 155: typedef void pevent_handler_t(void *arg);
! 156: .Ed
! 157: .Pp
! 158: When the event occurs,
! 159: .Fa "*peventp"
! 160: is set to
! 161: .Dv NULL
! 162: and then
! 163: .Fn handler arg
! 164: is invoked.
! 165: Therefore,
! 166: .Fa "*peventp"
! 167: is not equal to
! 168: .Dv NULL
! 169: if and only if the event is still pending.
! 170: For this to work,
! 171: .Fa "*peventp"
! 172: must remain valid and unmodified while the event is pending,
! 173: and the user code must initialize
! 174: .Fa peventp
! 175: to
! 176: .Dv NULL
! 177: before the first call to
! 178: .Fn pevent_register .
! 179: .Pp
! 180: The
! 181: .Fa type
! 182: and subsequent argument(s) define the event itself;
! 183: .Fa type
! 184: may have be one of the following values:
! 185: .Bl -tag -offset 3n -width PEVENT_MESG_PORT
! 186: .It Dv PEVENT_READ
! 187: Readable condition on a file descriptor.
! 188: The next argument must have type
! 189: .Li int .
! 190: .It Dv PEVENT_WRITE
! 191: Writable condition on a file descriptor.
! 192: The next argument must have type
! 193: .Li int .
! 194: .It Dv PEVENT_TIME
! 195: Time passage.
! 196: The next argument must have type
! 197: .Li int ,
! 198: and it is the relative time delay in milliseconds.
! 199: Negative delay values are silently converted to zero.
! 200: .It Dv PEVENT_MESG_PORT
! 201: Message(s) available on a message port.
! 202: The next argument must have type
! 203: .Li "struct mesg_port *".
! 204: .It Dv PEVENT_USER
! 205: User-triggered event.
! 206: No further arguments are required.
! 207: .El
! 208: .Pp
! 209: The
! 210: .Fa flags
! 211: parameter may contain any of the following values OR'd together:
! 212: .Pp
! 213: .Bl -tag -offset 3n -width PEVENT_OWN_THREADX
! 214: .It Li PEVENT_RECURRING
! 215: The event is recurring.
! 216: .It Li PEVENT_OWN_THREAD
! 217: Invoke
! 218: .Fn handler
! 219: in a separate thread.
! 220: .El
! 221: .Pp
! 222: .Dv PEVENT_RECURRING
! 223: causes the event to be automatically re-registered just before
! 224: each invocation of
! 225: .Fn handler .
! 226: In particular, this means that
! 227: .Fa "*peventp"
! 228: will not be
! 229: .Dv NULL
! 230: when
! 231: .Fn handler
! 232: is invoked.
! 233: .Pp
! 234: .Dv PEVENT_OWN_THREAD
! 235: causes a new thread to be spawned for each invocation of
! 236: .Fn handler ;
! 237: this thread may block, exit, or be canceled, and is by default not joinable.
! 238: If this flag is not set,
! 239: .Fn handler
! 240: will execute in the event context's main thread, in which case
! 241: .Fn handler
! 242: .Em "must not"
! 243: block or exit and the thread
! 244: .Em "must not"
! 245: be canceled.
! 246: .Pp
! 247: .Fn pevent_unregister
! 248: unregisters the event referenced by
! 249: .Fa "*peventp" .
! 250: Upon return,
! 251: .Fa "*peventp"
! 252: is set to
! 253: .Dv NULL .
! 254: If
! 255: .Fa "*peventp"
! 256: is already
! 257: .Dv NULL
! 258: when
! 259: .Fn pevent_unregister
! 260: is invoked, nothing happens.
! 261: .Pp
! 262: .Fn pevent_trigger
! 263: manually triggers an event, causing its handler to be invoked.
! 264: Although intended for use with
! 265: .Dv PEVENT_USER
! 266: events, it will work with any event.
! 267: The
! 268: .Fa event
! 269: may be
! 270: .Dv NULL ,
! 271: in which case nothing happens.
! 272: .Pp
! 273: .Fn pevent_get_info
! 274: returns the type and parameters associated with
! 275: .Fa event
! 276: by filling in the
! 277: .Li "struct pevent_info"
! 278: structure pointed to by
! 279: .Fa info :
! 280: .Bd -literal -offset 3n
! 281: struct pevent_info {
! 282: enum pevent_type type; /* event type */
! 283: union {
! 284: int fd; /* file descriptor (READ, WRITE) */
! 285: int millis; /* delay in milliseconds (TIME) */
! 286: struct mesg_port *port; /* message port (MESG_PORT) */
! 287: }; u;
! 288: };
! 289: .Ed
! 290: .\"
! 291: .Ss Synchronization
! 292: .\"
! 293: .Fn pevent_ctx_count ,
! 294: .Fn pevent_register ,
! 295: .Fn pevent_unregister ,
! 296: .Fn pevent_trigger ,
! 297: and
! 298: .Fn pevent_get_info
! 299: may all safely be called from different threads simultaneously.
! 300: However, there are inherent race conditions between an event's
! 301: .Fn handler
! 302: being invoked and reading the value of
! 303: .Fa "*peventp"
! 304: or unregistering the event with
! 305: .Fn pevent_unregister .
! 306: The
! 307: .Fa mutex
! 308: parameter to
! 309: .Fn pevent_register
! 310: can be used to avoid these problems.
! 311: .Pp
! 312: If a non-
! 313: .Dv NULL
! 314: .Fa mutex
! 315: is provided to
! 316: .Fn pevent_register ,
! 317: then
! 318: .Nm pevent
! 319: will acquire
! 320: .Fa "*mutex"
! 321: just before setting
! 322: .Fa "*pevent"
! 323: to
! 324: .Dv NULL
! 325: and invoking
! 326: .Fn handler ,
! 327: and
! 328: .Fa "*mutex"
! 329: will be automatically released when
! 330: .Fn handler
! 331: returns (or, in the case of
! 332: .Dv PEVENT_OWN_THREAD ,
! 333: the handler thread exits by any means).
! 334: If the user code acquires this mutex before any calls to
! 335: .Fn pevent_register
! 336: or
! 337: .Fn pevent_unregister ,
! 338: or before accessing
! 339: .Fa "*eventp" ,
! 340: then
! 341: .Fa "*eventp"
! 342: will always reflect the 'registered' state of the event and
! 343: .Fn handler
! 344: is guaranteed to never be invoked after
! 345: .Fn pevent_unregister
! 346: returns.
! 347: .Sh RETURN VALUES
! 348: .Fn pevent_ctx_create ,
! 349: .Fn pevent_register ,
! 350: and
! 351: .Fn pevent_get_info
! 352: return
! 353: .Dv NULL
! 354: or -1 to indicate an error,
! 355: with
! 356: .Va errno
! 357: set appropriately.
! 358: .Sh SEE ALSO
! 359: .Xr libpdel 3 ,
! 360: .Xr mesg_port 3 ,
! 361: .Xr paction 3 ,
! 362: .Xr pthread 3 ,
! 363: .Xr typed_mem 3
! 364: .Sh HISTORY
! 365: The PDEL library was developed at Packet Design, LLC.
! 366: .Dv "http://www.packetdesign.com/"
! 367: .Sh AUTHORS
! 368: .An Archie Cobbs Aq archie@freebsd.org
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>