AOLserver

# Thread C Library Functions

$Header: /cvsroot/aolserver/aolserver.com/docs/devel/c/index.html,v 1.1 2002/03/07 19:15:35 kriston Exp $

## Ns_AbsTimedWaitForEvent

Wait for an event to be broadcast

### Syntax

        int Ns_AbsTimedWaitForEvent (
        Ns_Cond* event,
        Ns_Mutex* lock,
        time_t abstime
        );

### Description

Wait for an event to be broadcast or the current time to be abstime, whichever comes first.

## Ns_AllocThreadLocalStorage

Initialize a local thread storage variable.

### Syntax

        int Ns_AllocThreadLocalStorage(
        Ns_ThreadLocalStorage * tls,
        void (*destructor) (void *)
        );

### Description

Initializes a thread local storage variable and sets its destructor function. The tls's value is initially NULL in all existing threads and any new threads which are later created. If the destructor function pointer is non-null and the tls is non-null in a particular thread when it exits, the destructor will be called for that thread.

Thread local storage is often used to store data which must be shared between unrelated functions much like global variables are used in a single threaded program. Thread local storage is also often used to provide buffer space unique to each thread when making older code thread safe.

### Examples

        static Ns_ThreadLocalStorage tls;

        void
        Init(void)
        {
            /* This function is called once at startup. */
            Ns_AllocThreadLocalStorage(&tls, Ns_Free);
        }

        char *
        GetBuffer
        {
            void *ptr;

            Ns_GetThreadLocalStorage(&tls, &ptr);
            if (ptr == NULL) {
                    /* Allocate a buffer for this thread. */
                    ptr = Ns_Malloc(BUFFER_SIZE);
                    Ns_SetThreadLocalStorage(&tls, ptr);
            }
            return (char *) ptr;
        }

## Ns_BeginDetachedThread

Create a detached thread

### Syntax

        int Ns_BeginDetachedThread(
        Ns_ThreadProc *start_routine,
        void *arg
        );

### Description

Ns_BeginDetachedThread creates a thread which cleans up its data as soon as it ends. Note that detached threads' ids can be reused immediately by the system, and they cannot be waited on.

### Examples

        static void
        ThreadStart(void *arg)
        {
            int n;

            n = (int) arg;
            Ns_Log(Notice, "%d: %d", Ns_GetThreadId(), n);
        }

        /*
          * ManyThreads - Create 10 threads which all log a message.
          */
        static void
        ManyThreads(void)
        {
            int i;

            for (i = 0; i < 10; ++i) {
                    Ns_BeginDetachedThread(ThreadStart, (void *) i);
            }
        }

## Ns_BeginThread

Start a thread

### Syntax

        int Ns_BeginThread(
        Ns_ThreadProc *start_routine,
        void *arg,
        Ns_Thread *thread
        );

### Description

Ns_BeginThread starts a new thread running start_routine and passwd arg as its context. If thread is non-null it will be filled with the thread's id. (see Ns_WaitForThread.)

Ns_ThreadCreate is the preferred function to start a thread.

### Examples

        static void
        ThreadStart(void *arg)
        {
            int n;

            n = (int) arg;
            Ns_Log(Notice, "%d: %d", Ns_GetThreadId(), n);
        }

        /*
          * ManyThreadWait - Create 10 threads which all log a message
          * and wait for all of them to exit.
          */
        static void
        ManyThreadWait(void)
        {
            int i;
            Ns_Thread tids[10];

            for (i = 0; i < 10; ++i) {
                    Ns_BeginThread(ThreadStart, (void *) i, &tids[i]);
            }

            for (i = 0; i < 10; ++i) {
                    Ns_WaitForThread(&tids[i]);
            }
        }

## Ns_BroadcastEvent

Wake up events that are waiting to be triggered

### Syntax

        int Ns_BroadcastEvent(
        Ns_Event * event
        );

### Description

Wake up all the threads waiting on the event. If no threads are waiting on the event, this function has no effect.

