~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/windowmanager/intern/wm_jobs.c

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
#include "BLI_blenlib.h"
39
39
#include "BLI_threads.h"
 
40
#include "BLI_utildefines.h"
40
41
 
41
42
#include "BKE_blender.h"
42
43
#include "BKE_context.h"
53
54
#include "wm_event_types.h"
54
55
#include "wm.h"
55
56
 
56
 
 
 
57
#include "PIL_time.h"
57
58
 
58
59
/* ********************** Threaded Jobs Manager ****************************** */
59
60
 
113
114
/* internal */
114
115
        void *owner;
115
116
        int flag;
116
 
        short suspended, running, ready, do_update, stop;
 
117
        short suspended, running, ready, do_update, stop, job_type;
117
118
        float progress;
118
119
 
119
120
        /* for display in header, identification */
126
127
        /* we use BLI_threads api, but per job only 1 thread runs */
127
128
        ListBase threads;
128
129
 
 
130
        double start_time;
129
131
};
130
132
 
131
133
/* finds:
132
 
 * 1st priority: job with same owner and name
133
 
 * 2nd priority: job with same owner
 
134
 * if type, compare for it, otherwise any matching job 
134
135
 */
135
 
static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const char *name)
 
136
static wmJob *wm_job_find(wmWindowManager *wm, void *owner, const int job_type)
136
137
{
137
 
        wmJob *steve, *found = NULL;
 
138
        wmJob *wm_job;
138
139
        
139
 
        for (steve = wm->jobs.first; steve; steve = steve->next)
140
 
                if (steve->owner == owner) {
141
 
                        found = steve;
142
 
                        if (name && strcmp(steve->name, name) == 0)
143
 
                                return steve;
 
140
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next)
 
141
                if (wm_job->owner == owner) {
 
142
                        
 
143
                        if (job_type) {
 
144
                                if ( wm_job->job_type == job_type)
 
145
                                        return wm_job;
 
146
                        }
 
147
                        else
 
148
                                return wm_job;
144
149
                }
145
150
        
146
 
        return found;
 
151
        return NULL;
147
152
}
148
153
 
149
154
/* ******************* public API ***************** */
150
155
 
151
156
/* returns current or adds new job, but doesnt run it */
152
 
/* every owner only gets a single job, adding a new one will stop running stop and 
 
157
/* every owner only gets a single job, adding a new one will stop running job and 
153
158
 * when stopped it starts the new one */
154
 
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag)
 
159
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, const char *name, int flag, int job_type)
155
160
{
156
 
        wmJob *steve = wm_job_find(wm, owner, name);
157
 
        
158
 
        if (steve == NULL) {
159
 
                steve = MEM_callocN(sizeof(wmJob), "new job");
160
 
        
161
 
                BLI_addtail(&wm->jobs, steve);
162
 
                steve->win = win;
163
 
                steve->owner = owner;
164
 
                steve->flag = flag;
165
 
                BLI_strncpy(steve->name, name, sizeof(steve->name));
 
161
        wmJob *wm_job = wm_job_find(wm, owner, job_type);
 
162
        
 
163
        if (wm_job == NULL) {
 
164
                wm_job = MEM_callocN(sizeof(wmJob), "new job");
 
165
        
 
166
                BLI_addtail(&wm->jobs, wm_job);
 
167
                wm_job->win = win;
 
168
                wm_job->owner = owner;
 
169
                wm_job->flag = flag;
 
170
                wm_job->job_type = job_type;
 
171
                BLI_strncpy(wm_job->name, name, sizeof(wm_job->name));
166
172
        }
 
173
        /* else: a running job, be careful */
167
174
        
168
 
        return steve;
 
175
        /* prevent creating a job with an invalid type */
 
176
        BLI_assert(wm_job->job_type != WM_JOB_TYPE_ANY);
 
177
 
 
178
        return wm_job;
169
179
}
170
180
 
171
181
/* returns true if job runs, for UI (progress) indicators */
172
 
int WM_jobs_test(wmWindowManager *wm, void *owner)
 
182
int WM_jobs_test(wmWindowManager *wm, void *owner, int job_type)
173
183
{
174
 
        wmJob *steve;
 
184
        wmJob *wm_job;
175
185
        
176
186
        /* job can be running or about to run (suspended) */
177
 
        for (steve = wm->jobs.first; steve; steve = steve->next)
178
 
                if (steve->owner == owner)
179
 
                        if (steve->running || steve->suspended)
180
 
                                return 1;
 
187
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
 
188
                if (wm_job->owner == owner) {
 
189
                        if (job_type == WM_JOB_TYPE_ANY || (wm_job->job_type == job_type)) {
 
190
                                if (wm_job->running || wm_job->suspended) {
 
191
                                        return TRUE;
 
192
                                }
 
193
                        }
 
194
                }
 
195
        }
181
196
 
182
 
        return 0;
 
197
        return FALSE;
183
198
}
184
199
 
