cancellation.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  16. #include <setjmp.h>
  17. #include <stdlib.h>
  18. #include "pthreadP.h"
  19. /* The next two functions are similar to pthread_setcanceltype() but
  20. more specialized for the use in the cancelable functions like write().
  21. They do not need to check parameters etc. */
  22. int
  23. attribute_hidden
  24. __pthread_enable_asynccancel (void)
  25. {
  26. struct pthread *self = THREAD_SELF;
  27. int oldval = THREAD_GETMEM (self, cancelhandling);
  28. while (1)
  29. {
  30. int newval = oldval | CANCELTYPE_BITMASK;
  31. if (newval == oldval)
  32. break;
  33. int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
  34. oldval);
  35. if (__builtin_expect (curval == oldval, 1))
  36. {
  37. if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
  38. {
  39. THREAD_SETMEM (self, result, PTHREAD_CANCELED);
  40. __do_cancel ();
  41. }
  42. break;
  43. }
  44. /* Prepare the next round. */
  45. oldval = curval;
  46. }
  47. return oldval;
  48. }
  49. void
  50. internal_function attribute_hidden
  51. __pthread_disable_asynccancel (int oldtype)
  52. {
  53. /* If asynchronous cancellation was enabled before we do not have
  54. anything to do. */
  55. if (oldtype & CANCELTYPE_BITMASK)
  56. return;
  57. struct pthread *self = THREAD_SELF;
  58. int oldval = THREAD_GETMEM (self, cancelhandling);
  59. while (1)
  60. {
  61. int newval = oldval & ~CANCELTYPE_BITMASK;
  62. if (newval == oldval)
  63. break;
  64. int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
  65. oldval);
  66. if (__builtin_expect (curval == oldval, 1))
  67. break;
  68. /* Prepare the next round. */
  69. oldval = curval;
  70. }
  71. }