@@ -92,6 +92,7 @@ ParallelFileProcessor::ParallelFileProcessor(const int n, const int verbose)
92
92
{
93
93
threadPool.clear ();
94
94
nJobs = n;
95
+ nProcessing = 0 ;
95
96
nProcessed = 0 ;
96
97
allDoneEvent = NULL ;
97
98
ioLock = new CRITSECTLOCK (4000 );
@@ -157,7 +158,11 @@ int ParallelFileProcessor::run()
157
158
}
158
159
if ( allDoneEvent ){
159
160
DWORD waitResult = ~WAIT_OBJECT_0;
160
- while ( nJobs >= 1 && !quitRequested () && size () > 0 && waitResult != WAIT_OBJECT_0 ){
161
+ // contrary to what one might expect, we should NOT use size()==0 as a stopping criterium.
162
+ // The queue size is decreased when a worker picks a new file to process, not when it's
163
+ // finished. Using size()==0 as a stopping criterium caused the processing interrupts
164
+ // that were observed with large files.
165
+ while ( nJobs >= 1 && !quitRequested () && waitResult != WAIT_OBJECT_0 ){
161
166
waitResult = WaitForSingleObject ( allDoneEvent, 2000 );
162
167
if ( nJobs ){
163
168
double perc = 100.0 * nProcessed / N;
@@ -176,10 +181,15 @@ int ParallelFileProcessor::run()
176
181
prevPerc = perc;
177
182
}
178
183
}
179
- if ( quitRequested () && !threadPool.empty () ){
180
- // the WaitForSingleObject() call above was interrupted by the signal that
181
- // led to quitRequested() being set and as a result the workers haven't yet
182
- // had the chance to exit cleanly. Give them that chance now.
184
+ }
185
+ if ( (quitRequested () && !threadPool.empty ()) || nProcessing > 0 ){
186
+ // the WaitForSingleObject() call above was interrupted by the signal that
187
+ // led to quitRequested() being set and as a result the workers haven't yet
188
+ // had the chance to exit cleanly. Give them that chance now.
189
+ fprintf ( stderr, " quitting [%ld]..." , nProcessing ); fflush (stderr);
190
+ waitResult = WaitForSingleObject ( allDoneEvent, 2000 );
191
+ for ( i = 0 ; i < 4 && waitResult == WAIT_TIMEOUT ; ++i ){
192
+ fprintf ( stderr, " [%ld]..." , nProcessing) ; fflush (stderr);
183
193
waitResult = WaitForSingleObject ( allDoneEvent, 2000 );
184
194
}
185
195
}
@@ -191,7 +201,11 @@ int ParallelFileProcessor::run()
191
201
while ( !threadPool.empty () ){
192
202
FileProcessor *thread = threadPool.front ();
193
203
if ( thread->GetExitCode () == (THREAD_RETURN)STILL_ACTIVE ){
194
- fprintf ( stderr, " Stopping worker thread #%d that is still active!\n " , i );
204
+ fprintf ( stderr, " Stopping worker thread #%d that is still %s!\n " , i, (thread->scope )? " processing" : " active" );
205
+ std::string currentFileName = thread->currentFileName ();
206
+ if ( currentFileName.c_str ()[0 ] ){
207
+ fprintf ( stderr, " \t current file: %s\n " , currentFileName.c_str () );
208
+ }
195
209
thread->Stop (true );
196
210
}
197
211
if ( thread->nProcessed ){
@@ -229,10 +243,10 @@ int ParallelFileProcessor::run()
229
243
230
244
int ParallelFileProcessor::workerDone (FileProcessor *worker)
231
245
{ CRITSECTLOCK::Scope scope (threadLock);
232
- char name[17 ];
246
+ // char name[17];
247
+ // pthread_getname_np( (pthread_t) GetThreadId(worker->GetThread()), name, sizeof(name) );
248
+ // fprintf( stderr, "workerDone(): worker \"%s\" is done; %ld workers left\n", name, nJobs - 1 );
233
249
nJobs -= 1 ;
234
- pthread_getname_np ( (pthread_t ) GetThreadId (worker->GetThread ()), name, sizeof (name) );
235
- // fprintf( stderr, "workerDone(): worker \"%s\" is done\n", name );
236
250
if ( nJobs <= 0 ){
237
251
if ( allDoneEvent ){
238
252
SetEvent (allDoneEvent);
@@ -252,8 +266,15 @@ DWORD FileProcessor::Run(LPVOID arg)
252
266
// create a scoped lock without closing it immediately
253
267
CRITSECTLOCK::Scope scp (PP->ioLock , 0 );
254
268
scope = &scp;
269
+ currentEntry = &entry;
270
+ _InterlockedIncrement (&PP->nProcessing );
255
271
entry.compress ( this , PP );
272
+ _InterlockedDecrement (&PP->nProcessing );
256
273
_InterlockedIncrement (&PP->nProcessed );
274
+ currentEntry = NULL ;
275
+ nProcessed += 1 ;
276
+ scope = NULL ;
277
+
257
278
runningTotalRaw += entry.fileInfo .st_size ;
258
279
runningTotalCompressed += (entry.compressedSize > 0 )? entry.compressedSize : entry.fileInfo .st_size ;
259
280
if ( PP->verbose () > 1 ){
@@ -264,8 +285,6 @@ DWORD FileProcessor::Run(LPVOID arg)
264
285
cpuUsage += info.cpu_usage /10.0 ;
265
286
}
266
287
}
267
- nProcessed += 1 ;
268
- scope = NULL ;
269
288
}
270
289
}
271
290
return DWORD (nProcessed);
@@ -281,19 +300,25 @@ void FileProcessor::InitThread()
281
300
282
301
inline bool FileProcessor::lockScope ()
283
302
{
284
- if ( scope ){
285
- PP->ioLockedFlag = scope->Lock ();
303
+ if ( PP ){
304
+ if ( scope ){
305
+ PP->ioLockedFlag = scope->Lock ();
306
+ }
307
+ return PP->ioLockedFlag ;
286
308
}
287
- return PP-> ioLockedFlag ;
309
+ return false ;
288
310
}
289
311
290
312
inline bool FileProcessor::unLockScope ()
291
313
{
292
- if ( scope ){
293
- scope->Unlock ();
294
- PP->ioLockedFlag = *scope;
314
+ if ( PP ){
315
+ if ( scope ){
316
+ scope->Unlock ();
317
+ PP->ioLockedFlag = *scope;
318
+ }
319
+ return PP->ioLockedFlag ;
295
320
}
296
- return PP-> ioLockedFlag ;
321
+ return false ;
297
322
}
298
323
299
324
// ================================= C interface functions =================================
0 commit comments