185
200
float WM_jobs_progress(wmWindowManager *wm, void *owner)
186
201
{
187
 
        wmJob *steve = wm_job_find(wm, owner, NULL);
 
202
        wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY);
188
203
        
189
 
        if (steve && steve->flag & WM_JOB_PROGRESS)
190
 
                return steve->progress;
 
204
        if (wm_job && wm_job->flag & WM_JOB_PROGRESS)
 
205
                return wm_job->progress;
191
206
        
192
207
        return 0.0;
193
208
}
194
209
 
195
210
char *WM_jobs_name(wmWindowManager *wm, void *owner)
196
211
{
197
 
        wmJob *steve = wm_job_find(wm, owner, NULL);
 
212
        wmJob *wm_job = wm_job_find(wm, owner, WM_JOB_TYPE_ANY);
198
213
        
199
 
        if (steve)
200
 
                return steve->name;
 
214
        if (wm_job)
 
215
                return wm_job->name;
201
216
        
202
217
        return NULL;
203
218
}
204
219
 
205
 
int WM_jobs_is_running(wmJob *steve)
 
220
int WM_jobs_is_running(wmJob *wm_job)
206
221
{
207
 
        return steve->running;
 
222
        return wm_job->running;
208
223
}
209
224
 
210
 
void *WM_jobs_get_customdata(wmJob *steve)
 
225
void *WM_jobs_customdata_get(wmJob *wm_job)
211
226
{
212
 
        if (!steve->customdata) {
213
 
                return steve->run_customdata;
 
227
        if (!wm_job->customdata) {
 
228
                return wm_job->run_customdata;
214
229
        }
215
230
        else {
216
 
                return steve->customdata;
 
231
                return wm_job->customdata;
217
232
        }
218
233
}
219
234
 
220
 
void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *))
 
235
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void (*free)(void *))
221
236
{
222
237
        /* pending job? just free */
223
 
        if (steve->customdata)
224
 
                steve->free(steve->customdata);
 
238
        if (wm_job->customdata)
 
239
                wm_job->free(wm_job->customdata);
225
240
        
226
 
        steve->customdata = customdata;
227
 
        steve->free = free;
 
241
        wm_job->customdata = customdata;
 
242
        wm_job->free = free;
228
243
 
229
 
        if (steve->running) {
 
244
        if (wm_job->running) {
230
245
                /* signal job to end */
231
 
                steve->stop = 1;
 
246
                wm_job->stop = TRUE;
232
247
        }
233
248
}
234
249
 
235
 
void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note, unsigned int endnote)
 
250
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
236
251
{
237
 
        steve->timestep = timestep;
238
 
        steve->note = note;
239
 
        steve->endnote = endnote;
 
252
        wm_job->timestep = timestep;
 
253
        wm_job->note = note;
 
254
        wm_job->endnote = endnote;
240
255
}
241
256
 
242
 
