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

  
 
  

home | help
PEVENT(3)		     Library Functions Manual		       PEVENT(3)

NAME
     pevent -- pthread event library

LIBRARY
     PDEL Library (libpdel, -lpdel)

SYNOPSIS
     #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);

DESCRIPTION
     These functions support event-driven programming.	Event-driven programming
     is simpler and more efficient than threaded programming because only a sin-
     gle  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 comple-
     tion, 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	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 regis-
     tered are automatically unregistered.  Upon return, *ctxp is set  to  NULL.
     If *ctxp is already NULL when pevent_ctx_destroy() is invoked, nothing hap-
     pens.

     It  is safe to call pevent_ctx_destroy() from within an event handler func-
     tion.

     pevent_ctx_count() returns the number of events currently	registered  with
     ctx.

   Events
     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_regis-
     ter() 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 in-
     voked.   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 unmodi-
     fied 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 ar-
			  gument must have type int.

	PEVENT_WRITE	  Writable condition on a file descriptor.  The next ar-
			  gument 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  ar-
			  gument must have type struct mesg_port *.

	PEVENT_USER	  User-triggered  event.   No  further arguments are re-
			  quired.

     The flags parameter may contain any of the following values OR'd together:

	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 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 re-
     turn, *peventp is set to NULL.  If *peventp is already NULL when pevent_un-
     register() is invoked, nothing happens.

     pevent_trigger()  manually triggers an event, causing its handler to be in-
     voked.  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;
	};

   Synchronization
     pevent_ctx_count(),  pevent_register(),  pevent_unregister(),  pevent_trig-
     ger(),  and  pevent_get_info()  may  all  safely  be  called from different
     threads simultaneously.  However, there are inherent  race  conditions  be-
     tween  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 ac-
     quire  *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.

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

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

HISTORY
     The   PDEL   library    was    developed	 at    Packet	 Design,    LLC.
     http://www.packetdesign.com/

AUTHORS
     Archie Cobbs <archie@freebsd.org>

FreeBSD ports 15.quarterly	 April 22, 2002 		       PEVENT(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=pevent_ctx_count&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help