framework2

Форк
0
182 строки · 4.6 Кб
1
#include "ofThread.h"
2
#include "ofLog.h"
3

4
#ifdef TARGET_ANDROID
5
#include <jni.h>
6
#include "ofxAndroidUtils.h"
7
#endif
8

9
//-------------------------------------------------
10
ofThread::ofThread()
11
:threadRunning(false)
12
,threadDone(true)
13
,mutexBlocks(true)
14
,name(""){
15
}
16

17
//-------------------------------------------------
18
bool ofThread::isThreadRunning() const{
19
    return threadRunning;
20
}
21

22
//-------------------------------------------------
23
std::thread::id ofThread::getThreadId() const{
24
	return thread.get_id();
25
}
26

27
//-------------------------------------------------
28
std::string ofThread::getThreadName() const{
29
	return name;
30
}
31

32
//-------------------------------------------------
33
void ofThread::setThreadName(const std::string & name){
34
	this->name = name;
35
}
36

37
//-------------------------------------------------
38
void ofThread::startThread(){
39
	std::unique_lock<std::mutex> lck(mutex);
40
	if(threadRunning || !threadDone){
41
		ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Cannot start, thread already running.";
42
		return;
43
	}
44

45
	threadDone = false;
46
	threadRunning = true;
47
	this->mutexBlocks = true;
48

49
	thread = std::thread(std::bind(&ofThread::run,this));
50
}
51

52
//-------------------------------------------------
53
void ofThread::startThread(bool mutexBlocks){
54
    std::unique_lock<std::mutex> lck(mutex);
55
	if(threadRunning || !threadDone){
56
		ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Cannot start, thread already running.";
57
		return;
58
	}
59

60
    threadDone = false;
61
    threadRunning = true;
62
    this->mutexBlocks = mutexBlocks;
63

64
	thread = std::thread(std::bind(&ofThread::run,this));
65
}
66

67
//-------------------------------------------------
68
bool ofThread::lock(){
69
	if(mutexBlocks){
70
		mutex.lock();
71
	}else{
72
		if(!mutex.try_lock()){
73
			return false; // mutex is locked, tryLock failed
74
		}
75
	}
76
	return true;
77
}
78

79
//-------------------------------------------------
80
bool ofThread::tryLock(){
81
	return mutex.try_lock();
82
}
83

84
//-------------------------------------------------
85
void ofThread::unlock(){
86
	mutex.unlock();
87
}
88

89
//-------------------------------------------------
90
void ofThread::stopThread(){
91
    threadRunning = false;
92
}
93

94
//-------------------------------------------------
95
void ofThread::waitForThread(bool callStopThread, long milliseconds){
96
	if(!threadDone){
97
		// tell thread to stop
98
        if(callStopThread){
99
            stopThread();
100
		}
101

102
		// wait for the thread to finish
103
        if(isCurrentThread()){
104
			return; // waitForThread should only be called outside thread
105
		}
106

107
        if (INFINITE_JOIN_TIMEOUT == milliseconds){
108
            std::unique_lock<std::mutex> lck(mutex);
109
            if(!threadDone){
110
                condition.wait(lck);
111
            }
112
        }else{
113
            // Wait for "joinWaitMillis" milliseconds for thread to finish
114
            std::unique_lock<std::mutex> lck(mutex);
115
            if(!threadDone && condition.wait_for(lck,std::chrono::milliseconds(milliseconds))==std::cv_status::timeout){
116
				// unable to completely wait for thread
117
            }
118
        }
119
    }
120
}
121

122
//-------------------------------------------------
123
void ofThread::sleep(long milliseconds){
124
	std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
125
}
126

127
//-------------------------------------------------
128
void ofThread::yield(){
129
	std::this_thread::yield();
130
}
131

132
//-------------------------------------------------
133
bool ofThread::isCurrentThread() const{
134
    return std::this_thread::get_id() == thread.get_id();
135
}
136

137
//-------------------------------------------------
138
std::thread & ofThread::getNativeThread(){
139
	return thread;
140
}
141

142
//-------------------------------------------------
143
const std::thread & ofThread::getNativeThread() const{
144
	return thread;
145
}
146

147
//-------------------------------------------------
148
void ofThread::threadedFunction(){
149
	ofLogWarning("ofThread") << "- name: " << getThreadName() << " - Override ofThread::threadedFunction() in your ofThread subclass.";
150
}
151

152
//-------------------------------------------------
153
void ofThread::run(){
154
#ifdef TARGET_ANDROID
155
	JNIEnv * env;
156
	jint attachResult = ofGetJavaVMPtr()->AttachCurrentThread(&env,nullptr);
157
	if(attachResult!=0){
158
		ofLogWarning() << "couldn't attach new thread to java vm";
159
	}
160
#endif
161

162
	// user function
163
    // should loop endlessly.
164
	try{
165
		threadedFunction();
166
	}catch(const std::exception& exc){
167
		ofLogFatalError("ofThreadErrorLogger::exception") << exc.what();
168
	}catch(...){
169
		ofLogFatalError("ofThreadErrorLogger::exception") << "Unknown exception.";
170
	}
171
	try{
172
		thread.detach();
173
	}catch(...){}
174
#ifdef TARGET_ANDROID
175
	attachResult = ofGetJavaVMPtr()->DetachCurrentThread();
176
#endif
177

178
    std::unique_lock<std::mutex> lck(mutex);
179
	threadRunning = false;
180
	threadDone = true;
181
    condition.notify_all();
182
}
183

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.