### Examples

        static Ns_Event myev;
        static Ns_Mutex mylock;

        void
        Init(void)
        {
            /* Initialize the lock and event at startup. */
            Ns_InitializeMutex(&mylock);
            Ns_InitializeEvent(&myev);
        }

        /* Lock the mutex and wait for the event. */
        void
        WaitFunc(void)
        {
            Ns_LockMutex(&mylock);
            Ns_WaitForEvent(&myev, &mylock);
        }

        /* Wake up any waiting threads. */
        void
        BroadcastFunc(void)
        {
            Ns_BroadcastEvent(&myev);
        }

## Ns_CacheBroadcast

Broadcast to condition variable

### Syntax

        void Ns_CacheBroadcast (
        Ns_Cache* cache
        );

### Description

Broadcast to the cache's condition variable, waking all threads. Every cache has an associated cond for user use. Every cache has an associated cond for user use.

## Ns_CacheCreate

Create a new cache

### Syntax

        Ns_Cache* Ns_CacheCreate (
        char* name,
        int keys,
        time_t timeout,
        Ns_Callback* freeProc
        );

### Description

Create a new cache with the specified name. The keys argument is the size of the cache key in system words. The timeout argument is the time for cache entries to live. The freeProc argument is the Ns_Callback to free cache entry data.

For a good example of how to use the Ns_Cache* functions, look at nsd/fastpath.c.

## Ns_CacheCreateEntry

Create a cache entry

### Syntax

        Ns_Entry* Ns_CacheCreateEntry (
        Ns_Cache* cache,
        char* key,
        int* pnew
        );

### Description

Create a new cache entry in the specified cache. This function emulates Tcl_CreateHashEntry's interface.

## Ns_CacheCreateSz

Create a size-based cache

### Syntax

        Ns_Cache* Ns_CacheCreateSz (
        char* name,
        int keys,
        size_t maxsize,
        Ns_Callback* freeProc
        );

### Description

Create a new size-based cache (a cache that has a maximum size in bytes, specified by the maxsize argument). The keys argument is TCL_STRING_KEYS or TCL_ONE_WORD_KEYS or an integer >=2, which is the number of machine words needed to store a cache key. The freeProc argument is the Ns_Callback to free cache entry data.

## Ns_CacheDeleteEntry

Delete a cache entry

### Syntax

        void Ns_CacheDeleteEntry (
        Ns_Entry* entry
        );

### Description

Delete the specified entry from the cache table.

## Ns_CacheFind

Find a cache

### Syntax

        Ns_Cache* Ns_CacheFind (
        char* name
        );

### Description

Find a cache by name.

## Ns_CacheFindEntry

Find a cache entry

### Syntax

        Ns_Entry* Ns_CacheFindEntry (
        Ns_Cache* cache,
        char* key
        );

### Description

Find a cache entry.

## Ns_CacheFirstEntry

Get first cache entry

### Syntax

        Ns_Entry* Ns_CacheFirstEntry (
        Ns_Cache* cache,
        Ns_CacheSearch* searchPtr
        );

### Description

Return a pointer to the first entry in the cache (Cache entries are stored in no particular order.)

## Ns_CacheFlush

Flush all cache entries

### Syntax

        void Ns_CacheFlush (
        Ns_Cache* cache
        );

### Description

Flush every entry from the specified cache.

## Ns_CacheFlushEntry

Delete a cache entry

### Syntax

        void Ns_CacheFlushEntry (
        Ns_Entry* entry
        );

### Description

Delete an entry from the cache table after first unsetting the current entry value (if any).

## Ns_CacheFree

Free allocated memory

### Syntax

        void Ns_CacheFree (
        Ns_Cache* cache,
        void* memPtr
        );

### Description

Frees memory allocated with Ns_CacheMalloc.

## Ns_CacheGetValue

Get value of cache entry

### Syntax

        void* Ns_CacheGetValue (
        Ns_Entry* entry
        );

### Description

Get the value (contents) of a cache entry.

## Ns_CacheKey

Get key of cache entry

### Syntax

        char* Ns_CacheKey (
        Ns_Entry* entry
        );

### Description

Gets the key of a cache entry.

## Ns_CacheLock

Lock a cache

### Syntax

        void Ns_CacheLock (
        Ns_Cache* cache
        );

### Description

Lock the cache. This must be done before performing any read/write action on a cache.

## Ns_CacheMalloc

Allocate memory

### Syntax

        void* Ns_CacheMalloc (
        Ns_Cache* cache,
        size_t len
        );

### Description

