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

FreeBSD Manual Pages

  
 
  

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

NAME
       paction -- actions in a separate	thread

LIBRARY
       PDEL Library (libpdel, -lpdel)

SYNOPSIS
       #include	<sys/types.h>
       #include	<pthread.h>
       #include	<pdel/util/paction.h>

       int
       paction_start(struct   paction	**actionp,   pthread_mutex_t   *mutex,
	   paction_handler_t *handler, paction_finish_t	*finish, void *arg);

       void
       paction_cancel(struct paction **actionp);

DESCRIPTION
       These functions provide support for actions, which are simply  function
       invocations that	happen in separate threads.  This is just a simplified
       API for spawning	and cancelling threads with built-in support for mutex
       locking and avoiding certain race conditions.

       paction_start()	creates	 a  new	action and stores a pointer to the ac-
       tion, represented by a struct paction, in *actionp.  The	creation of an
       action  results	in  handler()  being  invoked	in   a	 new   thread.
       paction_cancel()	 cancels an action by canceling	its associated thread.
       In any case, when the action has	completed, finish()  is	 invoked.   If
       the  action  was	 not canceled via paction_cancel(), then *mutex	is ac-
       quired  before  finish()	 is  invoked  and  released   afterward.    If
       paction_cancel()	 was  called,  then  the  mutex	 is  not  acquired for
       finish().  The was_canceled argument to finish()	reflects this.

       handler and finish must be pointers to functions	having these types:

	  typedef void paction_handler_t(void *arg);
	  typedef void paction_finish_t(void *arg, int was_canceled);

       When paction_start() is invoked,	*actionp must be NULL.	As long	as the
       action is still in progress (i.e., finish() has not yet been  invoked),
       *actionp	 will  be non-NULL.  When the action completes or is canceled,
       *actionp	is set to NULL again.  Therefore, *actionp must	 remain	 valid
       and  unmodified	for  the duration of the action, and can be used as an
       indicator of whether the	action has completed.

       paction_cancel()	cancels	an outstanding action.	This  results  in  the
       action  thread  being  canceled at the next cancellation	point.	There-
       fore, handler() may need	to register thread cleanup hooks in  order  to
       free any	allocated resources in the case	of cancellation.  Upon return,
       *actionp	  is   set   to	 NULL.	 If  *actionp  is  already  NULL  when
       paction_cancel()	is invoked, nothing happens.

       In any case, finish() is	invoked	when the action	terminates.  There are
       two reasons for an action terminating:  either  the  action  terminated
       normally,  or  paction_cancel()	was invoked.  If the action terminated
       normally, *mutex	is locked, *actionp is set to NULL,  and  finish()  is
       invoked with was_canceled set to	zero.  When finish() returns *mutex is
       unlocked.

       If  the action was canceled by paction_cancel(),	then neither mutex nor
       actionp are dereferenced; final() is simply  called  with  was_canceled
       set to non-zero.	 Note that *actionp will have already been set to NULL
       previously by paction_cancel().

       Cancelling  the action thread directly via pthread_cancel(3) is treated
       just as if handler() returned early; i.e., the first case above.

   Synchronization
       There are inherent race conditions between an action's  finish()	 func-
       tion  being  invoked and	reading	the value of *actionp or canceling the
       action with paction_cancel().  The *mutex should	be used	to avoid these
       problems	by using it to protect *actionp.

       The user	code should acquire *mutex before calling  paction_start()  or
       paction_cancel(),  or  before  accessing	*actionp.  If this protocol is
       followed, then *actionp will be non-NULL	if and only if the  action  is
       still  pending,	i.e., finish() has not yet been	invoked.  In addition,
       the was_canceled	argument will always be	accurate, i.e.,	be non-zero if
       and only	if paction_cancel() was	called to cancel the action.

       Finally,	mutex and actionp will not be dereferenced  after  a  call  to
       paction_cancel(), so it is always safe to destroy the memory pointed to
       by mutex	and actionp after calling paction_cancel().  However, arg must
       remain	valid  until  finish()	is  invoked,  which  may  occur	 after
       paction_cancel()	returns; alternatively,	finish() must not  dereference
       arg if was_canceled is non-zero.

RETURN VALUES
       paction_start()	returns	-1 if there is an error, with errno set	appro-
       priately.  In particular, if *actionp is	not equal to NULL, then	 errno
       will be set to EBUSY.

SEE ALSO
       libpdel(3), pevent(3), pthread_cancel(3), pthread_create(3)

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

AUTHORS
       Archie Cobbs <archie@freebsd.org>

FreeBSD	ports 15.0		April 22, 2002			    PACTION(3)

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

home | help