Threads and mutexes

## Detailed Description

Oracle proposes a portable implementation of Mutex and Thread objects

OCILIB implements these OCI features for portable multi-threading support.

Mutexes are designed for mutual exclusion between thread in order to lock resources temporarily

Thread keys can be seen as process-wide variables that have a thread-specific values. It allows to create a unique key identified by a name (string) that can store values specific to each thread.

OCILIB exposes the types OCI_Mutex, OCI_Thread

Warning
  OCILIB MUST be initialized with OCI_ENV_THREADED to enable threads support
  OCI_Thread relies on Oracle API which uses natives threading capabilities of the supported platform
  Using OCI_Mutex :
  - On Microsoft Windows, a thread can call OCI_MutexAcquire() more than once without any blocking. Just be sure that there is an OCI_MutexRelease() for every OCI_MutexAcquire() call
  - On Unix systems, a thread MUST call OCI_MutexRelease() after every call to OCI_MutexAcquire() in order to be able to call OCI_MutexAcquire() again. If not, it will be blocked...

Example
  #include "ocilib.h"
  #define MAX_THREADS 50
  void err_handler(OCI_Error *err)
  {
  printf("%s\n", OCI_ErrorGetString(err));
  }
  void key_cleanup(void *str)
  {
  free(str);
  }
  void worker(OCI_Thread *thread, void *data)
  {
  const void *id = OCI_HandleGetThreadID(thread);
  char *str = malloc(50);
  sprintf(str, "thread %p !\n", id);
  OCI_ThreadKeySetValue("ID", str);
  str = OCI_ThreadKeyGetValue("ID");
  printf(str);
  }
  int main(void)
  {
  OCI_Thread *th[MAX_THREADS];
  int i;
  if (!OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT | OCI_ENV_THREADED))
  {
  return EXIT_FAILURE;
  }
  OCI_ThreadKeyCreate("ID", key_cleanup);
  /* create threads */
  for (i = 0; i < MAX_THREADS; i++)
  {
  th[i] = OCI_ThreadCreate();
  OCI_ThreadRun(th[i], worker, NULL);
  }
  /* wait for threads and cleanup */
  for (i = 0; i < MAX_THREADS; i++)
  {
  OCI_ThreadJoin(th[i]);
  OCI_ThreadFree(th[i]);
  }
  OCI_Cleanup();
  return EXIT_SUCCESS;
  }

## Functions

OCI_EXPORT OCI_Mutex *OCI_API | OCI_MutexCreate (void)
| Create a Mutex object. More...
OCI_EXPORT boolean OCI_API | OCI_MutexFree (OCI_Mutex *mutex)
| Destroy a mutex object. More...
OCI_EXPORT boolean OCI_API | OCI_MutexAcquire (OCI_Mutex *mutex)
| Acquire a mutex lock. More...
OCI_EXPORT boolean OCI_API | OCI_MutexRelease (OCI_Mutex *mutex)
| Release a mutex lock. More...
OCI_EXPORT OCI_Thread *OCI_API | OCI_ThreadCreate (void)
| Create a Thread object. More...
OCI_EXPORT boolean OCI_API | OCI_ThreadFree (OCI_Thread *thread)
| Destroy a thread object. More...
OCI_EXPORT boolean OCI_API | OCI_ThreadRun (OCI_Thread *thread, POCI_THREAD proc, void *arg)
| Execute the given routine within the given thread object. More...
OCI_EXPORT boolean OCI_API | OCI_ThreadJoin (OCI_Thread *thread)
| Join the given thread. More...
OCI_EXPORT boolean OCI_API | OCI_ThreadKeyCreate (const otext *name, POCI_THREADKEYDEST destfunc)
| Create a thread key object. More...
OCI_EXPORT boolean OCI_API | OCI_ThreadKeySetValue (const otext *name, void *value)
| Set a thread key value. More...
OCI_EXPORT void *OCI_API | OCI_ThreadKeyGetValue (const otext *name)
| Get a thread key value. More...