Allocate memory from a cache-local pool.

## Ns_CacheName

Get name of cache

### Syntax

        char* Ns_CacheName (
        Ns_Entry* entry
        );

### Description

Get the name of the cache.

## Ns_CacheNextEntry

Get next cache entry

### Syntax

        Ns_Entry* Ns_CacheNextEntry (
        Ns_CacheSearch* searchPtr
        );

### Description

Get the next cache entry. When used in conjunction with Ns_CacheFirstEntry, you can traverse the whole cache.

## Ns_CacheSetValue

Set value of cache entry

### Syntax

        void Ns_CacheSetValue (
        Ns_Entry* entry,
        void* value
        );

### Description

Set the value of a cache entry.

## Ns_CacheSetValueSz

Set value of cache entry and adjust cache size

### Syntax

        void Ns_CacheSetValueSz (
        Ns_Entry* entry,
        void* value,
        size_t size
        );

### Description

Free the cache entry's previous contents, set it to the new contents, increase the size of the cache, and prune the cache until it's back under the maximum size.

## Ns_CacheSignal

Signal cache's condition variable

### Syntax

        void Ns_CacheSignal (
        Ns_Cache* cache
        );

### Description

Signal the cache's condition variable, waking the first waiting thread (if any).

Note: Consider waking all threads with Ns_CacheBroadcast, instead.

## Ns_CacheTimedGetValue

Wait for cache entry to be set

### Syntax

        void* Ns_CacheTimedGetValue (
        Ns_Cache* cache,
        char* key,
        Ns_Time* timePtr,
        int* condPtr
        );

### Description

Wait for an entry's value to be set to non-null by some other thread up to the given timeout or until an optional condition integer becomes zero. Note that the cache and key are given instead of the entry because you cannot rely on an entry to remain valid during the Ns_CondTimedWait.

## Ns_CacheTimedWait

Wait for condition variable to be set

### Syntax

        int Ns_CacheTimedWait (
        Ns_Cache* cache,
        Ns_Time* timePtr
        );

### Description

Wait for the cache's condition variable to be signaled or the given absolute timeout if timePtr is not NULL.

## Ns_CacheUnlock

Unlock cache

### Syntax

        void Ns_CacheUnlock (
        Ns_Cache* cache
        );

### Description

Unlock the specified cache.

## Ns_CacheUnsetValue

Reset cache entry to null

### Syntax

        void Ns_CacheUnsetValue (
        Ns_Entry* entry
        );

### Description

Reset the value of an entry to NULL, calling the free proc for any previous entry and updating the cache size.

## Ns_CacheWait

Wait indefinitely for condition variable to be set

### Syntax

        void Ns_CacheWait (
        Ns_Cache* cache
        );

### Description

Wait indefinitely for the cache's condition variable to be signaled.

## Ns_CondBroadcast

Wake up all threads waiting on a cond

### Syntax

        void Ns_CondBroadcast (
        Ns_Cond*
        );

### Description

Wake up all threads that are waiting on a cond. For more informations on condition variables, look at the pthread_cond_wait(3P) man page.

## Ns_CondDestroy

Free a cond's memory

### Syntax

        void Ns_CondDestroy (
        Ns_Cond *condPtr
        );

### Description

Free a cond's memory.

## Ns_CondInit

Initialize a cond

### Syntax

        void Ns_CondInit (
        Ns_Cond *condPtr
        );

### Description

Initialize a cond. You don't need to call this function if it is initialized to 0, as is the case with static variables.

## Ns_CondSignal

Wake up a single thread

### Syntax

        void Ns_CondSignal (
        Ns_Cond *condPtr
        );

### Description

Wake up a single thread blocking on a cond.

## Ns_CondTimedWait

Block on a cond

### Syntax

        int Ns_CondTimedWait (
        Ns_Cond *condPtr ,
        Ns_Mutex *mutexPtr ,
        Ns_Time *timePtr
        );

### Description

Block on a cond until signaled or the specified time expires. The time is absolute. The Ns_Time value can be manipulated with Ns_GetTime, Ns_DiffTime, or Ns_IncrTime.

## Ns_CondWait

Wait indefinitely on a cond

### Syntax

        void Ns_CondWait (
        Ns_Cond *condPtr ,
        Ns_Mutex *mutexPtr
        );

