Agar


Note: The Agar manual pages follow certain conventions, notably concerning function return values. Please read AG_Intro(3) first.


SYNOPSIS

#include <agar/core.h>

DESCRIPTION

On all platforms with threads support, Agar can be compiled with support for multithreading. Agar API calls, unless otherwise documented, then become free-threaded (safe to use from different threads without need for application-level synchronization).

CONVENTIONS

The Agar API documentation follows the convention that all functions are free-threaded, unless mentioned otherwise.

Under some circumstances, application-level synchronization is required. The AG_Object(3) simplifies this task by providing a per-object lock (which is implicitely acquired in some contexts, such as event handler execution). For instance, the following code accesses a VFS in an unsafe manner:
AG_Object *myObject;
myObject = AG_ObjectFind(myRoot, "/Foo");
if (myObject != NULL) { ... }			/* UNSAFE */

The following code should be used instead:
AG_Object *myObject;
AG_ObjectLock(myRoot);
myObject = AG_ObjectFind(myRoot, "/Foo");
if (myObject != NULL) { ... }
AG_ObjectUnlock(myRoot);

THREADS INTERFACE

When compiled with threads support, Agar provides a portable, minimal interface to the operating system's native threads interface.

MUTEXES

Mutexes (MUTual EXclusion devices) are commonly used to protect shared data structure against concurrent modifications.


void AG_MutexInit (AG_Mutex *mutex)

void AG_MutexInitRecursive (AG_Mutex *mutex)

int AG_MutexTryInit (AG_Mutex *mutex)

int AG_MutexTryInitRecursive (AG_Mutex *mutex)

void AG_MutexDestroy (AG_Mutex *mutex)

void AG_MutexLock (AG_Mutex *mutex)

int AG_MutexTryLock (AG_Mutex *mutex)

void AG_MutexUnlock (AG_Mutex *mutex)


The AG_MutexInit() function initializes a mutex structure. AG_MutexInitRecursive() initializes a recursive mutex (a mutex with a reference count), which allows nested AG_MutexLock() calls. If the mutex cannot be allocated, a fatal error is raised. The AG_MutexTryInit() and AG_MutexTryInitRecursive() variants return an error code on failure.

AG_MutexDestroy() frees all resources allocated for a mutex.

AG_MutexLock() and AG_MutexUnlock() respectively acquire and release a mutex.

AG_MutexTryLock() tries to acquire a mutex without blocking and immediately returns 0 on success and -1 on failure. Note that AG_MutexTryLock() does not set any error message with AG_SetError(3).

CONDITION VARIABLES


void AG_CondInit (AG_Cond *cv)

int AG_CondTryInit (AG_Cond *cv)

void AG_CondDestroy (AG_Cond *cv)

void AG_CondBroadcast (AG_Cond *cv)

void AG_CondSignal (AG_Cond *cv)

int AG_CondWait (AG_Cond *cv, AG_Mutex *m)

int AG_CondTimedWait (AG_Cond *cv, AG_Mutex *m, const struct timespec *t)


AG_CondInit() initializes a condition variable structure. If the condition variable cannot be allocated, a fatal error is raised. The AG_CondTryInit() variant returns an error code on failure.

AG_CondDestroy() releases resources allocated for a condition variable.

AG_CondBroadcast() unblock all threads which are currently blocked waiting on cv. AG_CondSignal() unblocks at least one thread currently blocked waiting on cv.

AG_CondWait() blocks the calling thread until cv is signaled. The AG_CondTimedWait() variant will not block for more than the specified amount of time.

All of these functions will raise a fatal condition if an error is encountered.

THREADS


void AG_ThreadCreate (AG_Thread *th, void *(*fn)(void *arg), void *arg)

int AG_ThreadTryCreate (AG_Thread *th, void *(*fn)(void *arg), void *arg)

void AG_ThreadCancel (AG_Thread th)

int AG_ThreadJoin (AG_Thread th, void **exitVal)

void AG_ThreadExit (void *exitVal)

int AG_ThreadKill (AG_Thread th, int signal)


AG_ThreadCreate() creates a new thread executing fn. The optional argument arg is passed to fn. On success, AG_ThreadCreate() initializes the th structure and returns 0. On failure, a fatal error is raised. The AG_ThreadTryCreate() variant returns an error if the thread could not be created.

AG_ThreadCancel() requests that the specified thread be cancelled. If the given thread is invalid, a fatal error is raised.

AG_ThreadJoin() suspends the execution of the current thread until th terminates. When it does, the value passed to AG_ThreadExit() is made available in exitVal and AG_ThreadJoin() returns 0.

AG_ThreadExit() terminates the current thread. exitVal is an optional user pointer.

AG_ThreadKill() sends a signal to the specified thread.


THREAD-SPECIFIC VARIABLES


int AG_ThreadKeyCreate (AG_ThreadKey *key)

void AG_ThreadKeyDelete (AG_ThreadKey key)

void * AG_ThreadKeyGet (AG_ThreadKey key)

void * AG_ThreadKeySet (AG_ThreadKey key, const void *value)


AG_ThreadKeyCreate() initializes a thread-specific value described by the key structure. AG_ThreadKeyDelete() releases resources allocated for a key.

AG_ThreadKeyGet() returns the thread-specific value associated with key.

AG_ThreadKeySet() sets a thread-specific value with key.

SEE ALSO

AG_Intro(3), AG_Object(3)

HISTORY

The AG_Threads interface first appeared in Agar 1.0