pte_threadStart.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * pte_threadStart.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-embedded (PTE) - POSIX Threads Library for embedded systems
  11. * Copyright(C) 2008 Jason Schmidlapp
  12. *
  13. * Contact Email: [email protected]
  14. *
  15. *
  16. * Based upon Pthreads-win32 - POSIX Threads Library for Win32
  17. * Copyright(C) 1998 John E. Bossom
  18. * Copyright(C) 1999,2005 Pthreads-win32 contributors
  19. *
  20. * Contact Email: [email protected]
  21. *
  22. * The original list of contributors to the Pthreads-win32 project
  23. * is contained in the file CONTRIBUTORS.ptw32 included with the
  24. * source code distribution. The list can also be seen at the
  25. * following World Wide Web location:
  26. * http://sources.redhat.com/pthreads-win32/contributors.html
  27. *
  28. * This library is free software; you can redistribute it and/or
  29. * modify it under the terms of the GNU Lesser General Public
  30. * License as published by the Free Software Foundation; either
  31. * version 2 of the License, or (at your option) any later version.
  32. *
  33. * This library is distributed in the hope that it will be useful,
  34. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  35. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  36. * Lesser General Public License for more details.
  37. *
  38. * You should have received a copy of the GNU Lesser General Public
  39. * License along with this library in the file COPYING.LIB;
  40. * if not, write to the Free Software Foundation, Inc.,
  41. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  42. */
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include "pthread.h"
  46. #include "implement.h"
  47. #if defined(PTE_CLEANUP_CXX)
  48. # if defined(__GNUC__) && __GNUC__ < 3
  49. # include <new>
  50. # else
  51. # include <new>
  52. using
  53. std::terminate_handler;
  54. using
  55. std::terminate;
  56. using
  57. std::set_terminate;
  58. # endif
  59. typedef terminate_handler terminate_function;
  60. static terminate_function pte_oldTerminate;
  61. void
  62. pte_terminate ()
  63. {
  64. set_terminate (pte_oldTerminate);
  65. (void) pte_thread_detach_np();
  66. // terminate ();
  67. }
  68. #endif
  69. int pte_threadStart (void *vthreadParms)
  70. {
  71. ThreadParms * threadParms = (ThreadParms *) vthreadParms;
  72. pthread_t self;
  73. pte_thread_t * sp;
  74. void *(*start) (void *);
  75. void * arg;
  76. #ifdef PTE_CLEANUP_C
  77. #include <setjmp.h>
  78. int setjmp_rc;
  79. #endif
  80. void * status = (void *) 0;
  81. self = threadParms->tid;
  82. sp = (pte_thread_t *) self;
  83. start = threadParms->start;
  84. arg = threadParms->arg;
  85. // free (threadParms);
  86. pthread_setspecific (pte_selfThreadKey, sp);
  87. sp->state = PThreadStateRunning;
  88. #ifdef PTE_CLEANUP_C
  89. setjmp_rc = setjmp (sp->start_mark);
  90. if (0 == setjmp_rc)
  91. {
  92. /*
  93. * Run the caller's routine;
  94. */
  95. sp->exitStatus = status = (*start) (arg);
  96. }
  97. else
  98. {
  99. switch (setjmp_rc)
  100. {
  101. case PTE_EPS_CANCEL:
  102. status = sp->exitStatus = PTHREAD_CANCELED;
  103. break;
  104. case PTE_EPS_EXIT:
  105. status = sp->exitStatus;
  106. break;
  107. default:
  108. status = sp->exitStatus = PTHREAD_CANCELED;
  109. break;
  110. }
  111. }
  112. #else /* PTE_CLEANUP_C */
  113. #ifdef PTE_CLEANUP_CXX
  114. pte_oldTerminate = set_terminate (&pte_terminate);
  115. try
  116. {
  117. /*
  118. * Run the caller's routine in a nested try block so that we
  119. * can run the user's terminate function, which may call
  120. * pthread_exit() or be canceled.
  121. */
  122. try
  123. {
  124. status = sp->exitStatus = (*start) (arg);
  125. }
  126. catch (pte_exception &)
  127. {
  128. /*
  129. * Pass these through to the outer block.
  130. */
  131. throw;
  132. }
  133. catch (...)
  134. {
  135. /*
  136. * We want to run the user's terminate function if supplied.
  137. * That function may call pthread_exit() or be canceled, which will
  138. * be handled by the outer try block.
  139. *
  140. * pte_terminate() will be called if there is no user
  141. * supplied function.
  142. */
  143. terminate_function
  144. term_func = set_terminate (0);
  145. set_terminate (term_func);
  146. if (term_func != 0)
  147. {
  148. term_func ();
  149. }
  150. throw;
  151. }
  152. }
  153. catch (pte_exception_cancel &)
  154. {
  155. /*
  156. * Thread was canceled.
  157. */
  158. status = sp->exitStatus = PTHREAD_CANCELED;
  159. }
  160. catch (pte_exception_exit &)
  161. {
  162. /*
  163. * Thread was exited via pthread_exit().
  164. */
  165. status = sp->exitStatus;
  166. }
  167. catch (...)
  168. {
  169. /*
  170. * A system unexpected exception has occurred running the user's
  171. * terminate routine. We get control back within this block - cleanup
  172. * and release the exception out of thread scope.
  173. */
  174. status = sp->exitStatus = PTHREAD_CANCELED;
  175. (void) pthread_mutex_lock (&sp->cancelLock);
  176. sp->state = PThreadStateException;
  177. (void) pthread_mutex_unlock (&sp->cancelLock);
  178. (void) pte_thread_detach_np();
  179. (void) set_terminate (pte_oldTerminate);
  180. throw;
  181. /*
  182. * Never reached.
  183. */
  184. }
  185. (void) set_terminate (pte_oldTerminate);
  186. #else
  187. #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
  188. #endif /* PTE_CLEANUP_CXX */
  189. #endif /* PTE_CLEANUP_C */
  190. /*
  191. * We need to cleanup the pthread now if we have
  192. * been statically linked, in which case the cleanup
  193. * in dllMain won't get done. Joinable threads will
  194. * only be partially cleaned up and must be fully cleaned
  195. * up by pthread_join() or pthread_detach().
  196. *
  197. * Note: if this library has been statically linked,
  198. * implicitly created pthreads (those created
  199. * for OS threads which have called pthreads routines)
  200. * must be cleaned up explicitly by the application
  201. * (by calling pte_thread_detach_np()).
  202. */
  203. (void) pte_thread_detach_and_exit_np ();
  204. //pte_osThreadExit(status);
  205. /*
  206. * Never reached.
  207. */
  208. return (unsigned) status;
  209. } /* pte_threadStart */