### Description

Wait indefinetly on a cond.

## Ns_CsDestroy

Destroy a critical section object

### Syntax

        void Ns_CsDestroy(
        Ns_Cs*
        );

### Description

Free the resources associated with the critical section.

## Ns_CsEnter

Enter a critical section

### Syntax

        void Ns_CsEnter(
        Ns_Cs *csPtr
        );

### Description

Enter the specified critical section. If the critical section is use by another thread, the current will block until it is no longer so. Note that critical sections are recursive and must be exited the same number of times as they were entered.

## Ns_CsInit

Initialize a critical section

### Syntax

        void Ns_CsInit(
        Ns_Cs *csPtr
        );

### Description

Initialize the specified critical section. It is recommended that you use a mutex instead of a critical section if possible.

## Ns_CsLeave

Leave a critical section

### Syntax

        void Ns_CsLeave(
        Ns_Cs *csPtr
        );

### Description

Leave the specified critical section.

## Ns_DestroyCriticalSection

Free a critical section's resources

### Syntax

        int Ns_DestroyCriticalSection(
        Ns_CriticalSection * section
        );

### Description

Free the resources associated with the critical section.

Ns_CsDestroy is the preferred function for freeing a critical section's resources.

## Ns_DestroyEvent

Free an event's resources

### Syntax

        int Ns_DestroyEvent(
        Ns_Event * event
        );

### Description

Free the resources associated with the event object.

## Ns_DestroyMutex

Free a mutual exclusion lock's resources

### Syntax

        int Ns_DestroyMutex(
        Ns_Mutex * mutex
        );

### Description

Free the mutex's associated resources.

Ns_MutexDestroy is the preferred function for freeing a mutex's resources.

## Ns_DestroyRWLock

Destroy a read/write lock

### Syntax

        int Ns_DestroyRWLock(
        Ns_RWLock *lock
        );

### Description

Ns_DestroyRWLock frees the read/write lock's associated resources.

For general information about read/write locks and an example showing the use of the read/write lock functions, see the Ns_InitializeRWLock function.

Ns_RWLockDestroy is the preferred function for destroying a read/write lock.

## Ns_DestroySemaphore

Free a semaphore's resources

### Syntax

        int Ns_DestroySemaphore(
        Ns_Semaphore * sema
        );

### Description

Free the resources associated with the semaphore.

Ns_SemaDestroy is the preferred function for freeing a semaphore's resources.

## Ns_EnterCriticalSection

Enter a critical section

### Syntax

        int Ns_EnterCriticalSection(
        Ns_CriticalSection * section
        );

### Description

Enter the specified critical section. If the critical section is use by another thread, the current will block until it is no longer so. Note that critical sections are recursive and must be exited the same number of times as they were entered.

Ns_CsEnter is the preferred function for entering a critical section.

## Ns_ExitThread

Free a thread or mark as exited

### Syntax

        void Ns_ExitThread (
        int retcode
        );

### Description

Cleanup the thread's tls and memory pool and either free the thread if it's detached or mark the thread as exited and allow it to be joined.

Ns_ThreadExit is the preferred function for freeing a thread.

## Ns_GetThread

Get the identifier for the current thread

### Syntax

        void Ns_GetThread(
        Ns_Thread *thread
        );

### Description

Ns_GetThread fills in the unique thread identifier for the current thread. (see Ns_WaitForThread)

## Ns_GetThreadId

Get the unique ID number for the current thread

### Syntax

        int Ns_GetThreadId(void);

### Description

This routine tries to come up with a unique integer corresponding to the current thread. (This is the integer that shows up in the log files.) Often, this unique ID is the PID, but not always.

## Ns_GetThreadLocalStorage

Get the thread local storage

### Syntax

        int Ns_GetThreadLocalStorage(
        Ns_ThreadLocalStorage * tls,
        void **p
        );

### Description

Fill *p with the value of the thread local storage. Note: If tls has not been set within the current the thread *p will be set to NULL.

Ns_TlsGet is the preferred function for getting thread local storage.

## Ns_InitializeCriticalSection

Initialize a critical section

### Syntax

        int Ns_InitializeCriticalSection(
        Ns_CriticalSection * section
        );

### Description

