Genivia Home Documentation
Thread and mutex functions

updated Tue Aug 27 2024 by Robert van Engelen
 
Thread and mutex functions

This module defines portable thread and mutex functions. More...

Macros

#define THREAD_TYPE
 Type of a thread (thread ID) More...
 
#define THREAD_ID
 The thread ID of self. More...
 
#define THREAD_CREATE(tidptr, funcptr, argptr)
 Create a new thread. More...
 
#define THREAD_CREATEX(tidptr, funcptr, argptr)
 Create a new joinable thread (Windows only) More...
 
#define THREAD_CLOSE(tid)
 Close the thread ID handle created by THREAD_CREATEX (Windows only) More...
 
#define THREAD_DETACH(tid)
 Detach a thread. More...
 
#define THREAD_JOIN(tid)
 Join a thread. More...
 
#define THREAD_EXIT
 Exit the current thread. More...
 
#define THREAD_CANCEL(tid)
 Cancel a thread. More...
 
#define MUTEX_TYPE
 Type of a mutex object. More...
 
#define MUTEX_INITIALIZER
 Mutex initializer object. More...
 
#define MUTEX_SETUP(mx)
 Mutex object initialization. More...
 
#define MUTEX_CLEANUP(mx)
 Mutex object finalization. More...
 
#define MUTEX_LOCK(mx)
 Mutex object lock. More...
 
#define MUTEX_UNLOCK(mx)
 Mutex object unlock. More...
 
#define COND_TYPE
 The type of a condition variable. More...
 
#define COND_SETUP(cv)
 Condition variable initialization. More...
 
#define COND_CLEANUP(cv)
 Condition variable finalization. More...
 
#define COND_SIGNAL(cv)
 Condition variable signal operation. More...
 
#define COND_WAIT(mx, cv)
 Condition variable wait operation. More...
 

Detailed Description

This module defines portable thread and mutex functions.

Macro Definition Documentation

#define COND_CLEANUP (   cv)

Condition variable finalization.

This macro finalizes the specified condition variable.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Parameters
cvCOND_TYPE condition variable
#define COND_SETUP (   cv)

Condition variable initialization.

This macro initializes the specified condition variable.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Parameters
cvCOND_TYPE condition variable
#define COND_SIGNAL (   cv)

Condition variable signal operation.

This macro signals the specified condition variable.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Parameters
cvCOND_TYPE condition variable
#define COND_TYPE

The type of a condition variable.

This macro represents a portable condition variable

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
#define COND_WAIT (   mx,
  cv 
)

Condition variable wait operation.

This macro waits on the specified condition variable and releases the mutex while waiting.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Parameters
mxMUTEX_TYPE mutex object
cvCOND_TYPE condition variable
#define MUTEX_CLEANUP (   mx)

Mutex object finalization.

This macro finalizes a mutex object.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
... // some other work to do
Parameters
mxMUTEX_TYPE mutex object
#define MUTEX_INITIALIZER

Mutex initializer object.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
int main()
{
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
...
}
#define MUTEX_LOCK (   mx)

Mutex object lock.

This macro acquires mutex.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
... // some other work to do
Parameters
mxMUTEX_TYPE mutex object
#define MUTEX_SETUP (   mx)

Mutex object initialization.

This macro initializes a mutex object.

To declare and initialize static mutex objects, see MUTEX_INITIALIZER.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
... // some other work to do
Parameters
mxMUTEX_TYPE mutex object
#define MUTEX_TYPE

Type of a mutex object.

This macro represents a portable mutex object type.

To declare and initialize static mutex objects, see MUTEX_INITIALIZER.

Example:
#include "plugin/threads.h"
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
... // some other work to do
Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
#define MUTEX_UNLOCK (   mx)

Mutex object unlock.

This macro releases mutex.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
... // some other work to do
Parameters
mxMUTEX_TYPE mutex object
#define THREAD_CANCEL (   tid)

Cancel a thread.

This macro requests that the specified thread be cancelled.

POSIX threads can be cancelled when currently in a cancellation point, which are certain functions that will terminate the thread when the thread is cancelled.

