| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- /* Thread cancellation support.
- Copyright (C) 1995-2026 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <https://www.gnu.org/licenses/>. */
- #include <hurd/signal.h>
- #include <hurd/interrupt.h>
- #include <assert.h>
- #include <thread_state.h>
- error_t
- hurd_thread_cancel (thread_t thread)
- {
- struct hurd_sigstate *ss = _hurd_thread_sigstate (thread);
- struct machine_thread_all_state state;
- int state_change;
- error_t err;
- if (! ss)
- return EINVAL;
- if (ss == _hurd_self_sigstate ())
- {
- /* We are cancelling ourselves, so it is easy to succeed
- quickly. Since this function is not a cancellation point, we
- just leave the flag set pending the next cancellation point
- (hurd_check_cancel or RPC) and return success. */
- ss->cancel = 1;
- return 0;
- }
- assert (! __spin_lock_locked (&ss->critical_section_lock));
- __spin_lock (&ss->critical_section_lock);
- __spin_lock (&ss->lock);
- err = __thread_suspend (thread);
- __spin_unlock (&ss->lock);
- if (! err)
- {
- /* Set the flag telling the thread its operation is being cancelled. */
- ss->cancel = 1;
- /* Interrupt any interruptible RPC now in progress. */
- state.set = 0;
- _hurdsig_abort_rpcs (ss, 0, 0, &state, &state_change, NULL);
- if (state_change)
- err = __thread_set_state (thread, MACHINE_THREAD_STATE_FLAVOR,
- (natural_t *) &state.basic,
- MACHINE_THREAD_STATE_COUNT);
- if (ss->cancel_hook)
- /* The code being cancelled has a special wakeup function.
- Calling this should make the thread wake up and check the
- cancellation flag. */
- (*ss->cancel_hook) ();
- __thread_resume (thread);
- }
- _hurd_critical_section_unlock (ss);
- return err;
- }
- int
- hurd_check_cancel (void)
- {
- struct hurd_sigstate *ss = _hurd_self_sigstate ();
- int cancel;
- __spin_lock (&ss->lock);
- assert (! __spin_lock_locked (&ss->critical_section_lock));
- cancel = ss->cancel;
- ss->cancel = 0;
- __spin_unlock (&ss->lock);
- return cancel;
- }
|