Initialize the specified critical section. It is recommended that you use a mutex instead of a critical section if possible.

Ns_CsInit is the preferred function for initializing a critical section.

## Ns_InitializeEvent

Initialize an event object

### Syntax

        int Ns_InitializeEvent(
        Ns_Event * event
        );

### Description

Initialize an event object.

## Ns_InitializeMutex

Initialize a mutual exclusion lock

### Syntax

        int Ns_InitializeMutex(
        Ns_Mutex * mutex
        );

### Description

Initialize a Mutual Exclusion lock for use.

Ns_MutexInit is the preferred function for initializing a mutex.

## Ns_InitializeRWLock

Initialize a read/write lock

### Syntax

        int Ns_InitializeRWLock(
        Ns_RWLock *lock
        );

### Description

Initialize a read/write lock for use. A lock ID is returned via the lock parameter, which can be used in the other read/write lock functions.

About Read/Write Locks Read/write locks are a serialization mechanism for using data structures where multiple reads can happen simultaneously, but where writes must happen singly. For example, suppose you have a hash table that is heavily used but doesn't change very often. You'd like to have multiple threads be able to read from the table without blocking on each other, but when you need to update the table, you can do so safely without having to worry about other threads reading incorrect data.

The principal feature of read/write locks is the mechanism of which locks have priority and which locks must wait. Any number of read locks can be pending. If there's a write lock active, the read lock acquisition blocks until the write lock is released. Also, only one write lock can be in effect. If there are pending read locks active, the write lock acquisition blocks until all of the read locks drain. If a subsequent read lock acquisition attempt is made while a write lock is waiting to acquire, the write lock has priority.

Ns_RWLockInit is the preferred function for initializing a read/write lock.

### Examples

        NS_RWLock lock;
        int GetData (int key)
        {
            /* acquire a read lock */
            Ns_ReadLockRWLock (&lock);
            search through the data structure looking for key's data;

            /* release our read lock */
            Ns_ReadUnlockRWLock (&lock);
            return (value);

        } /* GetData */
        int StoreData (int key, int value)
        {
           /* acquire the write lock */
           Ns_WriteLockRWLock (&lock);
           manipulate the data structure storing key's value;
           /* release the write lock */
           Ns_WriteUnlockRWLock (&lock);
           return (value);
        } /* StoreData */
        ...
        Ns_InitializeRWLock (&lock);
        ...
        (different threads using GetData and StoreData)
        ...
        Ns_DestoryRWLock (&lock);

## Ns_InitializeSemaphore

Initialize a semaphore

### Syntax

        int Ns_InitializeSemaphore(
        Ns_Semaphore * sema,
        int beg_count
        );

### Description

Initialize the semaphore with a semaphore count of beg_count.

Ns_SemaInit is the preferred function for initializing a semaphore.

## Ns_LeaveCriticalSection

Leave a critical section

### Syntax

        int Ns_LeaveCriticalSection(
        Ns_CriticalSection * section
        );

### Description

Leave the specified critical section.

Ns_CsLeave is the preferred function for leaving a critical section.

## Ns_LockMutex

Create a mutual exclusion lock

### Syntax

        int Ns_LockMutex(
        Ns_Mutex * mutex
        );

### Description

Acquire the mutex. If the mutex is already locked then the current thread will block until the mutex is unlocked. Note: mutexes are not recursive. If the current thread tries to lock the mutex twice in a row, it will block or get an error depending on the platform.

## Ns_MutexDestroy

Destroy a mutex object

### Syntax

        void Ns_MutexDestroy (
        Ns_Mutex *mutexPtr
        );

### Description

Free the mutex's associated resources.

## Ns_MutexInit

Initialize a mutex object

### Syntax

        void Ns_MutexInit (
        Ns_Mutex *mutexPtr
        );

### Description

Initialize a Mutual Exclusion lock for use.

## Ns_MutexLock

Lock a mutex object

### Syntax

        void Ns_MutexLock (
        Ns_Mutex *mutexPtr
        );

### Description

Acquire the mutex. If the mutex is already locked then the current thread will block until the mutex is unlocked. Note: mutexes are not recursive. If the current thread tries to lock the mutex twice in a row, it will block or get an error depending on the platform.

## Ns_MutexUnlock

Unlock a mutex object

