File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / util / pevent.3
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:25:53 2012 UTC (12 years, 4 months ago) by misho
Branches: libpdel, MAIN
CVS tags: v0_5_3, HEAD
libpdel

.\" Copyright (c) 2001-2002 Packet Design, LLC.
.\" All rights reserved.
.\" 
.\" Subject to the following obligations and disclaimer of warranty,
.\" use and redistribution of this software, in source or object code
.\" forms, with or without modifications are expressly permitted by
.\" Packet Design; provided, however, that:
.\" 
.\"    (i)  Any and all reproductions of the source or object code
.\"         must include the copyright notice above and the following
.\"         disclaimer of warranties; and
.\"    (ii) No rights are granted, in any manner or form, to use
.\"         Packet Design trademarks, including the mark "PACKET DESIGN"
.\"         on advertising, endorsements, or otherwise except as such
.\"         appears in the above copyright notice or in the software.
.\" 
.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
.\" OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
.\" RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
.\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" Author: Archie Cobbs <archie@freebsd.org>
.\"
.\" $Id: pevent.3,v 1.1.1.1 2012/02/21 23:25:53 misho Exp $
.\"
.Dd April 22, 2002
.Dt PEVENT 3
.Os
.Sh NAME
.Nm pevent
.Nd pthread event library
.Sh LIBRARY
PDEL Library (libpdel, \-lpdel)
.Sh SYNOPSIS
.In pthread.h
.In pdel/util/pevent.h
.Ft "struct pevent_ctx *"
.Fn pevent_ctx_create "const char *mtype" "const pthread_attr_t *attr"
.Ft void
.Fn pevent_ctx_destroy "struct pevent_ctx **ctxp"
.Ft u_int
.Fn pevent_ctx_count "struct pevent_ctx *ctx"
.Ft int
.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" "..."
.Ft void
.Fn pevent_unregister "struct pevent **eventp"
.Ft void
.Fn pevent_trigger "struct pevent *event"
.Ft int
.Fn pevent_get_info "struct pevent *event" "struct pevent_info *info"
.Sh DESCRIPTION
These functions support event-driven programming.
Event-driven programming is simpler and more efficient than threaded
programming because only a single thread is created to handle all
blocking operations, rather than a new thread per operation.
However, because the thread's stack cannot be used to store information
between events, each event must be handled to completion, i.e., the
event handlers must not block before returning.
.Pp
Event handlers that block may also be used with these routines, but only
if a separate thread is spawned for the handler (see below).
.\"
.Ss Event contexts
.\"
.Fn pevent_ctx_create
creates a new event context, which is used to register events.
All events registered with the same event context will be serviced by
the single thread associated with that event context.
.Pp
The scheduling attributes contained in
.Fa "*attr"
are used when creating this thread; if
.Fa attr
is
.Dv NULL
then the default thread attributes are used.
Since
.Fn pevent_ctx_create
makes a copy of these attributes,
.Fa attr
may be discarded when
.Fn pevent_ctx_create
returns.
.Pp
.Fa mtype
is the
.Xr typed_mem 3
memory type used when allocating memory for the event context.
.Pp
.Fn pevent_ctx_destroy
destroys an event context.
Any events still registered are automatically unregistered.
Upon return,
.Fa "*ctxp"
is set to
.Dv NULL .
If
.Fa "*ctxp"
is already
.Dv NULL
when
.Fn pevent_ctx_destroy
is invoked, nothing happens.
.Pp
It is safe to call
.Fn pevent_ctx_destroy
from within an event handler function.
.Pp
.Fn pevent_ctx_count
returns the number of events currently registered with
.Fa ctx .
.\"
.Ss Events
.\"
.Fn pevent_register
creates a new event and registers it with
.Fa ctx .
If successful, zero is returned and a non-
.Dv NULL
reference to the event is stored in
.Fa "*peventp" .
When
.Fn pevent_register
is invoked,
.Fa "*peventp"
must be
.Dv NULL
or else an error will be returned with
.Va errno
set to
.Er EBUSY .
If
.Fn pevent_register
returns an error,
.Fa "*peventp"
will be unmodified.
.Pp
.Fa handler
must point to a function having this type:
.Bd -literal -offset 3n
typedef void pevent_handler_t(void *arg);
.Ed
.Pp
When the event occurs,
.Fa "*peventp"
is set to
.Dv NULL
and then
.Fn handler arg
is invoked.
Therefore,
.Fa "*peventp"
is not equal to
.Dv NULL
if and only if the event is still pending.
For this to work,
.Fa "*peventp"
must remain valid and unmodified while the event is pending,
and the user code must initialize
.Fa peventp
to
.Dv NULL
before the first call to
.Fn pevent_register .
.Pp
The
.Fa type
and subsequent argument(s) define the event itself;
.Fa type
may have be one of the following values:
.Bl -tag -offset 3n -width PEVENT_MESG_PORT
.It Dv PEVENT_READ
Readable condition on a file descriptor.
The next argument must have type
.Li int .
.It Dv PEVENT_WRITE
Writable condition on a file descriptor.
The next argument must have type
.Li int .
.It Dv PEVENT_TIME
Time passage.
The next argument must have type
.Li int ,
and it is the relative time delay in milliseconds.
Negative delay values are silently converted to zero.
.It Dv PEVENT_MESG_PORT
Message(s) available on a message port.
The next argument must have type
.Li "struct mesg_port *".
.It Dv PEVENT_USER
User-triggered event.
No further arguments are required.
.El
.Pp
The
.Fa flags
parameter may contain any of the following values OR'd together:
.Pp
.Bl -tag -offset 3n -width PEVENT_OWN_THREADX
.It Li PEVENT_RECURRING
The event is recurring.
.It Li PEVENT_OWN_THREAD
Invoke
.Fn handler
in a separate thread.
.El
.Pp
.Dv PEVENT_RECURRING
causes the event to be automatically re-registered just before
each invocation of
.Fn handler .
In particular, this means that
.Fa "*peventp"
will not be
.Dv NULL
when
.Fn handler
is invoked.
.Pp
.Dv PEVENT_OWN_THREAD
causes a new thread to be spawned for each invocation of
.Fn handler ;
this thread may block, exit, or be canceled, and is by default not joinable.
If this flag is not set,
.Fn handler
will execute in the event context's main thread, in which case
.Fn handler
.Em "must not"
block or exit and the thread
.Em "must not"
be canceled.
.Pp
.Fn pevent_unregister
unregisters the event referenced by
.Fa "*peventp" .
Upon return,
.Fa "*peventp"
is set to
.Dv NULL .
If
.Fa "*peventp"
is already
.Dv NULL
when
.Fn pevent_unregister
is invoked, nothing happens.
.Pp
.Fn pevent_trigger
manually triggers an event, causing its handler to be invoked.
Although intended for use with
.Dv PEVENT_USER
events, it will work with any event.
The
.Fa event
may be
.Dv NULL ,
in which case nothing happens.
.Pp
.Fn pevent_get_info
returns the type and parameters associated with
.Fa event
by filling in the
.Li "struct pevent_info"
structure pointed to by
.Fa info :
.Bd -literal -offset 3n
struct pevent_info {
    enum pevent_type    type;    /* event type */
    union {
        int              fd;       /* file descriptor (READ, WRITE) */
        int              millis;   /* delay in milliseconds (TIME) */
        struct mesg_port *port;    /* message port (MESG_PORT) */
    };                  u;
};
.Ed
.\"
.Ss Synchronization
.\"
.Fn pevent_ctx_count ,
.Fn pevent_register ,
.Fn pevent_unregister ,
.Fn pevent_trigger ,
and
.Fn pevent_get_info
may all safely be called from different threads simultaneously.
However, there are inherent race conditions between an event's
.Fn handler
being invoked and reading the value of
.Fa "*peventp"
or unregistering the event with
.Fn pevent_unregister .
The
.Fa mutex
parameter to
.Fn pevent_register
can be used to avoid these problems.
.Pp
If a non-
.Dv NULL
.Fa mutex
is provided to
.Fn pevent_register ,
then
.Nm pevent
will acquire
.Fa "*mutex"
just before setting
.Fa "*pevent"
to
.Dv NULL
and invoking
.Fn handler ,
and
.Fa "*mutex"
will be automatically released when
.Fn handler
returns (or, in the case of
.Dv PEVENT_OWN_THREAD ,
the handler thread exits by any means).
If the user code acquires this mutex before any calls to
.Fn pevent_register
or
.Fn pevent_unregister ,
or before accessing
.Fa "*eventp" ,
then
.Fa "*eventp"
will always reflect the 'registered' state of the event and
.Fn handler
is guaranteed to never be invoked after
.Fn pevent_unregister
returns.
.Sh RETURN VALUES
.Fn pevent_ctx_create ,
.Fn pevent_register ,
and
.Fn pevent_get_info
return
.Dv NULL
or -1 to indicate an error,
with
.Va errno
set appropriately.
.Sh SEE ALSO
.Xr libpdel 3 ,
.Xr mesg_port 3 ,
.Xr paction 3 ,
.Xr pthread 3 ,
.Xr typed_mem 3
.Sh HISTORY
The PDEL library was developed at Packet Design, LLC.
.Dv "http://www.packetdesign.com/"
.Sh AUTHORS
.An Archie Cobbs Aq archie@freebsd.org

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>