1 /* Cancel a thread.
2    Copyright (C) 2002-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library;  if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <pthread.h>
20 #include <hurd/signal.h>
21 
22 #include <pt-internal.h>
23 #include <pthreadP.h>
24 
25 static void
call_exit(void)26 call_exit (void)
27 {
28   __pthread_exit (0);
29 }
30 
31 int
__pthread_do_cancel(struct __pthread * p)32 __pthread_do_cancel (struct __pthread *p)
33 {
34   mach_port_t ktid;
35   int me;
36 
37   assert (p->cancel_pending == 1);
38   assert (p->cancel_state == PTHREAD_CANCEL_ENABLE);
39 
40   __pthread_mutex_unlock (&p->cancel_lock);
41 
42   ktid = __mach_thread_self ();
43   me = p->kernel_thread == ktid;
44   __mach_port_deallocate (__mach_task_self (), ktid);
45 
46   if (me)
47     call_exit ();
48   else
49     {
50       error_t err;
51       struct hurd_sigstate *ss = _hurd_thread_sigstate (p->kernel_thread);
52 
53       __spin_lock (&ss->critical_section_lock);
54       __spin_lock (&ss->lock);
55 
56       err = __thread_suspend (p->kernel_thread);
57       assert_perror (err);
58 
59       __spin_unlock (&ss->lock);
60 
61       err = __thread_abort (p->kernel_thread);
62       assert_perror (err);
63 
64       err = __thread_set_pcsptp (p->kernel_thread,
65 				 1, (void *) call_exit, 0, 0, 0, 0);
66       assert_perror (err);
67 
68       err = __thread_resume (p->kernel_thread);
69       assert_perror (err);
70 
71       _hurd_critical_section_unlock (ss);
72     }
73 
74   return 0;
75 }
76