1// thread -*- C++ -*-
2
3// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25
26#include <thread>
27#include <cerrno>
28
29#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
30
31namespace std
32{
33  namespace
34  {
35    extern "C" void*
36    execute_native_thread_routine(void* __p)
37    {
38      thread::_Impl_base* __t = static_cast<thread::_Impl_base*>(__p);
39      thread::__shared_base_type __local;
40      __local.swap(__t->_M_this_ptr);
41
42      __try
43	{
44	  __t->_M_run();
45	}
46      __catch(...)
47	{
48	  std::terminate();
49	}
50
51      return 0;
52    }
53  }
54
55  void
56  thread::join()
57  {
58    int __e = EINVAL;
59
60    if (_M_id != id())
61      __e = __gthread_join(_M_id._M_thread, NULL);
62
63    if (__e)
64      __throw_system_error(__e);
65
66    _M_id = id();
67  }
68
69  void
70  thread::detach()
71  {
72    int __e = EINVAL;
73
74    if (_M_id != id())
75      __e = __gthread_detach(_M_id._M_thread);
76
77    if (__e)
78      __throw_system_error(__e);
79
80    _M_id = id();
81  }
82
83  void
84  thread::_M_start_thread(__shared_base_type __b)
85  {
86    if (!__gthread_active_p())
87      __throw_system_error(int(errc::operation_not_permitted));
88
89    __b->_M_this_ptr = __b;
90    int __e = __gthread_create(&_M_id._M_thread,
91			       &execute_native_thread_routine, __b.get());
92    if (__e)
93    {
94      __b->_M_this_ptr.reset();
95      __throw_system_error(__e);
96    }
97  }
98}
99
100#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
101