|
|
| |
PEVENT(3) |
FreeBSD Library Functions Manual |
PEVENT(3) |
pevent —
pthread event library
PDEL Library (libpdel, -lpdel)
#include <pthread.h>
#include <pdel/util/pevent.h>
struct pevent_ctx *
pevent_ctx_create (const
char *mtype, const
pthread_attr_t *attr);
void
pevent_ctx_destroy (struct
pevent_ctx **ctxp);
u_int
pevent_ctx_count (struct
pevent_ctx *ctx);
int
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, ...);
void
pevent_unregister (struct
pevent **eventp);
void
pevent_trigger (struct
pevent *event);
int
pevent_get_info (struct
pevent *event, struct
pevent_info *info);
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.
Event handlers that block may also be used with these routines,
but only if a separate thread is spawned for the handler (see below).
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.
The scheduling attributes contained in *attr
are used when creating this thread; if attr is
NULL then the default thread attributes are used.
Since pevent_ctx_create () makes a copy of these
attributes, attr may be discarded when
pevent_ctx_create () returns.
mtype is the
typed_mem(3)
memory type used when allocating memory for the event context.
pevent_ctx_destroy () destroys an event
context. Any events still registered are automatically unregistered. Upon
return, *ctxp is set to NULL .
If *ctxp is already NULL when
pevent_ctx_destroy () is invoked, nothing
happens.
It is safe to call pevent_ctx_destroy ()
from within an event handler function.
pevent_ctx_count () returns the number of
events currently registered with ctx.
pevent_register () creates a new event and registers it
with ctx. If successful, zero is returned and a non-
NULL reference to the event is stored in
*peventp. When pevent_register ()
is invoked, *peventp must be
NULL or else an error will be returned with
errno set to EBUSY . If
pevent_register () returns an error,
*peventp will be unmodified.
handler must point to a function having this
type:
typedef void pevent_handler_t(void *arg);
When the event occurs, *peventp is set to
NULL and then
handler (arg) is invoked.
Therefore, *peventp is not equal to
NULL if and only if the event is still pending. For
this to work, *peventp must remain valid and
unmodified while the event is pending, and the user code must initialize
peventp to NULL before the
first call to pevent_register ().
The type and subsequent argument(s) define
the event itself; type may have be one of the
following values:
PEVENT_READ
- Readable condition on a file descriptor. The next argument must have type
int .
PEVENT_WRITE
- Writable condition on a file descriptor. The next argument must have type
int .
PEVENT_TIME
- Time passage. The next argument must have type
int , and it is the relative time delay in
milliseconds. Negative delay values are silently converted to zero.
PEVENT_MESG_PORT
- Message(s) available on a message port. The next argument must have type
struct mesg_port * .
PEVENT_USER
- User-triggered event. No further arguments are required.
The flags parameter may contain any of the
following values OR'd together:
PEVENT_RECURRING causes the event to be
automatically re-registered just before each invocation of
handler (). In particular, this means that
*peventp will not be NULL when
handler () is invoked.
PEVENT_OWN_THREAD causes a new thread to
be spawned for each invocation of handler (); this
thread may block, exit, or be canceled, and is by default not joinable. If
this flag is not set, handler () will execute in the
event context's main thread, in which case handler ()
must not block or exit and the thread must
not be canceled.
pevent_unregister () unregisters the event
referenced by *peventp. Upon return,
*peventp is set to NULL . If
*peventp is already NULL when
pevent_unregister () is invoked, nothing happens.
pevent_trigger () manually triggers an
event, causing its handler to be invoked. Although intended for use with
PEVENT_USER events, it will work with any event. The
event may be NULL , in which
case nothing happens.
pevent_get_info () returns the type and
parameters associated with event by filling in the
struct pevent_info structure pointed to by
info:
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;
};
pevent_ctx_count (),
pevent_register (),
pevent_unregister (),
pevent_trigger (), and
pevent_get_info () may all safely be called from
different threads simultaneously. However, there are inherent race conditions
between an event's handler () being invoked and reading
the value of *peventp or unregistering the event with
pevent_unregister (). The mutex
parameter to pevent_register () can be used to avoid
these problems.
If a non- NULL mutex
is provided to pevent_register (), then
pevent will acquire *mutex
just before setting *pevent to
NULL and invoking handler (),
and *mutex will be automatically released when
handler () returns (or, in the case of
PEVENT_OWN_THREAD , the handler thread exits by any
means). If the user code acquires this mutex before any calls to
pevent_register () or
pevent_unregister (), or before accessing
*eventp, then *eventp will
always reflect the 'registered' state of the event and
handler () is guaranteed to never be invoked after
pevent_unregister () returns.
pevent_ctx_create (),
pevent_register (), and
pevent_get_info () return NULL
or -1 to indicate an error, with errno set
appropriately.
The PDEL library was developed at Packet Design, LLC.
http://www.packetdesign.com/
Archie Cobbs ⟨archie@freebsd.org⟩
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |