## Deprecated thread API Deprecated thread API — old thread APIs (for reference only) |

## Synopsis

    #include <glib.h>

    #define             G_THREADS_IMPL_POSIX
    #define             G_THREADS_IMPL_WIN32

    void                g_thread_init                       (gpointer vtable);
    gboolean            g_thread_supported                  ();
    gboolean            g_thread_get_initialized            (void);

    GThread *           g_thread_create                     (GThreadFunc func,
                                                             gpointer data,
                                                             gboolean joinable,
                                                             GError **error);
    GThread *           g_thread_create_full                (GThreadFunc func,
                                                             gpointer data,
                                                             gulong stack_size,
                                                             gboolean joinable,
                                                             gboolean bound,
                                                             GThreadPriority priority,
                                                             GError **error);
    enum                GThreadPriority;
    void                g_thread_set_priority               (GThread *thread,
                                                             GThreadPriority priority);
    void                g_thread_foreach                    (GFunc thread_func,
                                                             gpointer user_data);

    GMutex *            g_mutex_new                         ();
    void                g_mutex_free                        (GMutex *mutex);
    GCond*              g_cond_new                          ();
    void                g_cond_free                         (GCond *cond);
    GPrivate *          g_private_new                       (GDestroyNotify notify);

                        GStaticMutex;
    #define             G_STATIC_MUTEX_INIT
    void                g_static_mutex_init                 (GStaticMutex *mutex);
    void                g_static_mutex_lock                 (GStaticMutex *mutex);
    gboolean            g_static_mutex_trylock              (GStaticMutex *mutex);
    void                g_static_mutex_unlock               (GStaticMutex *mutex);
    GMutex *            g_static_mutex_get_mutex            (GStaticMutex *mutex);
    void                g_static_mutex_free                 (GStaticMutex *mutex);

    struct              GStaticRecMutex;
    #define             G_STATIC_REC_MUTEX_INIT
    void                g_static_rec_mutex_init             (GStaticRecMutex *mutex);
    void                g_static_rec_mutex_lock             (GStaticRecMutex *mutex);
    gboolean            g_static_rec_mutex_trylock          (GStaticRecMutex *mutex);
    void                g_static_rec_mutex_unlock           (GStaticRecMutex *mutex);
    void                g_static_rec_mutex_lock_full        (GStaticRecMutex *mutex,
                                                             guint depth);
    guint               g_static_rec_mutex_unlock_full      (GStaticRecMutex *mutex);
    void                g_static_rec_mutex_free             (GStaticRecMutex *mutex);

    struct              GStaticRWLock;
    #define             G_STATIC_RW_LOCK_INIT
    void                g_static_rw_lock_init               (GStaticRWLock *lock);
    void                g_static_rw_lock_reader_lock        (GStaticRWLock *lock);
    gboolean            g_static_rw_lock_reader_trylock     (GStaticRWLock *lock);
    void                g_static_rw_lock_reader_unlock      (GStaticRWLock *lock);
    void                g_static_rw_lock_writer_lock        (GStaticRWLock *lock);
    gboolean            g_static_rw_lock_writer_trylock     (GStaticRWLock *lock);
    void                g_static_rw_lock_writer_unlock      (GStaticRWLock *lock);
    void                g_static_rw_lock_free               (GStaticRWLock *lock);

    struct              GStaticPrivate;
    #define             G_STATIC_PRIVATE_INIT
    void                g_static_private_init               (GStaticPrivate *private_key);
    gpointer            g_static_private_get                (GStaticPrivate *private_key);
    void                g_static_private_set                (GStaticPrivate *private_key,
                                                             gpointer data,
                                                             GDestroyNotify notify);
    void                g_static_private_free               (GStaticPrivate *private_key);

## Description

These APIs are deprecated. You should not use them in new code. This section remains only to assist with understanding code that was written to use these APIs at some point in the past.

## Details

### G_THREADS_IMPL_POSIX

    #define G_THREADS_IMPL_POSIX

### Warning

`G_THREADS_IMPL_POSIX` has been deprecated since version 2.32 and should not be used in newly-written code. POSIX threads are in use on all non-Windows systems. Use G_OS_WIN32 to detect Windows.

This macro is defined if POSIX style threads are used.

### G_THREADS_IMPL_WIN32

    #define G_THREADS_IMPL_NONE

### Warning

`G_THREADS_IMPL_WIN32` has been deprecated since version 2.32 and should not be used in newly-written code. Use G_OS_WIN32 to detect Windows.

This macro is defined if Windows style threads are used.

### g_thread_init ()

    void                g_thread_init                       (gpointer vtable);

### Warning

`g_thread_init` has been deprecated since version 2.32 and should not be used in newly-written code. This function is no longer necessary. The GLib threading system is automatically initialized at the start of your program.

If you use GLib from more than one thread, you must initialize the thread system by calling `g_thread_init()`.

Since version 2.24, calling `g_thread_init()` multiple times is allowed, but nothing happens except for the first call.

Since version 2.32, GLib does not support custom thread implementations anymore and the `vtable` parameter is ignored and you should pass `NULL`.

### Note

`g_thread_init()` must not be called directly or indirectly in a callback from GLib. Also no mutexes may be currently locked while calling `g_thread_init()`.

### Note

To use `g_thread_init()` in your program, you have to link with the libraries that the command pkg-config --libs gthread-2.0 outputs. This is not the case for all the other thread-related functions of GLib. Those can be used without having to link with the thread libraries.

`vtable` : | a function table of type GThreadFunctions, that provides the entry points to the thread system to be used. Since 2.32, this parameter is ignored and should always be `NULL`

### g_thread_supported ()

    gboolean            g_thread_supported                  ();

This macro returns `TRUE` if the thread system is initialized, and `FALSE` if it is not.

For language bindings, `g_thread_get_initialized()` provides the same functionality as a function.

Returns : | `TRUE`, if the thread system is initialized

### g_thread_get_initialized ()

    gboolean            g_thread_get_initialized            (void);

Indicates if `g_thread_init()` has been called.

Returns : | `TRUE` if threads have been initialized.

Since 2.20

### g_thread_create ()

    GThread *           g_thread_create                     (GThreadFunc func,
                                                             gpointer data,
                                                             gboolean joinable,
                                                             GError **error);

### Warning

`g_thread_create` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_thread_new()` instead

This function creates a new thread.

The new thread executes the function `func` with the argument `data`. If the thread was created successfully, it is returned.

`error` can be `NULL` to ignore errors, or non-`NULL` to report errors. The error is set, if and only if the function returns `NULL`.

This function returns a reference to the created thread only if `joinable` is `TRUE`. In that case, you must free this reference by calling `g_thread_unref()` or `g_thread_join()`. If `joinable` is `FALSE` then you should probably not touch the return value.

`func` : | a function to execute in the new thread
`data` : | an argument to supply to the new thread
`joinable` : | should this thread be joinable?
`error` : | return location for error, or `NULL`
Returns : | the new GThread on success

### g_thread_create_full ()

    GThread *           g_thread_create_full                (GThreadFunc func,
                                                             gpointer data,
                                                             gulong stack_size,
                                                             gboolean joinable,
                                                             gboolean bound,
                                                             GThreadPriority priority,
                                                             GError **error);

### Warning

`g_thread_create_full` has been deprecated since version 2.32 and should not be used in newly-written code. The `bound` and `priority` arguments are now ignored. Use `g_thread_new()`.

This function creates a new thread.

`func` : | a function to execute in the new thread.
`data` : | an argument to supply to the new thread.
`stack_size` : | a stack size for the new thread.
`joinable` : | should this thread be joinable?
`bound` : | ignored
`priority` : | ignored
`error` : | return location for error.
Returns : | the new GThread on success.

### enum GThreadPriority

    typedef enum {
      G_THREAD_PRIORITY_LOW,
      G_THREAD_PRIORITY_NORMAL,
      G_THREAD_PRIORITY_HIGH,
      G_THREAD_PRIORITY_URGENT
    } GThreadPriority;

### Warning

`GThreadPriority` has been deprecated since version 2.32 and should not be used in newly-written code. Thread priorities no longer have any effect.

`G_THREAD_PRIORITY_LOW` | a priority lower than normal
`G_THREAD_PRIORITY_NORMAL` | the default priority
`G_THREAD_PRIORITY_HIGH` | a priority higher than normal
`G_THREAD_PRIORITY_URGENT` | the highest priority

### g_thread_set_priority ()

    void                g_thread_set_priority               (GThread *thread,
                                                             GThreadPriority priority);

### Warning

`g_thread_set_priority` has been deprecated since version 2.32 and should not be used in newly-written code. Thread priorities no longer have any effect.

This function does nothing.

`thread` : | a GThread.
`priority` : | ignored

### g_thread_foreach ()

    void                g_thread_foreach                    (GFunc thread_func,
                                                             gpointer user_data);

### Warning

`g_thread_foreach` has been deprecated since version 2.32 and should not be used in newly-written code. There aren't many things you can do with a GThread, except comparing it with one that was returned from `g_thread_create()`. There are better ways to find out if your thread is still alive.

Call `thread_func` on all GThreads that have been created with `g_thread_create()`.

Note that threads may decide to exit while `thread_func` is running, so without intimate knowledge about the lifetime of foreign threads, `thread_func` shouldn't access the GThread* pointer passed in as first argument. However, `thread_func` will not be called for threads which are known to have exited already.

Due to thread lifetime checks, this function has an execution complexity which is quadratic in the number of existing threads.

`thread_func` : | function to call for all GThread structures
`user_data` : | second argument to `thread_func`

Since 2.10

### g_mutex_new ()

    GMutex *            g_mutex_new                         ();

### Warning

`g_mutex_new` has been deprecated since version 2.32 and should not be used in newly-written code. GMutex can now be statically allocated, or embedded in structures and initialised with `g_mutex_init()`.

Allocates and initializes a new GMutex.

Returns : | a newly allocated GMutex. Use `g_mutex_free()` to free

### g_mutex_free ()

    void                g_mutex_free                        (GMutex *mutex);

### Warning

`g_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code. GMutex can now be statically allocated, or embedded in structures and initialised with `g_mutex_init()`.

Destroys a `mutex` that has been created with `g_mutex_new()`.

Calling `g_mutex_free()` on a locked mutex may result in undefined behaviour.

`mutex` : | a GMutex

### g_cond_new ()

    GCond*              g_cond_new                          ();

### Warning

`g_cond_new` has been deprecated since version 2.32 and should not be used in newly-written code. GCond can now be statically allocated, or embedded in structures and initialised with `g_cond_init()`.

Allocates and initializes a new GCond.

Returns : | a newly allocated GCond. Free with `g_cond_free()`

### g_cond_free ()

    void                g_cond_free                         (GCond *cond);

### Warning

`g_cond_free` has been deprecated since version 2.32 and should not be used in newly-written code. GCond can now be statically allocated, or embedded in structures and initialised with `g_cond_init()`.

Destroys a GCond that has been created with `g_cond_new()`.

Calling `g_cond_free()` for a GCond on which threads are blocking leads to undefined behaviour.

`cond` : | a GCond

### g_private_new ()

    GPrivate *          g_private_new                       (GDestroyNotify notify);

### Warning

`g_private_new` has been deprecated since version 2.32 and should not be used in newly-written code. dynamic allocation of GPrivate is a bad idea. Use static storage and `G_PRIVATE_INIT()` instead.

Creates a new GPrivate.

`notify` : | a GDestroyNotify
Returns : | a newly allocated GPrivate (which can never be destroyed)

### GStaticMutex

    typedef struct _GStaticMutex GStaticMutex;

A GStaticMutex works like a GMutex.

Prior to GLib 2.32, GStaticMutex had the significant advantage that it doesn't need to be created at run-time, but can be defined at compile-time. Since 2.32, GMutex can be statically allocated as well, and GStaticMutex has been deprecated.

Here is a version of our `give_me_next_number()` example using a GStaticMutex.

Example 20. Using GStaticMutex to simplify thread-safe programming

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int
    give_me_next_number (void)
    {
      static int current_number = 0;
      int ret_val;
      static GStaticMutex mutex = G_STATIC_MUTEX_INIT;

      g_static_mutex_lock (&mutex);
      ret_val = current_number = calc_next_number (current_number);
      g_static_mutex_unlock (&mutex);

      return ret_val;
    }

Sometimes you would like to dynamically create a mutex. If you don't want to require prior calling to `g_thread_init()`, because your code should also be usable in non-threaded programs, you are not able to use `g_mutex_new()` and thus GMutex, as that requires a prior call to `g_thread_init()`. In theses cases you can also use a GStaticMutex. It must be initialized with `g_static_mutex_init()` before using it and freed with with `g_static_mutex_free()` when not needed anymore to free up any allocated resources.

Even though GStaticMutex is not opaque, it should only be used with the following functions, as it is defined differently on different platforms.

All of the `g_static_mutex_*` functions apart from `g_static_mutex_get_mutex` can also be used even if `g_thread_init()` has not yet been called. Then they do nothing, apart from `g_static_mutex_trylock`, which does nothing but returning `TRUE`.

### Note

All of the `g_static_mutex_*` functions are actually macros. Apart from taking their addresses, you can however use them as if they were functions.

### G_STATIC_MUTEX_INIT

    #define G_STATIC_MUTEX_INIT

A GStaticMutex must be initialized with this macro, before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_mutex_init()`.

    1
    GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;

### g_static_mutex_init ()

    void                g_static_mutex_init                 (GStaticMutex *mutex);

### Warning

`g_static_mutex_init` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_mutex_init()`

Initializes `mutex`. Alternatively you can initialize it with G_STATIC_MUTEX_INIT.

`mutex` : | a GStaticMutex to be initialized.

### g_static_mutex_lock ()

    void                g_static_mutex_lock                 (GStaticMutex *mutex);

### Warning

`g_static_mutex_lock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_mutex_lock()`

Works like `g_mutex_lock()`, but for a GStaticMutex.

`mutex` : | a GStaticMutex.

### g_static_mutex_trylock ()

    gboolean            g_static_mutex_trylock              (GStaticMutex *mutex);

### Warning

`g_static_mutex_trylock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_mutex_trylock()`

Works like `g_mutex_trylock()`, but for a GStaticMutex.

`mutex` : | a GStaticMutex.
Returns : | `TRUE`, if the GStaticMutex could be locked.

### g_static_mutex_unlock ()

    void                g_static_mutex_unlock               (GStaticMutex *mutex);

### Warning

`g_static_mutex_unlock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_mutex_unlock()`

Works like `g_mutex_unlock()`, but for a GStaticMutex.

`mutex` : | a GStaticMutex.

### g_static_mutex_get_mutex ()

    GMutex *            g_static_mutex_get_mutex            (GStaticMutex *mutex);

### Warning

`g_static_mutex_get_mutex` has been deprecated since version 2.32 and should not be used in newly-written code. Just use a GMutex

For some operations (like `g_cond_wait()`) you must have a GMutex instead of a GStaticMutex. This function will return the corresponding GMutex for `mutex`.

`mutex` : | a GStaticMutex.
Returns : | the GMutex corresponding to `mutex`.

### g_static_mutex_free ()

    void                g_static_mutex_free                 (GStaticMutex *mutex);

### Warning

`g_static_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_mutex_clear()`

Releases all resources allocated to `mutex`.

You don't have to call this functions for a GStaticMutex with an unbounded lifetime, i.e. objects declared 'static', but if you have a GStaticMutex as a member of a structure and the structure is freed, you should also free the GStaticMutex.

### Note

Calling `g_static_mutex_free()` on a locked mutex may result in undefined behaviour.

`mutex` : | a GStaticMutex to be freed.

### struct GStaticRecMutex

    struct GStaticRecMutex {
    };

A GStaticRecMutex works like a GStaticMutex, but it can be locked multiple times by one thread. If you enter it n times, you have to unlock it n times again to let other threads lock it. An exception is the function `g_static_rec_mutex_unlock_full()`: that allows you to unlock a GStaticRecMutex completely returning the depth, (i.e. the number of times this mutex was locked). The depth can later be used to restore the state of the GStaticRecMutex by calling `g_static_rec_mutex_lock_full()`. In GLib 2.32, GStaticRecMutex has been deprecated in favor of GRecMutex.

Even though GStaticRecMutex is not opaque, it should only be used with the following functions.

All of the `g_static_rec_mutex_*` functions can be used even if `g_thread_init()` has not been called. Then they do nothing, apart from `g_static_rec_mutex_trylock`, which does nothing but returning `TRUE`.

### G_STATIC_REC_MUTEX_INIT

    #define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }

A GStaticRecMutex must be initialized with this macro before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_rec_mutex_init()`.

    1
    GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;

### g_static_rec_mutex_init ()

    void                g_static_rec_mutex_init             (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_init` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_init()`

A GStaticRecMutex must be initialized with this function before it can be used. Alternatively you can initialize it with G_STATIC_REC_MUTEX_INIT.

`mutex` : | a GStaticRecMutex to be initialized.

### g_static_rec_mutex_lock ()

    void                g_static_rec_mutex_lock             (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_lock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_lock()`

Locks `mutex`. If `mutex` is already locked by another thread, the current thread will block until `mutex` is unlocked by the other thread. If `mutex` is already locked by the calling thread, this functions increases the depth of `mutex` and returns immediately.

`mutex` : | a GStaticRecMutex to lock.

### g_static_rec_mutex_trylock ()

    gboolean            g_static_rec_mutex_trylock          (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_trylock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_trylock()`

Tries to lock `mutex`. If `mutex` is already locked by another thread, it immediately returns `FALSE`. Otherwise it locks `mutex` and returns `TRUE`. If `mutex` is already locked by the calling thread, this functions increases the depth of `mutex` and immediately returns `TRUE`.

`mutex` : | a GStaticRecMutex to lock.
Returns : | `TRUE`, if `mutex` could be locked.

### g_static_rec_mutex_unlock ()

    void                g_static_rec_mutex_unlock           (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_unlock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_unlock()`

Unlocks `mutex`. Another thread will be allowed to lock `mutex` only when it has been unlocked as many times as it had been locked before. If `mutex` is completely unlocked and another thread is blocked in a `g_static_rec_mutex_lock()` call for `mutex`, it will be woken and can lock `mutex` itself.

`mutex` : | a GStaticRecMutex to unlock.

### g_static_rec_mutex_lock_full ()

    void                g_static_rec_mutex_lock_full        (GStaticRecMutex *mutex,
                                                             guint depth);

### Warning

`g_static_rec_mutex_lock_full` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_lock()`

Works like calling `g_static_rec_mutex_lock()` for `mutex` `depth` times.

`mutex` : | a GStaticRecMutex to lock.
`depth` : | number of times this mutex has to be unlocked to be completely unlocked.

### g_static_rec_mutex_unlock_full ()

    guint               g_static_rec_mutex_unlock_full      (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_unlock_full` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_unlock()`

Completely unlocks `mutex`. If another thread is blocked in a `g_static_rec_mutex_lock()` call for `mutex`, it will be woken and can lock `mutex` itself. This function returns the number of times that `mutex` has been locked by the current thread. To restore the state before the call to `g_static_rec_mutex_unlock_full()` you can call `g_static_rec_mutex_lock_full()` with the depth returned by this function.

`mutex` : | a GStaticRecMutex to completely unlock.
Returns : | number of times `mutex` has been locked by the current thread.

### g_static_rec_mutex_free ()

    void                g_static_rec_mutex_free             (GStaticRecMutex *mutex);

### Warning

`g_static_rec_mutex_free` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rec_mutex_clear()`

Releases all resources allocated to a GStaticRecMutex.

You don't have to call this functions for a GStaticRecMutex with an unbounded lifetime, i.e. objects declared 'static', but if you have a GStaticRecMutex as a member of a structure and the structure is freed, you should also free the GStaticRecMutex.

`mutex` : | a GStaticRecMutex to be freed.

### struct GStaticRWLock

    struct GStaticRWLock {
    };

### Warning

`GStaticRWLock` has been deprecated since version 2.32 and should not be used in newly-written code. Use a GRWLock instead

The GStaticRWLock struct represents a read-write lock. A read-write lock can be used for protecting data that some portions of code only read from, while others also write. In such situations it is desirable that several readers can read at once, whereas of course only one writer may write at a time. Take a look at the following example:

Example 21. An array with access functions

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
    GPtrArray *array;

    gpointer
    my_array_get (guint index)
    {
      gpointer retval = NULL;

      if (!array)
        return NULL;

      g_static_rw_lock_reader_lock (&rwlock);
      if (index < array->len)
        retval = g_ptr_array_index (array, index);
      g_static_rw_lock_reader_unlock (&rwlock);

      return retval;
    }

    void
    my_array_set (guint index, gpointer data)
    {
      g_static_rw_lock_writer_lock (&rwlock);

      if (!array)
        array = g_ptr_array_new ();

      if (index >= array->len)
        g_ptr_array_set_size (array, index+1);
      g_ptr_array_index (array, index) = data;

      g_static_rw_lock_writer_unlock (&rwlock);
    }

This example shows an array which can be accessed by many readers (the ``my_array_get()`` function) simultaneously, whereas the writers (the ``my_array_set()`` function) will only be allowed once at a time and only if no readers currently access the array. This is because of the potentially dangerous resizing of the array. Using these functions is fully multi-thread safe now.

Most of the time, writers should have precedence over readers. That means, for this implementation, that as soon as a writer wants to lock the data, no other reader is allowed to lock the data, whereas, of course, the readers that already have locked the data are allowed to finish their operation. As soon as the last reader unlocks the data, the writer will lock it.

Even though GStaticRWLock is not opaque, it should only be used with the following functions.

All of the `g_static_rw_lock_*` functions can be used even if `g_thread_init()` has not been called. Then they do nothing, apart from `g_static_rw_lock_*_trylock`, which does nothing but returning `TRUE`.

### Note

A read-write lock has a higher overhead than a mutex. For example, both `g_static_rw_lock_reader_lock()` and `g_static_rw_lock_reader_unlock()` have to lock and unlock a GStaticMutex, so it takes at least twice the time to lock and unlock a GStaticRWLock that it does to lock and unlock a GStaticMutex. So only data structures that are accessed by multiple readers, and which keep the lock for a considerable time justify a GStaticRWLock. The above example most probably would fare better with a GStaticMutex.

### G_STATIC_RW_LOCK_INIT

    #define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }

A GStaticRWLock must be initialized with this macro before it can be used. This macro can used be to initialize a variable, but it cannot be assigned to a variable. In that case you have to use `g_static_rw_lock_init()`.

    1
    GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;

### g_static_rw_lock_init ()

    void                g_static_rw_lock_init               (GStaticRWLock *lock);

### Warning

`g_static_rw_lock_init` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rw_lock_init()` instead

A GStaticRWLock must be initialized with this function before it can be used. Alternatively you can initialize it with G_STATIC_RW_LOCK_INIT.

`lock` : | a GStaticRWLock to be initialized.

### g_static_rw_lock_reader_lock ()

    void                g_static_rw_lock_reader_lock        (GStaticRWLock *lock);

### Warning

`g_static_rw_lock_reader_lock` has been deprecated since version 2.32 and should not be used in newly-written code. Use `g_rw_lock_reader_lock()` instead

Locks `lock` for reading. There may be unlimited concurrent locks for reading of a GStaticRWLock at the same time. If `lock` is already locked for writing by another thread or if another thread is already waiting to lock `lock` for writing, this function will block until `lock` is unlocked by the other writing thread and no other writing threads want to lock `lock`. This lock has to be unlocked by `g_static_rw_lock_reader_unlock()`.

GStaticRWLock is not recursive. It might seem to be possible to recursively lock for reading, but that can result in a deadlock, due to writer preference.

`lock` : | a GStaticRWLock to lock for reading.

### g_static_rw_lock_reader_trylock ()

    gboolean            g_static_rw_lock_reader_trylock     (GStaticRWLock *lock);

Tries to lock `lock` for reading. If `lock` is already locked for writing by another thread or if another thread is already waiting to lock `lock` for writing, immediately returns `FALSE`. Otherwise locks `lock` for reading and returns `TRUE`. This lock has to be unlocked by `g_static_rw_lock_reader_unlock()`.

`lock` : | a GStaticRWLock to lock for reading.
Returns : | `TRUE`, if `lock` could be locked for reading. Deprectated: 2.32: Use `g_rw_lock_reader_trylock()` instead

### g_static_rw_lock_reader_unlock ()

    void                g_static_rw_lock_reader_unlock      (GStaticRWLock *lock);

Unlocks `lock`. If a thread waits to lock `lock` for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock `lock` for writing.

Deprectated: 2.32: Use `g_rw_lock_reader_unlock()` instead

`lock` : | a GStaticRWLock to unlock after reading.

### g_static_rw_lock_writer_lock ()

    void                g_static_rw_lock_writer_lock        (GStaticRWLock *lock);

Locks `lock` for writing. If `lock` is already locked for writing or reading by other threads, this function will block until `lock` is completely unlocked and then lock `lock` for writing. While this functions waits to lock `lock`, no other thread can lock `lock` for reading. When `lock` is locked for writing, no other thread can lock `lock` (neither for reading nor writing). This lock has to be unlocked by `g_static_rw_lock_writer_unlock()`.

Deprectated: 2.32: Use `g_rw_lock_writer_lock()` instead

`lock` : | a GStaticRWLock to lock for writing.

### g_static_rw_lock_writer_trylock ()

    gboolean            g_static_rw_lock_writer_trylock     (GStaticRWLock *lock);

Tries to lock `lock` for writing. If `lock` is already locked (for either reading or writing) by another thread, it immediately returns `FALSE`. Otherwise it locks `lock` for writing and returns `TRUE`. This lock has to be unlocked by `g_static_rw_lock_writer_unlock()`.

`lock` : | a GStaticRWLock to lock for writing.
Returns : | `TRUE`, if `lock` could be locked for writing. Deprectated: 2.32: Use `g_rw_lock_writer_trylock()` instead

### g_static_rw_lock_writer_unlock ()

    void                g_static_rw_lock_writer_unlock      (GStaticRWLock *lock);

Unlocks `lock`. If a thread is waiting to lock `lock` for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock `lock` for writing. If no thread is waiting to lock `lock` for writing, and some thread or threads are waiting to lock `lock` for reading, the waiting threads are woken up and can lock `lock` for reading.

Deprectated: 2.32: Use `g_rw_lock_writer_unlock()` instead

`lock` : | a GStaticRWLock to unlock after writing.

### g_static_rw_lock_free ()

    void                g_static_rw_lock_free               (GStaticRWLock *lock);

### Warning

`g_static_rw_lock_free` has been deprecated since version 2.32 and should not be used in newly-written code. Use a GRWLock instead

Releases all resources allocated to `lock`.

You don't have to call this functions for a GStaticRWLock with an unbounded lifetime, i.e. objects declared 'static', but if you have a GStaticRWLock as a member of a structure, and the structure is freed, you should also free the GStaticRWLock.

`lock` : | a GStaticRWLock to be freed.

### struct GStaticPrivate

    struct GStaticPrivate {
    };

A GStaticPrivate works almost like a GPrivate, but it has one significant advantage. It doesn't need to be created at run-time like a GPrivate, but can be defined at compile-time. This is similar to the difference between GMutex and GStaticMutex. Now look at our ``give_me_next_number()`` example with GStaticPrivate:

Example 22. Using GStaticPrivate for per-thread data

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int
    give_me_next_number ()
    {
      static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT;
      int *current_number = g_static_private_get (&current_number_key);

      if (!current_number)
        {
          current_number = g_new (int,1);
          *current_number = 0;
          g_static_private_set (&current_number_key, current_number, g_free);
        }

      *current_number = calc_next_number (*current_number);

      return *current_number;
    }

### G_STATIC_PRIVATE_INIT

    #define G_STATIC_PRIVATE_INIT

Every GStaticPrivate must be initialized with this macro, before it can be used.

    1
    GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;

### g_static_private_init ()

    void                g_static_private_init               (GStaticPrivate *private_key);

Initializes `private_key`. Alternatively you can initialize it with G_STATIC_PRIVATE_INIT.

`private_key` : | a GStaticPrivate to be initialized

### g_static_private_get ()

    gpointer            g_static_private_get                (GStaticPrivate *private_key);

Works like `g_private_get()` only for a GStaticPrivate.

This function works even if `g_thread_init()` has not yet been called.

`private_key` : | a GStaticPrivate
Returns : | the corresponding pointer

### g_static_private_set ()

    void                g_static_private_set                (GStaticPrivate *private_key,
                                                             gpointer data,
                                                             GDestroyNotify notify);

Sets the pointer keyed to `private_key` for the current thread and the function `notify` to be called with that pointer (`NULL` or non-`NULL`), whenever the pointer is set again or whenever the current thread ends.

This function works even if `g_thread_init()` has not yet been called. If `g_thread_init()` is called later, the `data` keyed to `private_key` will be inherited only by the main thread, i.e. the one that called `g_thread_init()`.

### Note

`notify` is used quite differently from `destructor` in `g_private_new()`.

`private_key` : | a GStaticPrivate
`data` : | the new pointer
`notify` : | a function to be called with the pointer whenever the current thread ends or sets this pointer again

### g_static_private_free ()

    void                g_static_private_free               (GStaticPrivate *private_key);

Releases all resources allocated to `private_key`.

You don't have to call this functions for a GStaticPrivate with an unbounded lifetime, i.e. objects declared 'static', but if you have a GStaticPrivate as a member of a structure and the structure is freed, you should also free the GStaticPrivate.

`private_key` : | a GStaticPrivate to be freed

## See Also

GThread