ptw32_throw.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * ptw32_throw.c
  3. *
  4. * Description:
  5. * This translation unit implements routines which are private to
  6. * the implementation and may be used throughout it.
  7. *
  8. * --------------------------------------------------------------------------
  9. *
  10. * Pthreads-win32 - POSIX Threads Library for Win32
  11. * Copyright(C) 1998 John E. Bossom
  12. * Copyright(C) 1999,2005 Pthreads-win32 contributors
  13. *
  14. * Contact Email: [email protected]
  15. *
  16. * The current list of contributors is contained
  17. * in the file CONTRIBUTORS included with the source
  18. * code distribution. The list can also be seen at the
  19. * following World Wide Web location:
  20. * http://sources.redhat.com/pthreads-win32/contributors.html
  21. *
  22. * This library is free software; you can redistribute it and/or
  23. * modify it under the terms of the GNU Lesser General Public
  24. * License as published by the Free Software Foundation; either
  25. * version 2 of the License, or (at your option) any later version.
  26. *
  27. * This library is distributed in the hope that it will be useful,
  28. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  29. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  30. * Lesser General Public License for more details.
  31. *
  32. * You should have received a copy of the GNU Lesser General Public
  33. * License along with this library in the file COPYING.LIB;
  34. * if not, write to the Free Software Foundation, Inc.,
  35. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  36. */
  37. #include "pthread.h"
  38. #include "implement.h"
  39. #if defined(__CLEANUP_C)
  40. # include <setjmp.h>
  41. #endif
  42. /*
  43. * ptw32_throw
  44. *
  45. * All canceled and explicitly exited POSIX threads go through
  46. * here. This routine knows how to exit both POSIX initiated threads and
  47. * 'implicit' POSIX threads for each of the possible language modes (C,
  48. * C++, and SEH).
  49. */
  50. #if defined(_MSC_VER)
  51. /*
  52. * Ignore the warning:
  53. * "C++ exception specification ignored except to indicate that
  54. * the function is not __declspec(nothrow)."
  55. */
  56. #pragma warning(disable:4290)
  57. #endif
  58. void
  59. ptw32_throw (DWORD exception)
  60. #if defined(__CLEANUP_CXX)
  61. throw(ptw32_exception_cancel,ptw32_exception_exit)
  62. #endif
  63. {
  64. /*
  65. * Don't use pthread_self() to avoid creating an implicit POSIX thread handle
  66. * unnecessarily.
  67. */
  68. ptw32_thread_t * sp = (ptw32_thread_t *) pthread_getspecific (ptw32_selfThreadKey);
  69. #if defined(__CLEANUP_SEH)
  70. DWORD exceptionInformation[3];
  71. #endif
  72. sp->state = PThreadStateExiting;
  73. if (exception != PTW32_EPS_CANCEL && exception != PTW32_EPS_EXIT)
  74. {
  75. /* Should never enter here */
  76. exit (1);
  77. }
  78. if (NULL == sp || sp->implicit)
  79. {
  80. /*
  81. * We're inside a non-POSIX initialised Win32 thread
  82. * so there is no point to jump or throw back to. Just do an
  83. * explicit thread exit here after cleaning up POSIX
  84. * residue (i.e. cleanup handlers, POSIX thread handle etc).
  85. */
  86. #if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
  87. unsigned exitCode = 0;
  88. switch (exception)
  89. {
  90. case PTW32_EPS_CANCEL:
  91. exitCode = (unsigned)(size_t) PTHREAD_CANCELED;
  92. break;
  93. case PTW32_EPS_EXIT:
  94. if (NULL != sp)
  95. {
  96. exitCode = (unsigned)(size_t) sp->exitStatus;
  97. }
  98. break;
  99. }
  100. #endif
  101. #if defined(PTW32_STATIC_LIB)
  102. pthread_win32_thread_detach_np ();
  103. #endif
  104. #if ! (defined(__MINGW64__) || defined(__MINGW32__)) || defined (__MSVCRT__) || defined (__DMC__)
  105. _endthreadex (exitCode);
  106. #else
  107. _endthread ();
  108. #endif
  109. }
  110. #if defined(__CLEANUP_SEH)
  111. exceptionInformation[0] = (DWORD) (exception);
  112. exceptionInformation[1] = (DWORD) (0);
  113. exceptionInformation[2] = (DWORD) (0);
  114. RaiseException (EXCEPTION_PTW32_SERVICES, 0, 3, exceptionInformation);
  115. #else /* __CLEANUP_SEH */
  116. #if defined(__CLEANUP_C)
  117. ptw32_pop_cleanup_all (1);
  118. longjmp (sp->start_mark, exception);
  119. #else /* __CLEANUP_C */
  120. #if defined(__CLEANUP_CXX)
  121. switch (exception)
  122. {
  123. case PTW32_EPS_CANCEL:
  124. throw ptw32_exception_cancel ();
  125. break;
  126. case PTW32_EPS_EXIT:
  127. throw ptw32_exception_exit ();
  128. break;
  129. }
  130. #else
  131. #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
  132. #endif /* __CLEANUP_CXX */
  133. #endif /* __CLEANUP_C */
  134. #endif /* __CLEANUP_SEH */
  135. /* Never reached */
  136. }
  137. void
  138. ptw32_pop_cleanup_all (int execute)
  139. {
  140. while (NULL != ptw32_pop_cleanup (execute))
  141. {
  142. }
  143. }
  144. DWORD
  145. ptw32_get_exception_services_code (void)
  146. {
  147. #if defined(__CLEANUP_SEH)
  148. return EXCEPTION_PTW32_SERVICES;
  149. #else
  150. return (DWORD)0;
  151. #endif
  152. }