## Function Documentation

## OCI_MutexCreate()

OCI_EXPORT OCI_Mutex* OCI_API OCI_MutexCreate | ( | void |  | ) |

`#include <ocilib.h>`

Create a Mutex object.

Returns
  Mutex handle on success or NULL on failure

Referenced by ocilib::Mutex::Create().

## OCI_MutexFree()

OCI_EXPORT boolean OCI_API OCI_MutexFree | ( | OCI_Mutex * | mutex | ) |

`#include <ocilib.h>`

Destroy a mutex object.

Parameters

  mutex | - Mutex handle

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Mutex::Destroy().

## OCI_MutexAcquire()

OCI_EXPORT boolean OCI_API OCI_MutexAcquire | ( | OCI_Mutex * | mutex | ) |

`#include <ocilib.h>`

Acquire a mutex lock.

Parameters

  mutex | - Mutex handle

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Mutex::Acquire().

## OCI_MutexRelease()

OCI_EXPORT boolean OCI_API OCI_MutexRelease | ( | OCI_Mutex * | mutex | ) |

`#include <ocilib.h>`

Release a mutex lock.

Parameters

  mutex | - Mutex handle

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Mutex::Release().

## OCI_ThreadCreate()

OCI_EXPORT OCI_Thread* OCI_API OCI_ThreadCreate | ( | void |  | ) |

`#include <ocilib.h>`

Create a Thread object.

Returns
  Thread handle on success or NULL on failure

Referenced by ocilib::Thread::Create().

## OCI_ThreadFree()

OCI_EXPORT boolean OCI_API OCI_ThreadFree | ( | OCI_Thread * | thread | ) |

`#include <ocilib.h>`

Destroy a thread object.

Parameters

  thread | - Thread handle

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Thread::Destroy().

## OCI_ThreadRun()

OCI_EXPORT boolean OCI_API OCI_ThreadRun | ( | OCI_Thread * | thread,
|  | POCI_THREAD | proc,
|  | void * | arg
| ) |  |

`#include <ocilib.h>`

Execute the given routine within the given thread object.

Parameters

  thread | - Thread handle
  proc | - routine to execute
  arg | - parameter to pass to the routine

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Thread::Run().

## OCI_ThreadJoin()

OCI_EXPORT boolean OCI_API OCI_ThreadJoin | ( | OCI_Thread * | thread | ) |

`#include <ocilib.h>`

Join the given thread.

Parameters

  thread | - Thread handle

Note
  This function waits for the given thread to finish

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::Thread::Join().

## OCI_ThreadKeyCreate()

OCI_EXPORT boolean OCI_API OCI_ThreadKeyCreate | ( | const otext * | name,
|  | POCI_THREADKEYDEST | destfunc
| ) |  |

`#include <ocilib.h>`

Create a thread key object.

Parameters

  name | - Thread key name
  destfunc | - Thread key value destructor function

Note
  Parameter proc is optional. It's called when the thread terminates to allow the program to deal with the thread specific value of the key

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::ThreadKey::Create().

## OCI_ThreadKeySetValue()

OCI_EXPORT boolean OCI_API OCI_ThreadKeySetValue | ( | const otext * | name,
|  | void * | value
| ) |  |

`#include <ocilib.h>`

Set a thread key value.

Parameters

  name | - Thread key name
  value | - user value to set

Returns
  TRUE on success otherwise FALSE

Referenced by ocilib::ThreadKey::SetValue().

## OCI_ThreadKeyGetValue()

OCI_EXPORT void* OCI_API OCI_ThreadKeyGetValue | ( | const otext * | name | ) |

`#include <ocilib.h>`

Get a thread key value.

Parameters

  name | - Thread key name

Returns
  Thread key value on success otherwise FALSE

Referenced by ocilib::ThreadKey::GetValue().