## VipsThreadpool

VipsThreadpool — pools of worker threads

## Stability Level

Stable, unless otherwise indicated

## Functions

void * | vips_thread_state_set ()
VipsThreadState * | vips_thread_state_new ()
VipsThreadState * | ( *VipsThreadStartFn ) ()
int | ( *VipsThreadpoolAllocateFn ) ()
int | ( *VipsThreadpoolWorkFn ) ()
int | ( *VipsThreadpoolProgressFn ) ()
int | vips_threadpool_run ()
void | vips_get_tile_size ()

## Object Hierarchy

        GObject
        ╰── VipsObject
            ╰── VipsThreadState

## Includes

    #include <vips/vips.h>

## Description

A threadpool which allows reusing already started threads. Implementing this can be tedious and error-prone. Therefore we use the GLib provided threadpool for our convenience. An added advantage is, that the threads can be shared between the different subsystems, when they are using GLib.

The threadpool is created during `vips_init()` and is destroyed by `vips_shutdown()`.

vips_threadpool_run() loops a set of threads over an image. Threads take it in turns to allocate units of work (a unit might be a tile in an image), then run in parallel to process those units. An optional progress function can be used to give feedback.

## Functions

### vips_thread_state_set ()

    void *
    vips_thread_state_set (VipsObject *object,
                           void *a,
                           void *b);

### vips_thread_state_new ()

    VipsThreadState *
    vips_thread_state_new (VipsImage *im,
                           void *a);

### VipsThreadStartFn ()

    VipsThreadState *
    (*VipsThreadStartFn) (VipsImage *im,
                          void *a);

### VipsThreadpoolAllocateFn ()

    int
    (*VipsThreadpoolAllocateFn) (VipsThreadState *state,
                                 void *a,
                                 gboolean *stop);

This function is called to allocate a new work unit for the thread. It is always single-threaded, so it can modify per-pool state (such as a counter).

`a` , `b` , `c` are the values supplied to the call to `vips_threadpool_run()`.

It should set `stop` to `TRUE` to indicate that no work could be allocated because the job is done.

See also: `vips_threadpool_run()`.

#### Parameters

state | per-thread state |
a | client data |
b | client data |
c | client data |
stop | set this to signal end of computation |

#### Returns

0 on success, or -1 on error

### VipsThreadpoolWorkFn ()

    int
    (*VipsThreadpoolWorkFn) (VipsThreadState *state,
                             void *a);

This function is called to process a work unit. Many copies of this can run at once, so it should not write to the per-pool state. It can write to per-thread state.

`a` , `b` , `c` are the values supplied to the call to `vips_threadpool_run()`.

See also: `vips_threadpool_run()`.

#### Parameters

state | per-thread state |
a | client data |
b | client data |
c | client data |

#### Returns

0 on success, or -1 on error

### VipsThreadpoolProgressFn ()

    int
    (*VipsThreadpoolProgressFn) (void *a);

This function is called by the main thread once for every work unit processed. It can be used to give the user progress feedback.

See also: `vips_threadpool_run()`.

#### Parameters

a | client data |
b | client data |
c | client data |

#### Returns

0 on success, or -1 on error

### vips_threadpool_run ()

    int
    vips_threadpool_run (VipsImage *im,
                         VipsThreadStartFn start,
                         VipsThreadpoolAllocateFn allocate,
                         VipsThreadpoolWorkFn work,
                         VipsThreadpoolProgressFn progress,
                         void *a);

This function runs a set of threads over an image. It will use a newly created or reused thread within the VipsThreadPool. Each thread first calls `start` to create new per-thread state, then runs `allocate` to set up a new work unit (perhaps the next tile in an image, for example), then `work` to process that work unit. After each unit is processed, `progress` is called, so that the operation can give progress feedback. `progress` may be `NULL`.

The object returned by `start` must be an instance of a subclass of VipsThreadState. Use this to communicate between `allocate` and `work` .

`allocate` is always single-threaded (so it can write to the per-pool state), whereas `start` and `work` can be executed concurrently. `progress` is always called by the main thread (ie. the thread which called `vips_threadpool_run()`).

See also: `vips_concurrency_set()`.

#### Parameters

im | image to loop over |
start | allocate per-thread state |
allocate | allocate a work unit |
work | process a work unit |
progress | give progress feedback about a work unit, or `NULL` |
a | client data |

#### Returns

0 on success, or -1 on error.

### vips_get_tile_size ()

    void
    vips_get_tile_size (VipsImage *im,
                        int *tile_width,
                        int *tile_height,
                        int *n_lines);

Pick a tile size and a buffer height for this image and the current value of `vips_concurrency_get()`. The buffer height will always be a multiple of tile_height.

The buffer height is the height of each buffer we fill in sink disc. Since we have two buffers, the largest range of input locality is twice the output buffer size, plus whatever margin we add for things like convolution.

[method]

#### Parameters

im | image to guess for |
tile_width | return selected tile width. | [out]
tile_height | return selected tile height. | [out]
n_lines | return buffer height in scanlines. | [out]

## See Also

generate