Esempio n. 1
0
/* stop job, end thread, free data completely */
static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *wm_job)
{
	if (wm_job->running) {
		/* signal job to end */
		wm_job->stop = TRUE;
		wm_job_main_thread_yield(wm_job, true);
		BLI_end_threads(&wm_job->threads);

		if (wm_job->endjob)
			wm_job->endjob(wm_job->run_customdata);
	}
	
	if (wm_job->wt)
		WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
	if (wm_job->customdata)
		wm_job->free(wm_job->customdata);
	if (wm_job->run_customdata)
		wm_job->run_free(wm_job->run_customdata);
	
	/* remove wm_job */
	wm_job_free(wm, wm_job);
}
Esempio n. 2
0
/* hardcoded to event TIMERJOBS */
void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
{
	wmJob *wm_job, *wm_jobnext;
	float total_progress = 0.f;
	float jobs_progress = 0;

	for (wm_job = wm->jobs.first; wm_job; wm_job = wm_jobnext) {
		wm_jobnext = wm_job->next;

		if (wm_job->wt == wt) {

			/* running threads */
			if (wm_job->threads.first) {

				/* let threads get temporary lock over main thread if needed */
				wm_job_main_thread_yield(wm_job);

				/* always call note and update when ready */
				if (wm_job->do_update || wm_job->ready) {
					if (wm_job->update)
						wm_job->update(wm_job->run_customdata);
					if (wm_job->note)
						WM_event_add_notifier(C, wm_job->note, NULL);

					if (wm_job->flag & WM_JOB_PROGRESS)
						WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);
					wm_job->do_update = false;
				}

				if (wm_job->ready) {
					if (wm_job->endjob)
						wm_job->endjob(wm_job->run_customdata);

					/* free own data */
					wm_job->run_free(wm_job->run_customdata);
					wm_job->run_customdata = NULL;
					wm_job->run_free = NULL;

					// if (wm_job->stop) printf("job ready but stopped %s\n", wm_job->name);
					// else printf("job finished %s\n", wm_job->name);

					if (G.debug & G_DEBUG_JOBS) {
						printf("Job '%s' finished in %f seconds\n", wm_job->name,
						       PIL_check_seconds_timer() - wm_job->start_time);
					}

					wm_job->running = false;

					WM_job_main_thread_lock_release(wm_job);
					BLI_threadpool_end(&wm_job->threads);
					WM_job_main_thread_lock_acquire(wm_job);

					if (wm_job->endnote)
						WM_event_add_notifier(C, wm_job->endnote, NULL);

					WM_event_add_notifier(C, NC_WM | ND_JOB, NULL);

					/* new job added for wm_job? */
					if (wm_job->customdata) {
						// printf("job restarted with new data %s\n", wm_job->name);
						WM_jobs_start(wm, wm_job);
					}
					else {
						WM_event_remove_timer(wm, wm_job->win, wm_job->wt);
						wm_job->wt = NULL;

						/* remove wm_job */
						wm_job_free(wm, wm_job);
					}
				}
				else if (wm_job->flag & WM_JOB_PROGRESS) {
					/* accumulate global progress for running jobs */
					jobs_progress++;
					total_progress += wm_job->progress;
				}
			}
			else if (wm_job->suspended) {
				WM_jobs_start(wm, wm_job);
			}
		}
		else if (wm_job->threads.first && !wm_job->ready) {
			if (wm_job->flag & WM_JOB_PROGRESS) {
				/* accumulate global progress for running jobs */
				jobs_progress++;
				total_progress += wm_job->progress;
			}
		}
	}


	/* if there are running jobs, set the global progress indicator */
	if (jobs_progress > 0) {
		wmWindow *win;
		float progress = total_progress / (float)jobs_progress;

		for (win = wm->windows.first; win; win = win->next)
			WM_progress_set(win, progress);
	}
	else {
		wmWindow *win;

		for (win = wm->windows.first; win; win = win->next)
			WM_progress_clear(win);
	}

}