Esempio n. 1
0
/* This is also exported for teardown after background printing */
void
teardown_device_and_mem_for_thread(gx_device *dev, gp_thread_id thread_id, bool bg_print)
{
    gx_device_clist_common *thread_cdev = (gx_device_clist_common *)dev;
    gx_device_clist_reader *thread_crdev = (gx_device_clist_reader *)dev;
    gs_memory_t *thread_memory = dev->memory;

    /* First finish the thread */
    gp_thread_finish(thread_id);

    if (bg_print) {
        /* we are cleaning up a background printing thread, so we clean up similarly to */
        /* what is done  by clist_finish_page, but without re-opening the clist files.  */
        clist_teardown_render_threads(dev);	/* we may have used multiple threads */
        /* free the thread's icc_table since this was not done by clist_finish_page */
        clist_free_icc_table(thread_crdev->icc_table, thread_memory);
        thread_crdev->icc_table = NULL;
        /* NB: gdev_prn_free_memory below will free the color_usage_array */
    } else {
        /* make sure this doesn't get freed by gdev_prn_free_memory below */
        ((gx_device_clist_reader *)thread_cdev)->color_usage_array = NULL;
    }
    rc_decrement(thread_crdev->icc_cache_cl, "teardown_render_thread");
    thread_crdev->icc_cache_cl = NULL;
    /*
     * Free the BufferSpace, close the band files, optionally unlinking them.
     * We unlink the files if this call is cleaning up from bg printing.
     * Note that the BufferSpace is freed using 'ppdev->buf' so the 'data'
     * pointer doesn't need to be the one that the thread started with
     */
    /* If this thread was being used for background printing and NumRenderingThreads > 0 */
    /* the clist_setup_render_threads may have already closed these files                */
    if (thread_cdev->page_info.cfile != NULL)
        thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.bfile, thread_cdev->page_info.bfname, bg_print);
    if (thread_cdev->page_info.bfile != NULL)
        thread_cdev->page_info.io_procs->fclose(thread_cdev->page_info.cfile, thread_cdev->page_info.cfname, bg_print);
    thread_cdev->do_not_open_or_close_bandfiles = true; /* we already closed the files */

    gdev_prn_free_memory((gx_device *)thread_cdev);
    /* Free the device copy this thread used.  Note that the
       deviceN stuff if was allocated and copied earlier for the device
       will be freed with this call and the icc_struct ref count will be decremented. */
    gs_free_object(thread_memory, thread_cdev, "clist_teardown_render_threads");
#ifdef DEBUG
    dmprintf(thread_memory, "rendering thread ending memory state...\n");
    gs_memory_chunk_dump_memory(thread_memory);
    dmprintf(thread_memory, "                                    memory dump done.\n");
#endif
    gs_memory_chunk_release(thread_memory);
}
Esempio n. 2
0
void
clist_teardown_render_threads(gx_device *dev)
{
    gx_device_clist *cldev = (gx_device_clist *)dev;
    gx_device_clist_common *cdev = (gx_device_clist_common *)dev;
    gx_device_clist_reader *crdev = &cldev->reader;
    gs_memory_t *mem = cdev->bandlist_memory;
    int i;

    if (crdev->render_threads != NULL) {

	/* Wait for each thread to finish then free its memory */
	for (i = (crdev->num_render_threads - 1); i >= 0; i--) {
	    clist_render_thread_control_t *thread = &(crdev->render_threads[i]);
	    gx_device_clist_common *thread_cdev = (gx_device_clist_common *)thread->cdev;

	    if (thread->status == RENDER_THREAD_BUSY)
		gx_semaphore_wait(thread->sema_this);
	    /* Free control semaphores */
	    gx_semaphore_free(thread->sema_group);
	    gx_semaphore_free(thread->sema_this);
	    /* destroy the thread's buffer device */
	    thread_cdev->buf_procs.destroy_buf_device(thread->bdev);
	    /*
	     * Free the BufferSpace, close the band files 
	     * Note that the BufferSpace is freed using 'ppdev->buf' so the 'data'
	     * pointer doesn't need to be the one that the thread started with
	     */
	    /* Close the file handles, but don't delete (unlink) the files */
	    thread_cdev->page_info.io_procs->fclose(thread_cdev->page_bfile, thread_cdev->page_bfname, false);
	    thread_cdev->page_info.io_procs->fclose(thread_cdev->page_cfile, thread_cdev->page_cfname, false);
	    thread_cdev->do_not_open_or_close_bandfiles = true;	/* we already closed the files */
	    gdev_prn_free_memory((gx_device *)thread_cdev);
	    /* Free the device copy this thread used */
	    gs_free_object(thread->memory, thread_cdev, "clist_teardown_render_threads");
#ifdef DEBUG
	    if (gs_debug[':'])
		dprintf2("%% Thread %d total usertime=%ld msec\n", i, thread->cputime);
	    dprintf1("\nthread: %d ending memory state...\n", i);
	    gs_memory_chunk_dump_memory(thread->memory); 
	    dprintf("                                    memory dump done.\n");
#endif

	    gs_memory_chunk_release(thread->memory); 
	}
	cdev->data = crdev->main_thread_data;	/* restore the pointer for writing */
	gs_free_object(mem, crdev->render_threads, "clist_teardown_render_threads");
	crdev->render_threads = NULL;

	/* Now re-open the clist temp files so we can write to them */
	if (cdev->page_cfile == NULL) {
	    char fmode[4];

	    strcpy(fmode, "a+");	/* file already exists and we want to re-use it */
	    strncat(fmode, gp_fmode_binary_suffix, 1);
	    cdev->page_info.io_procs->fopen(cdev->page_cfname, fmode, &cdev->page_cfile,
				mem, cdev->bandlist_memory, true);
	    cdev->page_info.io_procs->fseek(cdev->page_cfile, 0, SEEK_SET, cdev->page_cfname);
	    cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &cdev->page_bfile,
				mem, cdev->bandlist_memory, false);
	    cdev->page_info.io_procs->fseek(cdev->page_bfile, 0, SEEK_SET, cdev->page_bfname);
	}
    }
}