Loading...
Searching...
No Matches
coap_threadsafe.c
Go to the documentation of this file.
/* coap_threadsafe.c -- Thread safe function locking wrappers
*
* Copyright (C) 2023-2024 Jon Shallow <supjps-libcoap@jpshallow.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see
* README for terms of use.
*/
#include "coap3/coap_libcoap_build.h"
#if COAP_THREAD_SAFE
#if COAP_THREAD_RECURSIVE_CHECK
void
coap_lock_unlock_func(const char *file, int line) {
assert(coap_thread_pid == global_lock.pid);
if (global_lock.in_callback) {
assert(global_lock.lock_count > 0);
global_lock.lock_count--;
} else {
global_lock.pid = 0;
global_lock.unlock_file = file;
global_lock.unlock_line = line;
coap_mutex_unlock(&global_lock.mutex);
}
}
int
coap_lock_lock_func(const char *file, int line) {
if (!coap_started) {
/* libcoap not initialized with coap_startup() */
return 0;
}
if (coap_mutex_trylock(&global_lock.mutex)) {
if (coap_thread_pid == global_lock.pid) {
/* This thread locked the mutex */
if (global_lock.in_callback) {
/* This is called from within an app callback */
global_lock.lock_count++;
assert(global_lock.in_callback == global_lock.lock_count);
return 1;
} else {
coap_log_alert("Thread Deadlock: Last %s: %u, this %s: %u\n",
global_lock.lock_file, global_lock.lock_line, file, line);
assert(0);
}
}
/* Wait for the other thread to unlock */
coap_mutex_lock(&global_lock.mutex);
}
/* Just got the lock, so should not be in a locked callback */
assert(!global_lock.in_callback);
global_lock.pid = coap_thread_pid;
global_lock.lock_file = file;
global_lock.lock_line = line;
return 1;
}
#else /* ! COAP_THREAD_RECURSIVE_CHECK */
void
coap_lock_unlock_func(void) {
assert(coap_thread_pid == global_lock.pid);
if (global_lock.in_callback) {
assert(global_lock.lock_count > 0);
global_lock.lock_count--;
} else {
global_lock.pid = 0;
coap_mutex_unlock(&global_lock.mutex);
}
}
int
coap_lock_lock_func(void) {
if (!coap_started) {
/* libcoap not initialized with coap_startup() */
return 0;
}
/*
* Some OS do not have support for coap_mutex_trylock() so
* cannot use that here and have to rely on lock-pid being stable
*/
if (global_lock.in_callback && coap_thread_pid == global_lock.pid) {
global_lock.lock_count++;
assert(global_lock.in_callback == global_lock.lock_count);
return 1;
}
coap_mutex_lock(&global_lock.mutex);
/* Just got the lock, so should not be in a locked callback */
assert(!global_lock.in_callback);
global_lock.pid = coap_thread_pid;
return 1;
}
#endif /* ! COAP_THREAD_RECURSIVE_CHECK */
#else /* ! COAP_THREAD_SAFE */
#ifdef __clang__
/* Make compilers happy that do not like empty modules. As this function is
* never used, we ignore -Wunused-function at the end of compiling this file
*/
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
static inline void
dummy(void) {
}
#endif /* ! COAP_THREAD_SAFE */
coap_libcoap_build.h
Library specific build wrapper for coap_internal.h.
coap_thread_pid
#define coap_thread_pid
Definition coap_mutex_internal.h:149
coap_mutex_unlock
#define coap_mutex_unlock(a)
Definition coap_mutex_internal.h:147
coap_mutex_trylock
#define coap_mutex_trylock(a)
Definition coap_mutex_internal.h:146
coap_mutex_lock
#define coap_mutex_lock(a)
Definition coap_mutex_internal.h:145
coap_started
int coap_started
Definition coap_net.c:4439
dummy
static void dummy(void)
Definition coap_threadsafe.c:111
coap_log_alert
#define coap_log_alert(...)
Definition coap_debug.h:84