2727#include < cstdlib>
2828#include < cstring>
2929#include < cstdio>
30+ #include < errno.h>
3031#endif
3132
3233ThreadExecutor::ThreadExecutor (const std::vector<std::string> &filenames, const Settings &settings, ErrorLogger &errorLogger)
@@ -51,12 +52,15 @@ void ThreadExecutor::addFileContent(const std::string &path, const std::string &
5152
5253#if (defined(__GNUC__) || defined(__sun)) && !defined(__MINGW32__)
5354
54- bool ThreadExecutor::handleRead (unsigned int &result)
55+ int ThreadExecutor::handleRead (unsigned int &result)
5556{
5657 char type = 0 ;
5758 if (read (_pipe[0 ], &type, 1 ) <= 0 )
5859 {
59- return false ;
60+ if ( errno == EAGAIN )
61+ return 0 ;
62+
63+ return -1 ;
6064 }
6165
6266 if (type != ' 1' && type != ' 2' && type != ' 3' )
@@ -104,10 +108,12 @@ bool ThreadExecutor::handleRead(unsigned int &result)
104108 iss >> fileResult;
105109 result += fileResult;
106110 _errorLogger.reportStatus (_fileCount, _filenames.size ());
111+ delete [] buf;
112+ return -1 ;
107113 }
108114
109115 delete [] buf;
110- return true ;
116+ return 1 ;
111117}
112118
113119unsigned int ThreadExecutor::check ()
@@ -134,65 +140,68 @@ unsigned int ThreadExecutor::check()
134140 }
135141
136142 unsigned int childCount = 0 ;
137- for (unsigned int i = 0 ; i < _filenames.size (); i++)
143+ unsigned int i = 0 ;
144+ while ( true )
138145 {
139- // Keep only wanted amount of child processes running at a time.
140- if ( childCount >= _settings._jobs )
146+ // Start a new child
147+ if ( i < _filenames. size () && childCount < _settings._jobs )
141148 {
142- while (handleRead (result))
149+ pid_t pid = fork ();
150+ if (pid < 0 )
151+ {
152+ // Error
153+ std::cerr << " Failed to create child process" << std::endl;
154+ exit (EXIT_FAILURE);
155+ }
156+ else if (pid == 0 )
143157 {
158+ CppCheck fileChecker (*this );
159+ fileChecker.settings (_settings);
160+
161+ if (_fileContents.size () > 0 && _fileContents.find (_filenames[i]) != _fileContents.end ())
162+ {
163+ // File content was given as a string
164+ fileChecker.addFile (_filenames[i], _fileContents[ _filenames[i] ]);
165+ }
166+ else
167+ {
168+ // Read file from a file
169+ fileChecker.addFile (_filenames[i]);
170+ }
171+
172+ unsigned int resultOfCheck = fileChecker.check ();
173+ std::ostringstream oss;
174+ oss << resultOfCheck;
175+ writeToPipe (' 3' , oss.str ());
176+ exit (0 );
177+ }
144178
179+ ++childCount;
180+ ++i;
181+ }
182+ else if (childCount > 0 )
183+ {
184+ // Wait for child to quit before stating new processes
185+ while (true )
186+ {
187+ int readRes = handleRead (result);
188+ if ( readRes == -1 )
189+ break ;
190+ else if ( readRes == 0 )
191+ usleep (5000 ); // 5 ms
145192 }
146193
147194 int stat = 0 ;
148195 waitpid (0 , &stat, 0 );
149196 --childCount;
150197 }
151-
152- pid_t pid = fork ();
153- if (pid < 0 )
198+ else if (childCount == 0 )
154199 {
155- // Error
156- std::cerr << " Failed to create child process" << std::endl;
157- exit (EXIT_FAILURE);
200+ // All done
201+ break ;
158202 }
159- else if (pid == 0 )
160- {
161- CppCheck fileChecker (*this );
162- fileChecker.settings (_settings);
163-
164- if (_fileContents.size () > 0 && _fileContents.find (_filenames[i]) != _fileContents.end ())
165- {
166- // File content was given as a string
167- fileChecker.addFile (_filenames[i], _fileContents[ _filenames[i] ]);
168- }
169- else
170- {
171- // Read file from a file
172- fileChecker.addFile (_filenames[i]);
173- }
174-
175- unsigned int resultOfCheck = fileChecker.check ();
176- std::ostringstream oss;
177- oss << resultOfCheck;
178- writeToPipe (' 3' , oss.str ());
179- exit (0 );
180- }
181-
182- ++childCount;
183203 }
184204
185- while (childCount > 0 )
186- {
187- int stat = 0 ;
188- waitpid (0 , &stat, 0 );
189- --childCount;
190- }
191-
192- while (handleRead (result))
193- {
194-
195- }
196205
197206 return result;
198207}
0 commit comments