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>