Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
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);

     pevent_ctx_destroy(struct pevent_ctx **ctxp);

     pevent_ctx_count(struct pevent_ctx	*ctx);

     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, ...);

     pevent_unregister(struct pevent **eventp);

     pevent_trigger(struct pevent *event);

     pevent_get_info(struct pevent *event, struct pevent_info *info);

     These functions support event-driven programming.	Event-driven program-
     ming 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).

   Event contexts
     pevent_ctx_create() creates a new event context, which is used to regis-
     ter 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 regis-
     tered are automatically unregistered.  Upon return, *ctxp is set to NULL.
     If	*ctxp is already NULL when pevent_ctx_destroy()	is invoked, nothing

     It	is safe	to call	pevent_ctx_destroy() from within an event handler

     pevent_ctx_count()	returns	the number of events currently registered with

     pevent_register() creates a new event and registers it with ctx.  If suc-
     cessful, 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

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

     The flags parameter may contain any of the	following values OR'd to-

	PEVENT_RECURRING    The	event is recurring.

	PEVENT_OWN_THREAD   Invoke handler() in	a separate thread.

     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 de-
     fault 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 con-
     ditions 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() re-
     turns (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() re-

     pevent_ctx_create(), pevent_register(), and pevent_get_info() return NULL
     or	-1 to indicate an error, with errno set	appropriately.

     libpdel(3), mesg_port(3), paction(3), pthread(3), typed_mem(3)

     The PDEL library was developed at Packet Design, LLC.

     Archie Cobbs <>

FreeBSD	13.0			April 22, 2002			  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help