blob: 020d94ebb1ace81eb1b604c17f7428d7ef9ebcea [file] [log] [blame]
dburgess82c46ff2011-10-07 02:40:51 +00001/*
2* Copyright 2008 Free Software Foundation, Inc.
3*
Pau Espin Pedrol21d03d32019-07-22 12:05:52 +02004* SPDX-License-Identifier: AGPL-3.0+
dburgess82c46ff2011-10-07 02:40:51 +00005*
6* This software is distributed under the terms of the GNU Affero Public License.
7* See the COPYING file in the main directory for details.
8*
9* This use of this software may be subject to additional restrictions.
10* See the LEGAL file in the main directory for details.
11
12 This program is free software: you can redistribute it and/or modify
13 it under the terms of the GNU Affero General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Affero General Public License for more details.
21
22 You should have received a copy of the GNU Affero General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
24
25*/
26
27
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +020028#include <string.h>
29#include <sys/types.h>
dburgess82c46ff2011-10-07 02:40:51 +000030
31#include "Threads.h"
32#include "Timeval.h"
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +020033#include "Logger.h"
34
35#ifndef gettid
36#include <sys/syscall.h>
37#define gettid() syscall(SYS_gettid)
38#endif
dburgess82c46ff2011-10-07 02:40:51 +000039
40
41using namespace std;
42
Pau Espin Pedrole503c982019-09-13 18:56:08 +020043#ifndef HAVE_ATOMIC_OPS
44 pthread_mutex_t atomic_ops_mutex = PTHREAD_MUTEX_INITIALIZER;
45#endif
dburgess82c46ff2011-10-07 02:40:51 +000046
47
48Mutex gStreamLock; ///< Global lock to control access to cout and cerr.
49
50void lockCout()
51{
52 gStreamLock.lock();
53 Timeval entryTime;
54 cout << entryTime << " " << pthread_self() << ": ";
55}
56
57
58void unlockCout()
59{
60 cout << dec << endl << flush;
61 gStreamLock.unlock();
62}
63
64
65void lockCerr()
66{
67 gStreamLock.lock();
68 Timeval entryTime;
69 cerr << entryTime << " " << pthread_self() << ": ";
70}
71
72void unlockCerr()
73{
74 cerr << dec << endl << flush;
75 gStreamLock.unlock();
76}
77
78
79
80
81
82
83
84Mutex::Mutex()
85{
86 bool res;
87 res = pthread_mutexattr_init(&mAttribs);
88 assert(!res);
89 res = pthread_mutexattr_settype(&mAttribs,PTHREAD_MUTEX_RECURSIVE);
90 assert(!res);
91 res = pthread_mutex_init(&mMutex,&mAttribs);
92 assert(!res);
93}
94
95
96Mutex::~Mutex()
97{
98 pthread_mutex_destroy(&mMutex);
99 bool res = pthread_mutexattr_destroy(&mAttribs);
100 assert(!res);
101}
102
103
104
105
106/** Block for the signal up to the cancellation timeout. */
107void Signal::wait(Mutex& wMutex, unsigned timeout) const
108{
109 Timeval then(timeout);
110 struct timespec waitTime = then.timespec();
111 pthread_cond_timedwait(&mSignal,&wMutex.mMutex,&waitTime);
112}
113
Pau Espin Pedrol5b60c982018-09-20 18:04:46 +0200114void set_selfthread_name(const char *name)
115{
116 pthread_t selfid = pthread_self();
117 pid_t tid = gettid();
118 if (pthread_setname_np(selfid, name) == 0) {
119 LOG(INFO) << "Thread "<< selfid << " (task " << tid << ") set name: " << name;
120 } else {
121 char buf[256];
122 int err = errno;
123 char* err_str = strerror_r(err, buf, sizeof(buf));
124 LOG(NOTICE) << "Thread "<< selfid << " (task " << tid << ") set name \"" << name << "\" failed: (" << err << ") " << err_str;
125 }
126}
dburgess82c46ff2011-10-07 02:40:51 +0000127
Pau Espin Pedrol75cb0b92019-04-25 19:33:58 +0200128void thread_enable_cancel(bool cancel)
129{
130 cancel ? pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) :
131 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
132}
133
dburgess82c46ff2011-10-07 02:40:51 +0000134void Thread::start(void *(*task)(void*), void *arg)
135{
136 assert(mThread==((pthread_t)0));
137 bool res;
kurtis.heimerl5a872472013-05-31 21:47:25 +0000138 // (pat) Moved initialization to constructor to avoid crash in destructor.
139 //res = pthread_attr_init(&mAttrib);
140 //assert(!res);
Eric Wildac0487e2019-06-17 13:02:44 +0200141 if (mStackSize != 0) {
142 res = pthread_attr_setstacksize(&mAttrib, mStackSize);
143 assert(!res);
144 }
dburgess82c46ff2011-10-07 02:40:51 +0000145 res = pthread_create(&mThread, &mAttrib, task, arg);
146 assert(!res);
147}
148
149
150
151// vim: ts=4 sw=4