root/trunk/libffado/src/libutil/PosixThread.h

Revision 2164, 5.4 kB (checked in by jwoithe, 9 years ago)

A more robust solution to ticket #354. Rather than relying on an ad hoc delay, use a condition variable to ensure that PosixThread::ThreadHandler?() acquires m_lock before anything else. It is particularly important that PosixThread::Kill() and PosixThread::Stop() don't lock m_lock before PosixThread::ThreadHandler?(); otherwise a deadlock will result.

Line 
1 /*
2  * Copyright (C) 2005-2008 by Pieter Palmers
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /*
25  * Copied from the jackd/jackdmp sources
26  * function names changed in order to avoid naming problems when using this in
27  * a jackd backend.
28  */
29
30 /* Original license:
31  *
32  *  Copyright (C) 2001 Paul Davis
33  *  Copyright (C) 2004-2006 Grame
34  *
35  *  This program is free software; you can redistribute it and/or modify
36  *  it under the terms of the GNU General Public License as published by
37  *  the Free Software Foundation; either version 2 of the License, or
38  *  (at your option) version 3 of the License.
39  *
40  *  This program is distributed in the hope that it will be useful,
41  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
42  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
43  *  GNU General Public License for more details.
44  *
45  *  You should have received a copy of the GNU General Public License
46  *  along with this program; if not, write to the Free Software
47  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
48  *
49  */
50
51 #ifndef __FFADO_POSIXTHREAD__
52 #define __FFADO_POSIXTHREAD__
53
54 #include "Thread.h"
55 #include <pthread.h>
56 #include "PosixMutex.h"
57
58 namespace Util
59 {
60
61 /*!
62 \brief The POSIX thread base class.
63 */
64
65 class PosixThread : public Thread
66 {
67
68     protected:
69
70         pthread_t fThread;
71         int fPriority;
72         bool fRealTime;
73         volatile bool fRunning;
74         int fCancellation;
75
76         pthread_mutex_t handler_active_lock;
77         pthread_cond_t handler_active_cond;
78         int handler_active;
79
80         static void* ThreadHandler(void* arg);
81         Util::Mutex &m_lock;
82     public:
83
84         PosixThread(RunnableInterface* runnable, bool real_time, int priority, int cancellation)
85                 : Thread(runnable), fThread((pthread_t)NULL), fPriority(priority), fRealTime(real_time), fRunning(false), fCancellation(cancellation)
86                 , handler_active(0)
87                 , m_lock(*(new Util::PosixMutex("THREAD")))
88         { pthread_mutex_init(&handler_active_lock, NULL);
89           pthread_cond_init(&handler_active_cond, NULL);
90         }
91         PosixThread(RunnableInterface* runnable)
92                 : Thread(runnable), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(PTHREAD_CANCEL_DEFERRED)
93                 , handler_active(0)
94                 , m_lock(*(new Util::PosixMutex("THREAD")))
95         { pthread_mutex_init(&handler_active_lock, NULL);
96           pthread_cond_init(&handler_active_cond, NULL);
97         }
98         PosixThread(RunnableInterface* runnable, int cancellation)
99                 : Thread(runnable), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(cancellation)
100                 , handler_active(0)
101                 , m_lock(*(new Util::PosixMutex("THREAD")))
102         { pthread_mutex_init(&handler_active_lock, NULL);
103           pthread_cond_init(&handler_active_cond, NULL);
104         }
105
106         PosixThread(RunnableInterface* runnable, std::string id, bool real_time, int priority, int cancellation)
107                 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(priority), fRealTime(real_time), fRunning(false), fCancellation(cancellation)
108                 , handler_active(0)
109                 , m_lock(*(new Util::PosixMutex(id)))
110         { pthread_mutex_init(&handler_active_lock, NULL);
111           pthread_cond_init(&handler_active_cond, NULL);
112         }
113         PosixThread(RunnableInterface* runnable, std::string id)
114                 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(PTHREAD_CANCEL_DEFERRED)
115                 , handler_active(0)
116                 , m_lock(*(new Util::PosixMutex(id)))
117         { pthread_mutex_init(&handler_active_lock, NULL);
118           pthread_cond_init(&handler_active_cond, NULL);
119         }
120         PosixThread(RunnableInterface* runnable, std::string id, int cancellation)
121                 : Thread(runnable, id), fThread((pthread_t)NULL), fPriority(0), fRealTime(false), fRunning(false), fCancellation(cancellation)
122                 , handler_active(0)
123                 , m_lock(*(new Util::PosixMutex(id)))
124         { pthread_mutex_init(&handler_active_lock, NULL);
125           pthread_cond_init(&handler_active_cond, NULL);
126         }
127
128         virtual ~PosixThread()
129         { delete &m_lock;
130           pthread_mutex_destroy(&handler_active_lock);
131           pthread_cond_destroy(&handler_active_cond);
132         }
133
134         virtual int Start();
135         virtual int Kill();
136         virtual int Stop();
137
138         virtual int AcquireRealTime();
139         virtual int AcquireRealTime(int priority);
140         virtual int DropRealTime();
141
142         pthread_t GetThreadID();
143
144     protected:
145
146 };
147
148 } // end of namespace
149
150
151 #endif // __FFADO_POSIXTHREAD__
Note: See TracBrowser for help on using the browser.