|  | Home | Documentation | Thread and mutex functions updated by Robert van Engelen |

Thread and mutex functions

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

## Macros

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

## Detailed Description

This module describes portable thread and mutex functions.

- #THREAD_TYPE
- #THREAD_ID
- #THREAD_CREATE(tidptr, funcptr, argptr)
- #THREAD_CREATEX(tidptr, funcptr, argptr) (for Windows)
- #THREAD_CLOSE(tid) (for Windows)
- #THREAD_DETACH(tid)
- #THREAD_JOIN(tid)
- #THREAD_EXIT
- #THREAD_CANCEL(tid)
- #MUTEX_TYPE
- #MUTEX_INITIALIZER
- #MUTEX_SETUP(mx)
- #MUTEX_CLEANUP(mx)
- #MUTEX_LOCK(mx)
- #MUTEX_TRYLOCK(mx)
- #MUTEX_UNLOCK(mx)
- #COND_TYPE
- #COND_SETUP(cv)
- #COND_CLEANUP(cv)
- #COND_SIGNAL(cv)
- #COND_WAIT(mx, cv)

## Macro Definition Documentation

## ◆ COND_CLEANUP

#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

  cv | #COND_TYPE condition variable

## ◆ COND_SETUP

#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

  cv | #COND_TYPE condition variable

## ◆ COND_SIGNAL

#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

  cv | #COND_TYPE condition variable

## ◆ COND_TYPE

#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.

## ◆ COND_WAIT

#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

  mx | #MUTEX_TYPE mutex object
  cv | #COND_TYPE condition variable

## ◆ MUTEX_CLEANUP

#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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
... // some other work to do
MUTEX_CLEANUP(lock);
MUTEX_CLEANUP
#define MUTEX_CLEANUP(mx)
Mutex object finalization.
Definition stdsoap2.h:11063
MUTEX_LOCK
#define MUTEX_LOCK(mx)
Mutex object lock.
Definition stdsoap2.h:11088
MUTEX_UNLOCK
#define MUTEX_UNLOCK(mx)
Mutex object unlock.
Definition stdsoap2.h:11144
MUTEX_TYPE
#define MUTEX_TYPE
Type of a mutex object.
Definition stdsoap2.h:10989
MUTEX_SETUP
#define MUTEX_SETUP(mx)
Mutex object initialization.
Definition stdsoap2.h:11038

Parameters

  mx | #MUTEX_TYPE mutex object

## ◆ MUTEX_INITIALIZER

#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"
static MUTEX_TYPE lock = MUTEX_INITIALIZER;
int main()
{
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
...
}
MUTEX_INITIALIZER
#define MUTEX_INITIALIZER
Mutex initializer object.
Definition stdsoap2.h:11011

## ◆ MUTEX_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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
... // some other work to do
MUTEX_CLEANUP(lock);

Parameters

  mx | #MUTEX_TYPE mutex object

## ◆ MUTEX_SETUP

#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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
... // some other work to do
MUTEX_CLEANUP(lock);

Parameters

  mx | #MUTEX_TYPE mutex object

## ◆ MUTEX_TRYLOCK

#define MUTEX_TRYLOCK | ( |  | mx | ) |

Mutex object try lock attempt to lock.

This macro acquires mutex if not locked, returns zero on success and nonzero on failure to lock

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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
if (MUTEX_TRYLOCK(lock) == 0)
{
... // critical section
MUTEX_UNLOCK(lock);
}
else
{
... // lock not acquired
}
... // some other work to do
MUTEX_CLEANUP(lock);
MUTEX_TRYLOCK
#define MUTEX_TRYLOCK(mx)
Mutex object try lock attempt to lock.
Definition stdsoap2.h:11119

Parameters

  mx | #MUTEX_TYPE mutex object

## ◆ MUTEX_TYPE

#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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
... // some other work to do
MUTEX_CLEANUP(lock);

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

## ◆ MUTEX_UNLOCK

#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"
MUTEX_TYPE lock;
MUTEX_SETUP(lock);
... // some other work to do
MUTEX_LOCK(lock);
... // critical section
MUTEX_UNLOCK(lock);
... // some other work to do
MUTEX_CLEANUP(lock);

Parameters

  mx | #MUTEX_TYPE mutex object

## ◆ THREAD_CANCEL