### Syntax

        void Ns_MutexUnlock (
        Ns_Mutex *mutexPtr
        );

### Description

Unlock the mutex.

## Ns_ReadLockRWLock

Acquire a read lock

### Syntax

        int Ns_ReadLockRWLock(
        Ns_RWLock *lock
        );

### Description

Ns_ReadLockRWLock acquires a read lock. Any number of read locks can be pending. If there's a write lock active, the read lock acquisition blocks until the write lock is released.

For general information about read/write locks and an example showing the use of the read/write lock functions, see the Ns_InitializeRWLock function.

Ns_RWLockRdLock is the preferred function for acquiring a read lock.

## Ns_ReadUnlockRWLock

Release a read lock

### Syntax

        int Ns_ReadUnlockRWLock(
        Ns_RWLock *lock
        );

### Description

Ns_ReadUnlockRWLock releases a read lock.

For general information about read/write locks and an example showing the use of the read/write lock functions, see the Ns_InitializeRWLock function.

Ns_RWLockUnlock is the preferred function for releasing a lock.

## Ns_ReleaseSemaphore

Increment the semaphore count

### Syntax

        int Ns_ReleaseSemaphore(
        Ns_Semaphore * sema,
        int count
        );

### Description

Increment the semaphore count.

Ns_SemaPost is the preferred function for incrementing the semaphore count.

## Ns_RWLockDestroy

Destroy a read/write lock

### Syntax

        void Ns_RWLockDestroy (
        Ns_RWLock*
        );

### Description

Ns_RWLockDestroy frees the read/write lock's associated resources.

## Ns_RWLockInit

Initialize a read/write lock

### Syntax

        void Ns_RWLockInit (
        Ns_RWLock*
        );

### Description

Initialize a read/write lock for use. A lock ID is returned via the lock parameter, which can be used in the other read/write lock functions.

About Read/Write Locks Read/write locks are a serialization mechanism for using data structures where multiple reads can happen simultaneously, but where writes must happen singly. For example, suppose you have a hash table that is heavily used but doesn't change very often. You'd like to have multiple threads be able to read from the table without blocking on each other, but when you need to update the table, you can do so safely without having to worry about other threads reading incorrect data.

The principal feature of read/write locks is the mechanism of which locks have priority and which locks must wait. Any number of read locks can be pending. If there's a write lock active, the read lock acquisition blocks until the write lock is released. Also, only one write lock can be in effect. If there are pending read locks active, the write lock acquisition blocks until all of the read locks drain. If a subsequent read lock acquisition attempt is made while a write lock is waiting to acquire, the write lock has priority.

## Ns_RWLockRdLock

Acquire a read lock

### Syntax

        void Ns_RWLockRdLock (
        Ns_RWLock *lockPtr
        );

### Description

Ns_RWLockRdLock acquires a read lock. Any number of read locks can be pending. If there's a write lock active, the read lock acquisition blocks until the write lock is released.

## Ns_RWLockUnlock

Release a read/write lock

### Syntax

        void Ns_RWLockUnlock (
        Ns_RWLock *lockPtr
        );

### Description

Ns_RWLockUnlock releases a read or write lock.

## Ns_RWLockWrLock

Acquire a write lock

### Syntax

        void Ns_RWLockWrLock (
        Ns_RWLock *lockPtr
        );

### Description

Ns_RWLockWrLock acquires a write lock. Only one write lock can be in effect. If there are pending read locks active, the write lock acquisition blocks until all of the read locks drain. If a subsequent read lock acquisition attempt is made, the write lock has priority.

## Ns_SemaDestroy

Destroy a semaphore object

### Syntax

        int Ns_SemaDestroy(
        Ns_Sema*
        );

### Description

Free the resources associated with the semaphore.

## Ns_SemaInit

Initialize a semaphore

### Syntax

        int Ns_SemaInit(
        Ns_Sema* ,
        int count
        );

### Description

Initialize the semaphore with a semaphore count of count.

## Ns_SemaPost

Increment the semaphore count

### Syntax

        int Ns_SemaPost(
        Ns_Sema* ,
        int count
        );

### Description

Increment the semaphore count.

## Ns_SemaWait

Wait for a semaphore count to be greater than zero.

