1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2008-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if defined (HAVE_CONFIG_H) 27 # include "config.h" 28 #endif 29 30 #include "oct-mutex.h" 31 #include "lo-error.h" 32 33 #if defined (OCTAVE_USE_WINDOWS_API) 34 # include <windows.h> 35 #elif defined (HAVE_PTHREAD_H) 36 # include <pthread.h> 37 #endif 38 39 namespace octave 40 { 41 void lock(void)42 base_mutex::lock (void) 43 { 44 (*current_liboctave_error_handler) ("mutex not supported on this platform"); 45 } 46 47 void unlock(void)48 base_mutex::unlock (void) 49 { 50 (*current_liboctave_error_handler) ("mutex not supported on this platform"); 51 } 52 53 bool try_lock(void)54 base_mutex::try_lock (void) 55 { 56 (*current_liboctave_error_handler) ("mutex not supported on this platform"); 57 58 return false; 59 } 60 61 #if defined (OCTAVE_USE_WINDOWS_API) 62 63 class 64 w32_mutex : public base_mutex 65 { 66 public: w32_mutex(void)67 w32_mutex (void) 68 : base_mutex () 69 { 70 InitializeCriticalSection (&cs); 71 } 72 ~w32_mutex(void)73 ~w32_mutex (void) 74 { 75 DeleteCriticalSection (&cs); 76 } 77 lock(void)78 void lock (void) 79 { 80 EnterCriticalSection (&cs); 81 } 82 unlock(void)83 void unlock (void) 84 { 85 LeaveCriticalSection (&cs); 86 } 87 try_lock(void)88 bool try_lock (void) 89 { 90 return (TryEnterCriticalSection (&cs) != 0); 91 } 92 93 private: 94 CRITICAL_SECTION cs; 95 }; 96 97 static DWORD thread_id = 0; 98 99 void init(void)100 thread::init (void) 101 { 102 thread_id = GetCurrentThreadId (); 103 } 104 105 bool is_thread(void)106 thread::is_thread (void) 107 { 108 return (GetCurrentThreadId () == thread_id); 109 } 110 111 #elif defined (HAVE_PTHREAD_H) 112 113 class 114 pthread_mutex : public base_mutex 115 { 116 public: pthread_mutex(void)117 pthread_mutex (void) 118 : base_mutex (), m_pm () 119 { 120 pthread_mutexattr_t attr; 121 122 pthread_mutexattr_init (&attr); 123 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 124 pthread_mutex_init (&m_pm, &attr); 125 pthread_mutexattr_destroy (&attr); 126 } 127 ~pthread_mutex(void)128 ~pthread_mutex (void) 129 { 130 pthread_mutex_destroy (&m_pm); 131 } 132 lock(void)133 void lock (void) 134 { 135 pthread_mutex_lock (&m_pm); 136 } 137 unlock(void)138 void unlock (void) 139 { 140 pthread_mutex_unlock (&m_pm); 141 } 142 try_lock(void)143 bool try_lock (void) 144 { 145 return (pthread_mutex_trylock (&m_pm) == 0); 146 } 147 148 private: 149 pthread_mutex_t m_pm; 150 }; 151 152 static pthread_t thread_id = 0; 153 154 void init(void)155 thread::init (void) 156 { 157 thread_id = pthread_self (); 158 } 159 160 bool is_thread(void)161 thread::is_thread (void) 162 { 163 return (pthread_equal (thread_id, pthread_self ()) != 0); 164 } 165 166 #endif 167 168 static base_mutex * init_rep(void)169 init_rep (void) 170 { 171 #if defined (OCTAVE_USE_WINDOWS_API) 172 return new w32_mutex (); 173 #elif defined (HAVE_PTHREAD_H) 174 return new pthread_mutex (); 175 #else 176 return new base_mutex (); 177 #endif 178 } 179 mutex(void)180 mutex::mutex (void) : m_rep (init_rep ()) { } 181 } 182