forked from danmar/cppcheck
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththreadexecutor.h
154 lines (129 loc) · 4.39 KB
/
threadexecutor.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2019 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef THREADEXECUTOR_H
#define THREADEXECUTOR_H
#include "errorlogger.h"
#include "importproject.h"
#include <cstddef>
#include <list>
#include <map>
#include <string>
#if (defined(__GNUC__) || defined(__sun)) && !defined(__MINGW32__) && !defined(__CYGWIN__)
#define THREADING_MODEL_FORK
#elif defined(_WIN32)
#define THREADING_MODEL_WIN
#include <windows.h>
#endif
class Settings;
/// @addtogroup CLI
/// @{
/**
* This class will take a list of filenames and settings and check then
* all files using threads.
*/
class ThreadExecutor : public ErrorLogger {
public:
ThreadExecutor(const std::map<std::string, std::size_t> &files, Settings &settings, ErrorLogger &errorLogger);
ThreadExecutor(const ThreadExecutor &) = delete;
~ThreadExecutor() OVERRIDE;
void operator=(const ThreadExecutor &) = delete;
unsigned int check();
void reportOut(const std::string &outmsg) OVERRIDE;
void reportErr(const ErrorLogger::ErrorMessage &msg) OVERRIDE;
void reportInfo(const ErrorLogger::ErrorMessage &msg) OVERRIDE;
void reportVerification(const std::string &str) OVERRIDE;
/**
* @brief Add content to a file, to be used in unit testing.
*
* @param path File name (used as a key to link with real file).
* @param content If the file would be a real file, this should be
* the content of the file.
*/
void addFileContent(const std::string &path, const std::string &content);
private:
const std::map<std::string, std::size_t> &mFiles;
Settings &mSettings;
ErrorLogger &mErrorLogger;
unsigned int mFileCount;
#if defined(THREADING_MODEL_FORK)
/** @brief Key is file name, and value is the content of the file */
std::map<std::string, std::string> mFileContents;
private:
enum PipeSignal {REPORT_OUT='1',REPORT_ERROR='2', REPORT_INFO='3', REPORT_VERIFICATION='4', CHILD_END='5'};
/**
* Read from the pipe, parse and handle what ever is in there.
*@return -1 in case of error
* 0 if there is nothing in the pipe to be read
* 1 if we did read something
*/
int handleRead(int rpipe, unsigned int &result);
void writeToPipe(PipeSignal type, const std::string &data);
/**
* Write end of status pipe, different for each child.
* Not used in master process.
*/
std::list<std::string> mErrorList;
int mWpipe;
/**
* @brief Check load average condition
* @param nchildren - count of currently ran children
* @return true - if new process can be started
*/
bool checkLoadAverage(size_t nchildren);
public:
/**
* @return true if support for threads exist.
*/
static bool isEnabled() {
return true;
}
#elif defined(THREADING_MODEL_WIN)
private:
enum class MessageType {REPORT_ERROR, REPORT_INFO};
std::map<std::string, std::string> mFileContents;
std::map<std::string, std::size_t>::const_iterator mItNextFile;
std::list<ImportProject::FileSettings>::const_iterator mItNextFileSettings;
std::size_t mProcessedFiles;
std::size_t mTotalFiles;
std::size_t mProcessedSize;
std::size_t mTotalFileSize;
CRITICAL_SECTION mFileSync;
std::list<std::string> mErrorList;
CRITICAL_SECTION mErrorSync;
CRITICAL_SECTION mReportSync;
void report(const ErrorLogger::ErrorMessage &msg, MessageType msgType);
static unsigned __stdcall threadProc(void*);
public:
/**
* @return true if support for threads exist.
*/
static bool isEnabled() {
return true;
}
#else
public:
/**
* @return true if support for threads exist.
*/
static bool isEnabled() {
return false;
}
#endif
};
/// @}
#endif // THREADEXECUTOR_H