19#if COAP_THREAD_RECURSIVE_CHECK
21coap_lock_unlock_func(
coap_lock_t *lock,
const char *file,
int line) {
23 if (lock->in_callback) {
24 assert(lock->lock_count > 0);
28 lock->unlock_file = file;
29 lock->unlock_line = line;
35coap_lock_lock_func(
coap_lock_t *lock,
const char *file,
int line) {
43 if (lock->in_callback) {
46 assert(lock->in_callback == lock->lock_count);
50 lock->lock_file, lock->lock_line, file, line);
58 assert(!lock->in_callback);
60 lock->lock_file = file;
61 lock->lock_line = line;
70 if (lock->in_callback) {
71 assert(lock->lock_count > 0);
91 assert(lock->in_callback == lock->lock_count);
96 assert(!lock->in_callback);
108uint32_t max_thread_no = 0;
113} coap_thread_param_t;
116coap_io_process_worker_thread(
void *arg) {
117 coap_thread_param_t *thread_param = (coap_thread_param_t *)arg;
119#if (COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_DEBUG)
123 thread_no = thread_param->thread_no;
146#if defined(HAVE_SIGNAL_H) || defined(__ZEPHYR__)
151typedef void (*coap_sig_handler_t)(int);
153static coap_sig_handler_t old_sigint_handler = SIG_IGN;
156coap_thread_sigint_handler(
int signum) {
158 if (old_sigint_handler != SIG_IGN && old_sigint_handler != SIG_DFL) {
159 old_sigint_handler(signum);
164typedef void (*coap_sig_action_t)(int, siginfo_t *,
void *);
165static coap_sig_action_t old_sigint_action =
NULL;
168coap_thread_sigint_action(
int signum, siginfo_t *siginfo,
void *ptr) {
170 if (old_sigint_action !=
NULL) {
171 old_sigint_action(signum, siginfo, ptr);
182 for (i = 0; i < context->thread_id_count ; i++) {
183 int s = pthread_kill(context->thread_id[i], COAP_THREAD_KILL_SIG);
193 for (i = 0; i < context->thread_id_count ; i++) {
195 int s = pthread_join(context->thread_id[i], &retval);
202 context->thread_id =
NULL;
203 context->thread_id_count = 0;
209 uint32_t base_thread;
211 if (thread_count == 0)
216 if (thread_no == 0) {
217 thread_no = ++max_thread_no;
220 old_sigint_handler = signal(COAP_THREAD_KILL_SIG, coap_thread_sigint_handler);
222 struct sigaction oldact;
223 struct sigaction newact;
226 if (sigaction(COAP_THREAD_KILL_SIG,
NULL, &oldact) != -1) {
227 if (oldact.sa_flags & SA_SIGINFO) {
228 if (oldact.sa_sigaction != coap_thread_sigint_action) {
229 memset(&newact, 0,
sizeof(newact));
230 sigemptyset(&newact.sa_mask);
231 newact.sa_sigaction = coap_thread_sigint_action;
232 newact.sa_flags = SA_SIGINFO;
233 if (sigaction(COAP_THREAD_KILL_SIG, &newact, &oldact) != -1) {
234 old_sigint_action = oldact.sa_sigaction;
238 if (oldact.sa_handler != coap_thread_sigint_handler) {
239 memset(&newact, 0,
sizeof(newact));
240 sigemptyset(&newact.sa_mask);
241 newact.sa_handler = coap_thread_sigint_handler;
243 if (sigaction(COAP_THREAD_KILL_SIG, &newact, &oldact) != -1) {
244 old_sigint_handler = oldact.sa_handler;
251 if (context->thread_id_count) {
252 coap_io_process_kill_threads(context);
255 base_thread = max_thread_no + 1;
256 max_thread_no = base_thread + thread_count - 1;
258 if (!context->thread_id) {
259 coap_log_err(
"thread start up memory allocate failure\n");
263 for (i = 0; i < thread_count ; i++) {
267 thread_param->context = context;
268 thread_param->thread_no = i + base_thread;
269 s = pthread_create(&context->thread_id[i],
NULL,
270 &coap_io_process_worker_thread, thread_param);
276 context->thread_id_count++;
294 if (thread_no == 0) {
295 thread_no = ++max_thread_no;
298 if (context->thread_id_count) {
299 coap_io_process_kill_threads(context);
const char * coap_socket_strerror(void)
COAP_THREAD_LOCAL_VAR volatile int coap_thread_quit
Library specific build wrapper for coap_internal.h.
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
#define coap_mutex_unlock(a)
#define coap_mutex_trylock(a)
#define coap_mutex_lock(a)
void coap_io_process_remove_threads_lkd(coap_context_t *context)
Release the coap_io_process() worker threads.
int coap_io_process_lkd(coap_context_t *ctx, uint32_t timeout_ms)
The main I/O processing function.
int coap_io_process_configure_threads(coap_context_t *context, uint32_t thread_count)
Configure a defined number of threads to do the alternate coap_io_process() work with traffic load ba...
void coap_io_process_remove_threads(coap_context_t *context)
Release the coap_io_process() worker threads.
void coap_send_recv_terminate(void)
Terminate any active coap_send_recv() sessions.
void coap_dtls_thread_shutdown(void)
Close down the underlying (D)TLS Library layer.
#define coap_lock_unlock()
Dummy for no thread-safe code.
#define coap_lock_lock(failed)
Dummy for no thread-safe code.
#define coap_log_debug(...)
#define coap_log_alert(...)
#define coap_log_err(...)
#define COAP_THREAD_LOCAL_VAR
The CoAP stack's global state is stored in a coap_context_t object.