FreeBSD Manual Pages
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)
NAME | LIBRARY | SYNOPSIS | DESCRIPTION | RETURN VALUES | SEE ALSO | HISTORY | AUTHORS
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>
