 |
|
| |
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.
|