void WM_jobs_callbacks(wmJob *steve, 
 
257
void WM_jobs_callbacks(wmJob *wm_job,
243
258
                       void (*startjob)(void *, short *, short *, float *),
244
259
                       void (*initjob)(void *),
245
260
                       void (*update)(void *),
246
261
                       void (*endjob)(void *))
247
262
{
248
 
        steve->startjob = startjob;
249
 
        steve->initjob = initjob;
250
 
        steve->update = update;
251
 
        steve->endjob = endjob;
 
263
        wm_job->startjob = startjob;
 
264
        wm_job->initjob = initjob;
 
265
        wm_job->update = update;
 
266
        wm_job->endjob = endjob;
252
267
}
253
268
 
254
269
static void *do_job_thread(void *job_v)
255
270
{
256
 
        wmJob *steve = job_v;
 
271
        wmJob *wm_job = job_v;
257
272
        
258
 
        steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update, &steve->progress);
259
 
        steve->ready = 1;
 
273
        wm_job->startjob(wm_job->run_customdata, &wm_job->stop, &wm_job->do_update, &wm_job->progress);
 
274
        wm_job->ready = TRUE;
260
275
        
261
276
        return NULL;
262
277
}
264
279
/* don't allow same startjob to be executed twice */
265
280
static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test)
266
281
{
267
 
        wmJob *steve;
268
 
        int suspend = 0;
 
282
        wmJob *wm_job;
 
283
        int suspend = FALSE;
269
284
        
270
285
        /* job added with suspend flag, we wait 1 timer step before activating it */
271
286
        if (test->flag & WM_JOB_SUSPEND) {
272
 
                suspend = 1;
 
287
                suspend = TRUE;
273
288
                test->flag &= ~WM_JOB_SUSPEND;
274
289
        }
275
290
        else {
276
291
                /* check other jobs */
277
 
                for (steve = wm->jobs.first; steve; steve = steve->next) {
 
292
                for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
278
293
                        /* obvious case, no test needed */
279
 
                        if (steve == test || !steve->running) continue;
 
294
                        if (wm_job == test || !wm_job->running) {
 
295
                                continue;
 
296
                        }
280
297
                        
281
298
                        /* if new job is not render, then check for same startjob */
282
299
                        if (0 == (test->flag & WM_JOB_EXCL_RENDER))
283
 
                                if (steve->startjob != test->startjob)
 
300
                                if (wm_job->startjob != test->startjob)
284
301
                                        continue;
285
302
                        
286
303
                        /* if new job is render, any render job should be stopped */
287
304
                        if (test->flag & WM_JOB_EXCL_RENDER)
288
 
                                if (0 == (steve->flag & WM_JOB_EXCL_RENDER))
 
305
                                if (0 == (wm_job->flag & WM_JOB_EXCL_RENDER))
289
306
                                        continue;
290
307
 
291
 
                        suspend = 1;
 
308
                        suspend = TRUE;
292
309
 
293
310
                        /* if this job has higher priority, stop others */
294
311
                        if (test->flag & WM_JOB_PRIORITY) {
295
 
                                steve->stop = 1;
296
 
                                // printf("job stopped: %s\n", steve->name);
 
312
                                wm_job->stop = TRUE;
 
313
                                // printf("job stopped: %s\n", wm_job->name);
297
314
                        }
298
315
                }
299
316
        }
305
322
 
306
323
/* if job running, the same owner gave it a new job */
307
324
/* if different owner starts existing startjob, it suspends itself */
308
 
void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
 
325
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
309
326
{
310
 
        if (steve->running) {
 
327
        if (wm_job->running) {
311
328
                /* signal job to end and restart */
312
 
                steve->stop = 1;
313
 
                // printf("job started a running job, ending... %s\n", steve->name);
 
329
                wm_job->stop = TRUE;
 
330
                // printf("job started a running job, ending... %s\n", wm_job->name);
314
331
        }
315
332
        else {
316
333
                
317
 
                if (steve->customdata && steve->startjob) {
318
 
                        
319
 
                        wm_jobs_test_suspend_stop(wm, steve);
320
 
                        
321
 
                        if (steve->suspended == 0) {
 
334
                if (wm_job->customdata && wm_job->startjob) {
 
335
                        
 
336
                        wm_jobs_test_suspend_stop(wm, wm_job);
 
337
                        
 
338
                        if (wm_job->suspended == FALSE) {
322
339
                                /* copy to ensure proper free in end */
323
 
                                steve->run_customdata = steve->customdata;
324
 
                                steve->run_free = steve->free;
325
 
                                steve->free = NULL;
326
 
                                steve->customdata = NULL;
327
 
                                steve->running = 1;
328
 
                                
329
 
                                if (steve->initjob)
330
 
                                        steve->initjob(steve->run_customdata);
331
 
                                
332
 
                                steve->stop = 0;
333
 
                                steve->ready = 0;
334
 
                                steve->progress = 0.0;
 
340
                                wm_job->run_customdata = wm_job->customdata;
 
341
                                wm_job->run_free = wm_job->free;
 
342
                                wm_job->free = NULL;
 
343
                                wm_job->customdata = NULL;
 
344
                                wm_job->running = TRUE;
 
345
                                
 
346
                                if (wm_job->initjob)
 
347
                                        wm_job->initjob(wm_job->run_customdata);
 
348
                                
 
349
                                wm_job->stop = FALSE;
 
350
                                wm_job->ready = FALSE;
 
351
                                wm_job->progress = 0.0;
335
352
 
336
 
                                // printf("job started: %s\n", steve->name);
 
353
                                // printf("job started: %s\n", wm_job->name);
337
354
                                
338
 
                                BLI_init_threads(&steve->threads, do_job_thread, 1);
339
 
                                BLI_insert_thread(&steve->threads, steve);
 
355
                                BLI_init_threads(&wm_job->threads, do_job_thread, 1);
 
356
                                BLI_insert_thread(&wm_job->threads, wm_job);
340
357
                        }
341
358
                        
342
359
                        /* restarted job has timer already */
343
 
                        if (steve->wt == NULL)
344
 
                                steve->wt = WM_event_add_timer(wm, steve->win, TIMERJOBS, steve->timestep);
 
360
                        if (wm_job->wt == NULL)
 
361
                                wm_job->wt = WM_event_add_timer(wm, wm_job->win, TIMERJOBS, wm_job->timestep);
 
362
 
 
363
                        if (G.debug & G_DEBUG_JOBS)
 
364
                                wm_job->start_time = PIL_check_seconds_timer();
345
365
                }
346
366
                else printf("job fails, not initialized\n");
347
367
        }
348
368
}
349
369
 
350
 
/* stop job, free data completely */
351
 
static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve)
 
370
/* stop job, end thread, free data completely */
 
371
static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
352
372
{
353
 
        if (steve->running) {
 
373
        if (wm_job->running) {
354
374
                /* signal job to end */
355
 
                steve->stop = 1;
356
 
                BLI_end_threads(&steve->threads);
357
 
 
358
 
                if (steve->endjob)
359
 
                        steve->endjob(steve->run_customdata);
360
 
        }
361
 
        
362
 
        if (steve->wt)
363
 
                WM_event_remove_timer(wm, steve->win, steve->wt);
364
 
        if (steve->customdata)
365
 
                steve->free(steve->customdata);
366
 
        if (steve->run_customdata)
367
 
                steve->run_free(steve->run_customdata);
368
 
        
369
 
        /* remove steve */
370
 
        BLI_remlink(&wm->jobs, steve);
371
 
        MEM_freeN(steve);
372
 
        
373
 
}
374
 
 
375
 
void WM_jobs_stop_all(wmWindowManager *wm)
376
 
{
377
 
        wmJob *steve;
378
 
        
379
 
        while ((steve = wm->jobs.first))
380
 
                wm_jobs_kill_job(wm, steve);
381
 
        
 
375
                wm_job->stop = TRUE;
 
376
                BLI_end_threads(&wm_job->threads);
 
377
 
 
378
                if (wm_job->endjob)
 
379
                        wm_job->endjob(wm_job->run_customdata);
 
380
        }
 
381
        
 
382
        if (wm_job->wt)
 
383
                WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
 
384
        if (wm_job->customdata)
 
385
                wm_job->free(wm_job->customdata);
 
386
        if (wm_job->run_customdata)
 
387
                wm_job->run_free(wm_job->run_customdata);
 
388
        
 
389
        /* remove wm_job */
 
390
        BLI_remlink(&wm->jobs, wm_job);
 
391
        MEM_freeN(wm_job);
 
392
        
 
393
}
 
394
 
 
395
/* wait until every job ended */
 
396
void WM_jobs_kill_all(wmWindowManager *wm)
 
397
{
 
398
        wmJob *wm_job;
 
399
        
 
400
        while ((wm_job = wm->jobs.first))
 
401
                wm_jobs_kill_job(wm, wm_job);
 
402
        
 
403
}
 
404
 
 
405
/* wait until every job ended, except for one owner (used in undo to keep screen job alive) */
 
406
void WM_jobs_kill_all_except(wmWindowManager *wm, void *owner)
 
407
{
 
408
        wmJob *wm_job, *next_job;
 
409
        
 
410
        for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
 
411
                next_job = wm_job->next;
 
412
 
 
413
                if (wm_job->owner != owner)
 
414
                        wm_jobs_kill_job(wm, wm_job);
 
415
        }
 
416
}
 
417
 
 
418
 
 
419
void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type)
 
420
{
 
421
        wmJob *wm_job, *next_job;
 
422
        
 
423
        for (wm_job = wm->jobs.first; wm_job; wm_job = next_job) {
 
424
                next_job = wm_job->next;
 
425
 
 
426
                if (wm_job->job_type == job_type)
 
427
                        wm_jobs_kill_job(wm, wm_job);
 
428
        }
382
429
}
383
430
 
384
431
/* signal job(s) from this owner or callback to stop, timer is required to get handled */
385
432
void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
386
433
{
387
 
        wmJob *steve;
 
434
        wmJob *wm_job;
388
435
        
389
 
        for (steve = wm->jobs.first; steve; steve = steve->next)
390
 
                if (steve->owner == owner || steve->startjob == startjob)
391
 
                        if (steve->running)
392
 
                                steve->stop = 1;
 
436
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
 
437
                if (wm_job->owner == owner || wm_job->startjob == startjob) {
 
438
                        if (wm_job->running) {
 
439
                                wm_job->stop = TRUE;
 
440
                        }
 
441
                }
 
442
        }
393
443
}
394
444
 
