GNU Octave  3.8.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
thread-manager.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2013 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #if defined (__WIN32__) && ! defined (__CYGWIN__)
28 #include <windows.h>
29 #else
30 #include <pthread.h>
31 #endif
32 
33 #include <sys/types.h>
34 #include <signal.h>
35 
36 #include "sighandlers.h"
37 #include "thread-manager.h"
38 
39 #if defined (__WIN32__) && ! defined (__CYGWIN__)
40 
41 class windows_thread_manager : public octave_base_thread_manager
42 {
43 public:
44 
45  windows_thread_manager (void) : octave_base_thread_manager () { }
46 
47  void register_current_thread (void) { }
48 
49  void interrupt (void)
50  {
51  GenerateConsoleCtrlEvent (CTRL_C_EVENT, 0);
52  }
53 };
54 
55 #else
56 
58 {
59 public:
60 
63  { }
64 
66  {
67  my_thread = pthread_self ();
68  initialized = true;
69  }
70 
71  void interrupt (void)
72  {
73  if (initialized)
74  pthread_kill (my_thread, SIGINT);
75  }
76 
77 private:
78 
79  pthread_t my_thread;
80 
82 };
83 
84 #endif
85 
87  : rep (octave_thread_manager::create_rep ())
88 { }
89 
90 // The following is a workaround for an apparent bug in GCC 4.1.2 and
91 // possibly earlier versions. See Octave bug report #30685 for details.
92 #if defined (__GNUC__)
93 # if ! (__GNUC__ > 4 \
94  || (__GNUC__ == 4 && (__GNUC_MINOR__ > 1 \
95  || (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ > 2))))
96 # undef GNULIB_NAMESPACE
97 # define GNULIB_NAMESPACE
98 # warning "disabling GNULIB_NAMESPACE for signal functions -- consider upgrading to a current version of GCC"
99 # endif
100 #endif
101 
102 static void
103 block_or_unblock_signal (int how, int sig)
104 {
105 #if ! defined (__WIN32__) || defined (__CYGWIN__)
106  // Blocking/unblocking signals at thread level is only supported
107  // on platform with fully compliant POSIX threads. This is not
108  // supported on Win32. Moreover, we have to make sure that SIGINT
109  // handler is not installed before calling AllocConsole: installing
110  // a SIGINT handler internally calls SetConsoleCtrlHandler, which
111  // must be called after AllocConsole to be effective.
112 
113  sigset_t signal_mask;
114 
115  GNULIB_NAMESPACE::sigemptyset (&signal_mask);
116 
117  GNULIB_NAMESPACE::sigaddset (&signal_mask, sig);
118 
119  pthread_sigmask (how, &signal_mask, 0);
120 #endif
121 }
122 
123 void
125 {
126  block_or_unblock_signal (SIG_BLOCK, SIGINT);
127 }
128 
129 void
131 {
132  block_or_unblock_signal (SIG_UNBLOCK, SIGINT);
133 }
134 
137 {
138 #if defined (__WIN32__) && ! defined (__CYGWIN__)
139  return new windows_thread_manager ();
140 #else
141  return new pthread_thread_manager ();
142 #endif
143 }