### Syntax

        int Ns_SemaWait(
        Ns_Sema*
        );

### Description

If the semaphore count is greater than zero, decrement it and continue. Otherwise, block until this is possible.

## Ns_SetThreadLocalStorage

Set thread local storage

### Syntax

        int Ns_SetThreadLocalStorage(
        Ns_ThreadLocalStorage * tls,
        void *p
        );

### Description

Set the thread local storage tls to the value p.

### Examples

       See the example for Ns_AllocThreadLocalStorage.

    Ns_TlsSet is the preferred function for setting thread local storage.

## Ns_ThreadCreate

Create new thread

### Syntax

        void Ns_ThreadCreate (
        Ns_ThreadProc* proc,
        void* arg,
        long stackSize,
        Ns_Thread* threadPtr
        );

### Description

Create a new thread.

## Ns_ThreadExit

Free or exit thread

### Syntax

        void Ns_ThreadExit (
        int exitCode
        );

### Description

Cleanup the thread's tls and memory pool and either free the thread if it's detached or mark the thread as exited and allow it to be joined.

## Ns_ThreadFree

Free thread pool memory

### Syntax

        void Ns_ThreadFree (
        void* ptr
        );

### Description

Free previously allocated memory from the per-thread pool.

## Ns_ThreadGetName

Get thread name

### Syntax

       char* Ns_ThreadGetName (void);

### Description

Return a pointer to calling thread's string name, as set with Ns_ThreadSetName.

## Ns_ThreadId

Get thread ID

### Syntax

       int Ns_ThreadId (void);

### Description

Return the numeric thread id for the calling thread.

## Ns_ThreadJoin

Wait for thread exit

### Syntax

        void Ns_ThreadJoin (
        Ns_Thread* threadPtr,
        int* exitCodePtr
        );

### Description

Wait for exit of a non-detached thread.

## Ns_ThreadMalloc

Allocate thread pool memory

### Syntax

        void* Ns_ThreadMalloc (
        unsigned int size
        );

### Description

Allocate thread-pool memory.

## Ns_ThreadPool

Get thread pool memory

### Syntax

        Ns_Pool* Ns_ThreadPool (void);

### Description

Get this thread's memory pool.

## Ns_ThreadRealloc

Realloc thread pool memory

### Syntax

        void* Ns_ThreadRealloc (
        void* ptr,
        unsigned int size
        );

### Description

realloc for thread memory pools.

## Ns_ThreadSelf

Get handle to thread

### Syntax

        void Ns_ThreadSelf (
        Ns_Thread* threadPtr
        );

### Description

Return opaque handle to thread's data structure.

## Ns_ThreadSetname

Set thread name

### Syntax

        void Ns_ThreadSetName (
        char* name
        );

### Description

Set the name of the thread, which is used in the server.log. The name can be retrieved with Ns_ThreadGetName.

## Ns_ThreadYield

Yield processor time to runnable threads

### Syntax

        void Ns_ThreadYield(void);

### Description

Ns_ThreadYield yields its processor time to any runnable threads with equal or higher priority.

## Ns_TimedWaitForEvent

Wait for an event for a specified time

### Syntax

        int Ns_TimedWaitForEvent(
        Ns_Event * event,
        Ns_Mutex * lock,
        int usec
        );

### Description

Same as Ns_WaitForEvent except that it has a timeout in seconds. On timeout, the function returns NS_TIMEOUT.

### Examples

            Ns_LockMutex(&lock);
            if (!ready) {
                    result = Ns_TimedWaitForEvent(&ev, &lock, 10);
                    if (result == NS_TIMEOUT) {
                            ... handle timeout ...
                    } else if (result != NS_OK) {
                            ... handle error ...
                    }
            }
            Ns_UnlockMutex(&lock);

## Ns_TlsAlloc

Allocate thread local storage

### Syntax

        void Ns_TlsAlloc (
        Ns_Tls* ,
        Ns_TlsCleanup*
        );

### Description

Allocate thread-local-storage. This is unneeded if the tls variable is initialized to 0 (as static data is). See pthread_setspecific(3P) for details on thread-local storage.

This function is a renamed version of Ns_AllocThreadLocalStorage.

## Ns_TlsGet

Get thread local storage

### Syntax

        void* Ns_TlsGet (
        Ns_Tls *tlsPtr
        );