395
445
/* actually terminate thread and job timer */
396
446
void WM_jobs_kill(wmWindowManager *wm, void *owner, void (*startjob)(void *, short int *, short int *, float *))
397
447
{
398
 
        wmJob *steve;
 
448
        wmJob *wm_job;
399
449
        
400
 
        steve = wm->jobs.first;
401
 
        while (steve) {
402
 
                if (steve->owner == owner || steve->startjob == startjob) {
403
 
                        wmJob *bill = steve;
404
 
                        steve = steve->next;
 
450
        wm_job = wm->jobs.first;
 
451
        while (wm_job) {
 
452
                if (wm_job->owner == owner || wm_job->startjob == startjob) {
 
453
                        wmJob *bill = wm_job;
 
454
                        wm_job = wm_job->next;
405
455
                        wm_jobs_kill_job(wm, bill);
406
456
                }
407
457
                else {
408
 
                        steve = steve->next;
 
458
                        wm_job = wm_job->next;
409
459
                }
410
460
        }
411
461
}
414
464
/* kill job entirely, also removes timer itself */
415
465
void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
416
466
{
417
 
        wmJob *steve;
 
467
        wmJob *wm_job;
418
468
        
419
 
        for (steve = wm->jobs.first; steve; steve = steve->next) {
420
 
                if (steve->wt == wt) {
421
 
                        wm_jobs_kill_job(wm, steve);
 
469
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
 
470
                if (wm_job->wt == wt) {
 
471
                        wm_jobs_kill_job(wm, wm_job);
422
472
                        return;
423
473
                }
424
474
        }
427
477
/* hardcoded to event TIMERJOBS */
428
478
void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
429
479
{
430
 
        wmJob *steve = wm->jobs.first, *stevenext;
 
480
        wmJob *wm_job, *wm_jobnext;
431
481
        float total_progress = 0.f;
432
482
        float jobs_progress = 0;
433
483
        
434
484
        
435
 
        for (; steve; steve = stevenext) {
436
 
                stevenext = steve->next;
 
485
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) {
 
486
                wm_jobnext = wm_job->next;
437
487
                
438
 
                if (steve->wt == wt) {
 
488
                if (wm_job->wt == wt) {
439
489
                        
440
490
                        /* running threads */
441
 
                        if (steve->threads.first) {
 
491
                        if (wm_job->threads.first) {
442
492
                                
443
493
                                /* always call note and update when ready */
444
 
                                if (steve->do_update || steve->ready) {
445
 
                                        if (steve->update)
446
 
                                                steve->update(steve->run_customdata);
447
 
                                        if (steve->note)
448
 
                                                WM_event_add_notifier(C, steve->note, NULL);
 
494
                                if (wm_job->do_update || wm_job->ready) {
 
495
                                        if (wm_job->update)
 
496
                                                wm_job->update(wm_job->run_customdata);
 
497
                                        if (wm_job->note)
 
498
                                                WM_event_add_notifier(C, wm_job->note, NULL);
449
499
 
450
 
                                        if (steve->flag & WM_JOB_PROGRESS)
 
500
                                        if (wm_job->flag & WM_JOB_PROGRESS)
451
501
                                                WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
452
 
                                        steve->do_update = 0;
453
 
                                }       
 
502
                                        wm_job->do_update = FALSE;
 
503
                                }
454
504
                                
455
 
                                if (steve->ready) {
456
 
                                        if (steve->endjob)
457
 
                                                steve->endjob(steve->run_customdata);
 
505
                                if (wm_job->ready) {
 
506
                                        if (wm_job->endjob)
 
507
                                                wm_job->endjob(wm_job->run_customdata);
458
508
 
459
509
                                        /* free own data */
460
 
                                        steve->run_free(steve->run_customdata);
461
 
                                        steve->run_customdata = NULL;
462
 
                                        steve->run_free = NULL;
463
 
                                        
464
 
                                        // if (steve->stop) printf("job ready but stopped %s\n", steve->name);
465
 
                                        // else printf("job finished %s\n", steve->name);
466
 
 
467
 
                                        steve->running = 0;
468
 
                                        BLI_end_threads(&steve->threads);
469
 
                                        
470
 
                                        if (steve->endnote)
471
 
                                                WM_event_add_notifier(C, steve->endnote, NULL);
 
510
                                        wm_job->run_free(wm_job->run_customdata);
 
511
                                        wm_job->run_customdata = NULL;
 
512
                                        wm_job->run_free = NULL;
 
513
                                        
 
514
                                        // if (wm_job->stop) printf("job ready but stopped %s\n", wm_job->name);
 
515
                                        // else printf("job finished %s\n", wm_job->name);
 
516
 
 
517
                                        if (G.debug & G_DEBUG_JOBS) {
 
518
                                                printf("Job '%s' finished in %f seconds\n", wm_job->name,
 
519
                                                       PIL_check_seconds_timer() - wm_job->start_time);
 
520
                                        }
 
521
 
 
522
                                        wm_job->running = FALSE;
 
523
                                        BLI_end_threads(&wm_job->threads);
 
524
                                        
 
525
                                        if (wm_job->endnote)
 
526
                                                WM_event_add_notifier(C, wm_job->endnote, NULL);
472
527
                                        
473
528
                                        WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
474
 
                                        
475
 
                                        /* new job added for steve? */
476
 
                                        if (steve->customdata) {
477
 
                                                // printf("job restarted with new data %s\n", steve->name);
478
 
                                                WM_jobs_start(wm, steve);
 
529
 
 
530
                                        /* so the info header updates on job end even if the mouse doesn't move.
 
531
                                         * a rather annoying/obscure bug, see [#32537] (second reply) */
 
532
                                        WM_event_add_mousemove_window(wm_job->win);
 
533
 
 
534
                                        /* new job added for wm_job? */
 
535
                                        if (wm_job->customdata) {
 
536
                                                // printf("job restarted with new data %s\n", wm_job->name);
 
537
                                                WM_jobs_start(wm, wm_job);
479
538
                                        }
480
539
                                        else {
481
 
                                                WM_event_remove_timer(wm, steve->win, steve->wt);
482
 
                                                steve->wt = NULL;
 
540
                                                WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
 
541
                                                wm_job->wt = NULL;
483
542
                                                
484
 
                                                /* remove steve */
485
 
                                                BLI_remlink(&wm->jobs, steve);
486
 
                                                MEM_freeN(steve);
 
543
                                                /* remove wm_job */
 
544
                                                BLI_remlink(&wm->jobs, wm_job);
 
545
                                                MEM_freeN(wm_job);
487
546
                                        }
488
547
                                }
489
 
                                else if (steve->flag & WM_JOB_PROGRESS) {
 
548
                                else if (wm_job->flag & WM_JOB_PROGRESS) {
490
549
                                        /* accumulate global progress for running jobs */
491
550
                                        jobs_progress++;
492
 
                                        total_progress += steve->progress;
 
551
                                        total_progress += wm_job->progress;
493
552
                                }
494
553
                        }
495
 
                        else if (steve->suspended) {
496
 
                                WM_jobs_start(wm, steve);
 
554
                        else if (wm_job->suspended) {
 
555
                                WM_jobs_start(wm, wm_job);
497
556
                        }
498
557
                }
499
 
                else if (steve->threads.first && !steve->ready) {
500
 
                        if (steve->flag & WM_JOB_PROGRESS) {
 
558
                else if (wm_job->threads.first && !wm_job->ready) {
 
559
                        if (wm_job->flag & WM_JOB_PROGRESS) {
501
560
                                /* accumulate global progress for running jobs */
502
561
                                jobs_progress++;
503
 
                                total_progress += steve->progress;
 
562
                                total_progress += wm_job->progress;
504
563
                        }
505
564
                }
506
565
        }
520
579
 
521
580
int WM_jobs_has_running(wmWindowManager *wm)
522
581
{
523
 
        wmJob *steve;
524
 
 
525
 
        for (steve = wm->jobs.first; steve; steve = steve->next)
526
 
                if (steve->running)
527
 
                        return 1;
528
 
 
529
 
        return 0;
 
582
        wmJob *wm_job;
 
583
 
 
584
        for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) {
 
585
                if (wm_job->running) {
 
586
                        return TRUE;
 
587
                }
 
588
        }
 
589
 
 
590
        return FALSE;
530
591
}