#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)
{
if (soap_valid_socket(soap_accept(soap)))
{
THREAD_TYPE tid;
struct soap *tsoap = soap_copy(soap);
if (!tsoap)
soap_force_closesock(soap);
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)
{
THREAD_TYPE tid;
struct soap *tsoap;
THREAD_DETACH(THREAD_ID);
// create a new thread that is timed to execute for max 10 seconds
tsoap = soap_copy(soap);
if (!tsoap)
{
soap_force_closesock(soap);
}
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
THREAD_CANCEL(tid);
}
// 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);
}
soap_free
*Finalize and free the given ::soap context from unmanaged heap memory void soap_free(struct soap *soap)
soap_end
*Delete all data from heap memory managed by the specified ::soap context and release the freed memory back to the heap int soap_end(struct soap *soap) * @returns `
soap_print_fault
void soap_print_fault(struct soap *soap, FILE *fd)
Print error message on the specified output.
soap_serve
*Bind and listen to a port SOAP_SOCKET soap_bind *(struct soap *soap, const char *host, int port, int backlog) * @returns the ` Accept a connection with a client SOAP_SOCKET soap_accept *(struct soap *soap) * @returns the ` Serve a pending request in soap_serve)(struct soap *soap) * @returns `
Definition stdsoap2.h:7466
soap_valid_socket
#define soap_valid_socket(sock)
Function macro to check if a socket is valid, i.e. not equal to #SOAP_INVALID_SOCKET.
Definition stdsoap2.h:1354
THREAD_TYPE
#define THREAD_TYPE
Type of a thread (thread ID).
Definition stdsoap2.h:10769
THREAD_DETACH
#define THREAD_DETACH(tid)
Detach a thread.
Definition stdsoap2.h:10845
THREAD_ID
#define THREAD_ID
The thread ID of self.
Definition stdsoap2.h:10777
THREAD_CANCEL
#define THREAD_CANCEL(tid)
Cancel a thread.
Definition stdsoap2.h:10964
THREAD_CREATE
#define THREAD_CREATE(tidptr, funcptr, argptr)
Create a new thread.
Definition stdsoap2.h:10816
soap
Context with the engine state.
Definition stdsoap2.h:2929
soap::errnum
int errnum
The errno value of the last failed IO operation.
Definition stdsoap2.h:3052
soap::recv_maxlength
ULONG64 recv_maxlength
User-definable maximum message length that is permitted to be received, zero means unlimited (the val...
Definition stdsoap2.h:3267
soap::bind_flags
int bind_flags
User-definable setsockopt level SOL_SOCKET flags when binding soap::master socket (the value is 0 by ...
Definition stdsoap2.h:3516
soap::send_timeout
int send_timeout
User-definable timeout to send a packet of data, positive timeout values are seconds,...
Definition stdsoap2.h:3309
soap::accept_timeout
int accept_timeout
User-definable timeout when waiting to accept a request from a client at the server-side with soap_ac...
Definition stdsoap2.h:3351
soap::transfer_timeout
int transfer_timeout
User-definable timeout to send or receive an entire message, positive timeout values are seconds,...
Definition stdsoap2.h:3281

Parameters

  tid | #THREAD_TYPE thread ID to cancel

## ◆ THREAD_CLOSE

#define THREAD_CLOSE | ( |  | tid | ) |

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

## ◆ THREAD_CREATE

#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"
  THREAD_TYPE tid;
  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
  THREAD_CREATEX
  #define THREAD_CREATEX(tidptr, funcptr, argptr)
  Create a new joinable thread (Windows only).
  Definition stdsoap2.h:10822
  THREAD_CLOSE
  #define THREAD_CLOSE(tid)
  Close the thread ID handle created by #THREAD_CREATEX (Windows only).
  Definition stdsoap2.h:10825
  THREAD_JOIN
  #define THREAD_JOIN(tid)
  Join a thread.
  Definition stdsoap2.h:10857

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_TYPE tid;
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

  tidptr | pointer to #THREAD_TYPE thread ID to assign
  funcptr | function to run by the new thread
  argptr | the argument (a pointer) to pass to the function when called

Returns
  zero on success and nonzero on failure

## ◆ THREAD_CREATEX

#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.

## ◆ THREAD_DETACH

#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

  tid | #THREAD_TYPE thread ID to detach

## ◆ THREAD_EXIT

#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.

## ◆ THREAD_ID

#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.

## ◆ THREAD_JOIN

#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

  tid | #THREAD_TYPE thread ID to join

## ◆ THREAD_TYPE

#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:

THREAD_TYPE tid;
while (THREAD_CREATE(&tid, (void*(*)(void*))&process_request, (void*)tsoap)))
sleep(1); // failed, try again