Warning
Cancelling a thread may lead to resource leaks when the thread has no mechanism to clean up its state (memory allocated, files and sockets opened etc.), unless cleanup handlers are defined for each thread, e.g. with pthread_cleanup_push. Even when defining a cleanup function, care must be taken to prevent resource leaks that may be caused by cancellation points that sit between a resouce acquisition operation and its release operation, e.g. between a file open and close operation some read/write functions may be called that are cancellation points. The gSOAP engine and plugins are designed to maintain the engine state using resource pointers to resources (memory, files, sockets etc.) in the soap context. The context should be passed to the cleanup function when added with pthread_cleanup_push to cleanup the context. This cleanup function should call soap_destroy, soap_end, and soap_free (in that order). However, use THREAD_CANCEL at your own risk. User-defined service operations and other non-gSOAP code may not meet the requirements to perform a safe THREAD_CANCEL unless the cleanup functions are carefully designed. Alternatively, a simpler approach with a global flag (a flag per thread) may suffice: set the flag by the main thread to indicate termination is requested of the specific thread and check this flag in the user-defined service operations to terminate the service operation with an error, e.g. return 500.
Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "soapH.h"
#include "plugin/threads.h"
struct soap *soap = soap_new();
soap->bind_flags = SO_REUSEADDR; // immediate port reuse
soap->accept_timeout = 3600; // exit loop when no request arrives in one hour
soap->send_timeout = soap_recv_timeout = 5; // 5 seconds max socket stall time (unlimited by default)
soap->transfer_timeout = 30; // 30 seconds max message transfer time (unlimited by default)
soap->recv_maxlength = 1048576; // limit messages received to 1MB (2GB by default)
if (soap_valid_socket(soap_bind(soap, NULL, PORTNUM, BACKLOG)))
{
while (1)
{
{
struct soap *tsoap = soap_copy(soap);
if (!tsoap)
else
while (THREAD_CREATE(&tid, (void*(*)(void*))&accept_request, (void*)tsoap))
sleep(1); // failed, try again
}
else if (soap->errnum) // accept failed, try again after 1 second
{
soap_print_fault(soap, stderr);
sleep(1);
}
else // accept_timeout timed out, quit looping
{
break;
}
soap_destroy(soap);
soap_end(soap);
}
}
soap_free(soap);
void *accept_request(struct soap *soap)
{
struct soap *tsoap;
// create a new thread that is timed to execute for max 10 seconds
tsoap = soap_copy(soap);
if (!tsoap)
{
}
else
{
while (THREAD_CREATE(&tid, (void*(*)(void*))&process_request, (void*)tsoap))
sleep(1); // failed, try again
// allow serving the request by the new thread for up to 30 seconds max
sleep(30);
// terminate process_request thread
}
// clean up
soap_destroy(soap);
soap_end(soap);
soap_free(soap);
return NULL;
}
void *process_request(struct soap *soap)
{
// add the cleanup function
pthread_cleanup_push((void(*)(void*))&cleanup, (void*)soap);
soap_serve(soap);
// remove the cleanup function and call it to cleanup the context
pthread_cleanup_pop(1);
return NULL;
}
void cleanup(struct soap *soap)
{
soap_destroy(soap);
soap_end(soap);
soap_free(soap);
}
Parameters
tidTHREAD_TYPE thread ID to cancel
#define THREAD_CLOSE (   tid)

Close the thread ID handle created by THREAD_CREATEX (Windows only)

#define THREAD_CREATE (   tidptr,
  funcptr,
  argptr 
)

Create a new thread.

This macro creates a new thread and runs the specified function with the argument parameter passed to this function.

Warning
On Windows platforms THREAD_CREATE uses _beginthread which returns a thread ID handle that cannot be joined. To join a thread use THREAD_CREATEX(&tid, func, arg) then THREAD_JOIN. Don't forget to THREAD_CLOSE(tid) afterwards:
#include "plugin/threads.h"
while (THREAD_CREATEX(&tid, (void*(*)(void*))&process_request, (void*)tsoap)))
sleep(1); // failed, try again
... // some other work to do
THREAD_JOIN(tid); // wait for the thread to terminate and join
THREAD_CLOSE(tid); // close handle
... // some other work to do
Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
while (THREAD_CREATE(&tid, (void*(*)(void*))&process_request, (void*)tsoap)))
sleep(1); // failed, try again
... // some other work to do
THREAD_JOIN(tid); // optional: to wait for the thread to terminate and join (see warning)
... // some other work to do
Parameters
tidptrpointer to THREAD_TYPE thread ID to assign
funcptrfunction to run by the new thread
argptrthe argument (a pointer) to pass to the function when called
Returns
zero on success and nonzero on failure
#define THREAD_CREATEX (   tidptr,
  funcptr,
  argptr 
)

Create a new joinable thread (Windows only)

On Windows platforms THREAD_CREATE uses _beginthread which returns a thread ID handle that cannot be joined. To join a thread use THREAD_CREATEX(&tid, func, arg) then THREAD_JOIN. Don't forget to THREAD_CLOSE(tid) afterwards.

#define THREAD_DETACH (   tid)

Detach a thread.

This macro detaches the specified thread. A detached thread cannot be joined back with the thread that created it. When a detached thread terminates, its resources are automatically released back to the system without the need for another thread to join with the terminated thread.

This macro has no effect on Windows platforms, see THREAD_CREATE.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
#include "plugin/threads.h"
THREAD_DETACH(THREAD_ID); // detach self
Parameters
tidTHREAD_TYPE thread ID to detach
#define THREAD_EXIT

Exit the current thread.

This macro terminates the current thread.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
#define THREAD_ID

The thread ID of self.

This macro represents the current thread ID, i.e. self.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
#define THREAD_JOIN (   tid)

Join a thread.

This macro waits for the termination of the specified thread to join it.

This macro requires THREAD_CREATEX and THREAD_CLOSE on Windows plaforms.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Parameters
tidTHREAD_TYPE thread ID to join
#define THREAD_TYPE

Type of a thread (thread ID)

This macro represents a portable thread ID type.

Note
This macro is declared in gsoap/plugin/threads.h and requires compilation of gsoap/plugin/threads.c on Windows platforms.
Example:
while (THREAD_CREATE(&tid, (void*(*)(void*))&process_request, (void*)tsoap)))
sleep(1); // failed, try again