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

  
 
  

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 in-
     vocations 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 action,
     represented by a struct paction, in *actionp.  The creation  of  an  action
     results  in handler() being invoked in a new thread.  paction_cancel() can-
     cels 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 acquired 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 ac-
     tion  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.  Therefore, 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, noth-
     ing 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() function
     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 fol-
     lowed, 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() re-
     turns;  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  appropri-
     ately.  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.quarterly	 April 22, 2002 		      PACTION(3)

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

home | help