diff --git a/include/nuttx/pthread.h b/include/nuttx/pthread.h index 54d5dc659bd..2625e40d531 100644 --- a/include/nuttx/pthread.h +++ b/include/nuttx/pthread.h @@ -2,7 +2,7 @@ * include/nuttx/pthread.h * Non-standard, NuttX-specific pthread-related declarations. * - * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -127,6 +127,72 @@ EXTERN const pthread_attr_t g_default_pthread_attr; * Public Function Prototypes ****************************************************************************/ +/**************************************************************************** + * Cancellation Points. + * + * Cancellation points shall occur when a thread is executing the following + * functions: + * + * accept() mq_timedsend() putpmsg() sigtimedwait() + * aio_suspend() msgrcv() pwrite() sigwait() + * clock_nanosleep() msgsnd() read() sigwaitinfo() + * close() msync() readv() sleep() + * connect() nanosleep() recv() system() + * creat() open() recvfrom() tcdrain() + * fcntl() pause() recvmsg() usleep() + * fdatasync() poll() select() wait() + * fsync() pread() sem_timedwait() waitid() + * getmsg() pselect() sem_wait() waitpid() + * getpmsg() pthread_cond_timedwait() send() write() + * lockf() pthread_cond_wait() sendmsg() writev() + * mq_receive() pthread_join() sendto() + * mq_send() pthread_testcancel() sigpause() + * mq_timedreceive() putmsg() sigsuspend() + * + * Each of the above function must call enter_cancellation_point() on entry + * in order to establish the cancellation point and leave_cancellation_point() + * on exit. These functions are described below. + * + ****************************************************************************/ + +/**************************************************************************** + * Name: enter_cancellation_point + * + * Description: + * Called at the beginning of the cancellation point to establish the + * cancellation point. This function does the following: + * + * 1. If deferred cancellation does not apply to this thread, nothing is + * done, otherwise, it + * 2. Sets state information in the caller's TCB and increments a nesting + * count. + * 3. If this is the outermost nesting level, it checks if there is a + * pending cancellation and, if so, calls either exit() or + * pthread_exit(), depending upon the type of the + * + ****************************************************************************/ + +void leave_cancellation_point(void); + +/**************************************************************************** + * Name: enter_cancellation_point + * + * Description: + * Called at the end of the cancellation point. This function does the + * following: + * + * 1. If deferred cancellation does not apply to this thread, nothing is + * done, otherwise, it + * 2. Clears state information in the caller's TCB and decrements a + * nesting count. + * 3. If this is the outermost nesting level, it checks if there is a + * pending cancellation and, if so, calls either exit() or + * pthread_exit(), depending upon the type of the + * + ****************************************************************************/ + +void enter_cancellation_point(void); + #undef EXTERN #ifdef __cplusplus } diff --git a/sched/pthread/Make.defs b/sched/pthread/Make.defs index f589f3dfef4..0ed862edf06 100644 --- a/sched/pthread/Make.defs +++ b/sched/pthread/Make.defs @@ -44,7 +44,8 @@ CSRCS += pthread_condwait.c pthread_condsignal.c pthread_condbroadcast.c CSRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwait.c CSRCS += pthread_cancel.c pthread_setcancelstate.c pthread_setcanceltype.c CSRCS += pthread_testcancel.c -CSRCS += pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c pthread_keydelete.c +CSRCS += pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c +CSRCS += pthread_keydelete.c CSRCS += pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c CSRCS += pthread_once.c pthread_release.c pthread_setschedprio.c diff --git a/sched/pthread/pthread_setcancelstate.c b/sched/pthread/pthread_setcancelstate.c index 4c457766fac..d5368421570 100644 --- a/sched/pthread/pthread_setcancelstate.c +++ b/sched/pthread/pthread_setcancelstate.c @@ -37,8 +37,12 @@ * Included Files ****************************************************************************/ +#include + #include #include + +#include "task/task.h" #include "sched/sched.h" /**************************************************************************** @@ -107,9 +111,9 @@ int pthread_setcancelstate(int state, FAR int *oldstate) * notify of the cancellation. */ - if (tcb->flags & TCB_FLAG_CANCEL_POINT) != 0) + if ((tcb->flags & TCB_FLAG_CANCEL_POINT) != 0) { -# warning Missing logic + notify_cancellation(); } } else diff --git a/sched/task/Make.defs b/sched/task/Make.defs index ddf3e972b73..e173a8b2460 100644 --- a/sched/task/Make.defs +++ b/sched/task/Make.defs @@ -66,6 +66,10 @@ ifeq ($(CONFIG_SCHED_ONEXIT),y) CSRCS += task_onexit.c endif +ifeq ($(CONFIG_CANCELLATION_POINTS),y) +CSRCS += task_cancelpt.c +endif + # Include task build support DEPPATH += --dep-path task diff --git a/sched/task/task.h b/sched/task/task.h index e81f0eaefcd..2abcf4a74da 100644 --- a/sched/task/task.h +++ b/sched/task/task.h @@ -80,4 +80,10 @@ int task_terminate(pid_t pid, bool nonblocking); void task_exithook(FAR struct tcb_s *tcb, int status, bool nonblocking); void task_recover(FAR struct tcb_s *tcb); +/* Cancellation points */ + +#ifdef CONFIG_CANCELLATION_POINTS +void notify_cancellation(void); +#endif + #endif /* __SCHED_TASK_TASK_H */ diff --git a/sched/task/task_cancelpt.c b/sched/task/task_cancelpt.c new file mode 100644 index 00000000000..2e294000d67 --- /dev/null +++ b/sched/task/task_cancelpt.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * sched/task/task_cancelpt.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Cancellation Points. + * + * Cancellation points shall occur when a thread is executing the following + * functions: + * + * accept() mq_timedsend() putpmsg() sigtimedwait() + * aio_suspend() msgrcv() pwrite() sigwait() + * clock_nanosleep() msgsnd() read() sigwaitinfo() + * close() msync() readv() sleep() + * connect() nanosleep() recv() system() + * creat() open() recvfrom() tcdrain() + * fcntl() pause() recvmsg() usleep() + * fdatasync() poll() select() wait() + * fsync() pread() sem_timedwait() waitid() + * getmsg() pselect() sem_wait() waitpid() + * getpmsg() pthread_cond_timedwait() send() write() + * lockf() pthread_cond_wait() sendmsg() writev() + * mq_receive() pthread_join() sendto() + * mq_send() pthread_testcancel() sigpause() + * mq_timedreceive() putmsg() sigsuspend() + * + * Each of the above function must call enter_cancellation_point() on entry + * in order to establish the cancellation point and leave_cancellation_point() + * on exit. These functions are described below. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "task/task.h" + +#ifdef CONFIG_CANCELLATION_POINTS + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: enter_cancellation_point + * + * Description: + * Called at the beginning of the cancellation point to establish the + * cancellation point. This function does the following: + * + * 1. If deferred cancellation does not apply to this thread, nothing is + * done, otherwise, it + * 2. Sets state information in the caller's TCB and increments a nesting + * count. + * 3. If this is the outermost nesting level, it checks if there is a + * pending cancellation and, if so, calls either exit() or + * pthread_exit(), depending upon the type of the + * + ****************************************************************************/ + +void leave_cancellation_point(void) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: enter_cancellation_point + * + * Description: + * Called at the end of the cancellation point. This function does the + * following: + * + * 1. If deferred cancellation does not apply to this thread, nothing is + * done, otherwise, it + * 2. Clears state information in the caller's TCB and decrements a + * nesting count. + * 3. If this is the outermost nesting level, it checks if there is a + * pending cancellation and, if so, calls either exit() or + * pthread_exit(), depending upon the type of the + * + ****************************************************************************/ + +void enter_cancellation_point(void) +{ +#warning Missing logic +} + +/**************************************************************************** + * Name: notify_cancellation + * + * Description: + * Called by task_delete() or pthread_cancel() if the cancellation occurs + * while we the thread is within the cancellation point. This logic + * behaves much like sending a signal: It will cause waiting threads + * to wake up and terminated with ECANCELED. A call to + * leave_cancellation_point() whould then follow, causing the thread to + * exit. + * + ****************************************************************************/ + +void notify_cancellation(void) +{ +#warning Missing logic +} + +#endif /* CONFIG_CANCELLATION_POINTS */