### Description

Get thread-local-storage. This function is a renamed version of Ns_GetThreadLocalStorage.

## Ns_TlsSet

Set thread local storage

### Syntax

        void Ns_TlsSet (
        Ns_Tls *tlsPtr ,
        void *value
        );

### Description

Set thread local storage. This function is a renamed version of Ns_SetThreadLocalStorage.

## Ns_UnlockMutex

Unlock the mutual exclusion lock

### Syntax

        int Ns_UnlockMutex(
        Ns_Mutex * mutex
        );

### Description

Unlock the mutex.

Ns_MutexLock is the preferred function for unlocking a mutex.

### Examples

       See the example for Ns_LockMutex.

## Ns_UTimedWaitForEvent

Wait for an event for a specified time, in microseconds

### Syntax

        int Ns_UTimedWaitForEvent(
        Ns_Event *event,
        Ns_Mutex *lock,
        int seconds,
        int microseconds
        );

### Description

Same as Ns_WaitForEvent except that it has a timeout in microseconds. On timeout, the function returns NS_TIMEOUT.

On the Irix platform, the timeout granularity is still in seconds. In this case, if you specify a timeout of less than one second, it will be treated as one second.

## Ns_WaitForEvent

Wait for an event

### Syntax

        int Ns_WaitForEvent(
        Ns_Event * event,
        Ns_Mutex * lock
        );

### Description

Unlock the lock and wait for the event. This function blocks the current thread's execution until the event has been set and it can reacquire the lock. The mutex lock is locked before and after the call.

### Examples

        static int ready = 0;
        static Ns_Event ev;
        static Ns_Mutex lock;

        void
        Init(void)
        {
            Ns_InitializeMutex(&lock);
            Ns_InitializeEvent(&ev);
        }

        void
        Waiter(void)
        {
            Ns_LockMutex(&lock);
            if (!ready) {
                    Ns_WaitForEvent(&ev, &lock);
            }
            Ns_UnlockMutex(&lock);
            ... resource ready ...
        }

## Ns_WaitForSemaphore

Wait for a semaphore count to be greater than zero.

### Syntax

        int Ns_WaitForSemaphore(
        Ns_Semaphore * sema
        );

### Description

If the semaphore count is greater than zero, decrement it and continue. Otherwise, block until this is possible.

Ns_SemaWait is the preferred function for waiting for a semaphore.

### Examples

        static Ns_Semaphore sem;

        void

    Init(void)
        {
            Ns_InitializeSemaphore(&sem, 0);
        }

        void
        Waiter(void)
        {
            Ns_WaitForSemaphore(&sem);
            ... access resource ...
        }

        void
        Releaser(void)
        {
            Ns_ReleaseSemaphore(&sem, 1);
        }

## Ns_WaitForThread

Wait for a thread to exit

### Syntax

        int Ns_WaitForThread(
        Ns_Thread *thread
        );

### Description

This routine blocks the current thread's execution until the specified thread exits.

### Examples

       See the example for Ns_BeginThread.

## Ns_WaitThread

Wait for thread to exit

### Syntax

        int Ns_WaitThread (
        Ns_Thread* thread,
        int* retcode
        );

### Description

This function blocks the current thread's execution until the specified thread exits.

## Ns_WriteLockRWLock

Acquire a write lock

### Syntax

        int Ns_WriteLockRWLock(
        Ns_RWLock *lock
        );

### Description

Ns_WriteLockRWLock acquires a write lock. Only one write lock can be in effect. If there are pending read locks active, the write lock acquisition blocks until all of the read locks drain. If a subsequent read lock acquisition attempt is made, the write lock has priority.

For general information about read/write locks and an example showing the use of the read/write lock functions, see the Ns_InitializeRWLock function.

Ns_RWLockWrLock is the preferred function for acquiring a write lock.

## Ns_WriteUnlockRWLock

Release a write lock.

### Syntax

        int Ns_WriteUnlockRWLock(
        Ns_RWLock *lock
        );

### Description

Ns_WriteUnlockRWLock releases a write lock.

For general information about read/write locks and an example showing the use of the read/write lock functions, see the Ns_InitializeRWLock function.

Ns_RWLockUnlock is the preferred function for releasing a lock.