Skip to content

Commit

Permalink
multi-thread: Add in thread safe support
Browse files Browse the repository at this point in the history
Optional compile time thread safe code supported.

Locking is done at the coap_context_t level, and if enabled is primarily
done coap_threadsafe.c and coap_threadsafe_internal.h.

coap_threadsafe_internal.h causes coap_X() to get mapped to coap_X_locked()
throughout the libcoap library code with the exception of coap_threadsafe.c
if thread safe is enabled.
  • Loading branch information
mrdeep1 committed Nov 25, 2023
1 parent 6b4fac9 commit c69c5d5
Show file tree
Hide file tree
Showing 50 changed files with 1,998 additions and 130 deletions.
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,14 @@ option(
WITH_EPOLL
"compile with epoll support"
ON)
option(
ENABLE_THREAD_SAFE
"enable building with thread safe support"
ON)
option(
ENABLE_THREAD_RECURSIVE_LOCK_CHECK
"enable building with thread recursive lock detection"
OFF)
option(
ENABLE_SMALL_STACK
"enable if the system has small stack size"
Expand Down Expand Up @@ -376,6 +384,16 @@ else()
message(STATUS "compiling without epoll support")
endif()

if(ENABLE_THREAD_SAFE)
set(COAP_THREAD_SAFE "${ENABLE_THREAD_SAFE}")
message(STATUS "compiling with thread safe support")
endif()

if(ENABLE_THREAD_RECURSIVE_LOCK_CHECK)
set(COAP_THREAD_RECURSIVE_CHECK "${ENABLE_THREAD_DEADLOCK_CHECK}")
message(STATUS "compiling with thread recursive lock detection support")
endif()

if(ENABLE_SMALL_STACK)
set(COAP_CONSTRAINED_STACK "${ENABLE_SMALL_STACK}")
message(STATUS "compiling with small stack support")
Expand Down Expand Up @@ -608,6 +626,8 @@ message(STATUS "ENABLE_CLIENT_MODE:..............${ENABLE_CLIENT_MODE}")
message(STATUS "ENABLE_SERVER_MODE:..............${ENABLE_SERVER_MODE}")
message(STATUS "ENABLE_OSCORE:...................${ENABLE_OSCORE}")
message(STATUS "ENABLE_ASYNC:....................${ENABLE_ASYNC}")
message(STATUS "ENABLE_THREAD_SAFE:..............${ENABLE_THREAD_SAFE}")
message(STATUS "ENABLE_THREAD_RECURSIVE_CHECK....${ENABLE_THREAD_RECURSIVE_LOCK_DETECTION}")
message(STATUS "ENABLE_DOCS:.....................${ENABLE_DOCS}")
message(STATUS "ENABLE_EXAMPLES:.................${ENABLE_EXAMPLES}")
message(STATUS "DTLS_BACKEND:....................${DTLS_BACKEND}")
Expand Down Expand Up @@ -682,6 +702,7 @@ target_sources(
${CMAKE_CURRENT_LIST_DIR}/src/coap_str.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_subscribe.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_tcp.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_threadsafe.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_time.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_uri.c
${CMAKE_CURRENT_LIST_DIR}/src/coap_ws.c
Expand Down
2 changes: 2 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ EXTRA_DIST = \
include/coap$(LIBCOAP_API_VERSION)/coap_sha1_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_subscribe_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_tcp_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_threadsafe_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_uri_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_uthash_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_utlist_internal.h \
Expand Down Expand Up @@ -214,6 +215,7 @@ libcoap_@LIBCOAP_NAME_SUFFIX@_la_SOURCES = \
src/coap_str.c \
src/coap_subscribe.c \
src/coap_tcp.c \
src/coap_threadsafe.c \
src/coap_time.c \
src/coap_tinydtls.c \
src/coap_uri.c \
Expand Down
6 changes: 6 additions & 0 deletions cmake_coap_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@
/* Define to 1 if the library has async separate response support. */
#cmakedefine COAP_ASYNC_SUPPORT @COAP_ASYNC_SUPPORT@

/* Define to 1 if the library has thread safe support. */
#cmakedefine COAP_THREAD_SAFE @COAP_THREAD_SAFE@

/* Define to 1 if the library has thread deadlock detection support. */
#cmakedefine COAP_THREAD_RECURSIVE_CHECK @COAP_THREAD_RECURSIVE_CHECK@

/* Define to 0-8 for maximum logging level. */
#cmakedefine COAP_MAX_LOGGING_LEVEL @COAP_MAX_LOGGING_LEVEL@

Expand Down
6 changes: 6 additions & 0 deletions coap_config.h.contiki
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
/* Define to 1 to build with Q-Block (RFC9177) support. */
/* #undef COAP_Q_BLOCK_SUPPORT 1 */

/* Define to 1 to build with thread recursive lock detection support. */
/* #undef COAP_THREAD_RECURSIVE_CHECK 1 */

/* Define to 1 if libcoap has thread safe support. */
/* #undef COAP_THREAD_SAFE 1 */

/* Define to 1 if you have the <assert.h> header file. */
#define HAVE_ASSERT_H 1

Expand Down
14 changes: 14 additions & 0 deletions coap_config.h.riot
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@
#endif /* COAP_ASYNC_SUPPORT */
#endif /* CONFIG_LIBCOAP_ASYNC_SUPPORT */

#ifdef CONFIG_LIBCOAP_THREAD_SAFE
#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 1
#endif /* COAP_THREAD_SAFE */
#endif /* CONFIG_LIBCOAP_THREAD_SAFE */

#ifdef CONFIG_LIBCOAP_THREAD_RECURSIVE_CHECK
#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 1
#endif /* COAP_THREAD_RECURSIVE_CHECK */
#endif /* CONFIG_LIBCOAP_THREAD_RECURSIVE_CHECK */

#ifdef CONFIG_LIBCOAP_MAX_STRING_SIZE
#ifndef COAP_MAX_STRING_SIZE
#define COAP_MAX_STRING_SIZE CONFIG_LIBCOAP_MAX_STRING_SIZE
Expand Down
14 changes: 14 additions & 0 deletions coap_config.h.riot.in
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,20 @@
#endif /* COAP_ASYNC_SUPPORT */
#endif /* CONFIG_LIBCOAP_ASYNC_SUPPORT */

#ifdef CONFIG_LIBCOAP_THREAD_SAFE
#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 1
#endif /* COAP_THREAD_SAFE */
#endif /* CONFIG_LIBCOAP_THREAD_SAFE */

#ifdef CONFIG_LIBCOAP_THREAD_RECURSIVE_CHECK
#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 1
#endif /* COAP_THREAD_RECURSIVE_CHECK */
#endif /* CONFIG_LIBCOAP_THREAD_RECURSIVE_CHECK */

#ifdef CONFIG_LIBCOAP_MAX_STRING_SIZE
#ifndef COAP_MAX_STRING_SIZE
#define COAP_MAX_STRING_SIZE CONFIG_LIBCOAP_MAX_STRING_SIZE
Expand Down
10 changes: 10 additions & 0 deletions coap_config.h.windows
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@
#define COAP_ASYNC_SUPPORT 1
#endif

#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 0
#endif

#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 0
#endif

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "[email protected]"

Expand Down
10 changes: 10 additions & 0 deletions coap_config.h.windows.in
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@
#define COAP_ASYNC_SUPPORT 1
#endif

#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 0
#endif

#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 0
#endif

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@"

Expand Down
23 changes: 23 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -966,6 +966,26 @@ if test "x$with_epoll" = "xyes"; then
AC_DEFINE(COAP_EPOLL_SUPPORT, 1, [Define to 1 if the system has epoll support.])
fi

AC_ARG_ENABLE([thread-safe],
[AS_HELP_STRING([--enable-thread-safe],
[Enable building with thread safe support [default=yes]])],
[enable_thread_safe="$enableval"],
[enable_thread_safe="yes"])

if test "x$enable_thread_safe" = "xyes"; then
AC_DEFINE(COAP_THREAD_SAFE, 1, [Define to 1 if libcoap has thread safe support])
fi

AC_ARG_ENABLE([thread-recursive-lock-detection],
[AS_HELP_STRING([--enable-thread-recursive-lock-detection],
[Enable building with thread recursive locking detection support [default=yes]])],
[enable_recursive_detection="$enableval"],
[enable_recursive_detection="yes"])

if test "x$enable_recursive_detection" = "xyes"; then
AC_DEFINE(COAP_THREAD_RECURSIVE_CHECK, 1, [Define to 1 detect recursive locking detection support])
fi

AC_ARG_ENABLE([small-stack],
[AS_HELP_STRING([--enable-small-stack],
[Use small-stack if the available stack space is restricted [default=no]])],
Expand Down Expand Up @@ -1144,6 +1164,7 @@ man/coap_handler.txt
man/coap_init.txt
man/coap_io.txt
man/coap_keepalive.txt
man/coap_locking.txt
man/coap_logging.txt
man/coap_lwip.txt
man/coap_observe.txt
Expand Down Expand Up @@ -1280,6 +1301,8 @@ if test "x$enable_max_logging_level" != "x8"; then
else
AC_MSG_RESULT([ enable max logging level : "none"])
fi
AC_MSG_RESULT([ enable thread safe code : "$enable_thread_safe"])
AC_MSG_RESULT([ enable recursive lock chk: "$enable_recursive_detection"])
if test "x$build_doxygen" = "xyes"; then
AC_MSG_RESULT([ build doxygen pages : "yes"])
AC_MSG_RESULT([ --> Doxygen around : "yes" ($DOXYGEN $doxygen_version)])
Expand Down
1 change: 1 addition & 0 deletions examples/lwip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ COAP_SRC = coap_address.c \
coap_str.c \
coap_subscribe.c \
coap_tcp.c \
coap_threadsafe.c \
coap_tinydtls.c \
coap_uri.c \
coap_ws.c
Expand Down
12 changes: 12 additions & 0 deletions examples/lwip/client-coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@
*/

#include "coap_config.h"

#if COAP_THREAD_SAFE
/*
* Unfortunately, this needs to be set so that locking mapping of coap_
* functions does not take place in this file. coap.h includes coap_mem.h which
* includes lwip headers (lwippools.h) which includes coap_internal.h which
* includes coap_threadsafe_internal.h which does the mapping unless
* COAP_THREAD_IGNORE_LOCKED_MAPPING is set.
*/
#define COAP_THREAD_IGNORE_LOCKED_MAPPING
#endif

#include <coap3/coap.h>
#include <sys/types.h>
#include <sys/socket.h>
Expand Down
10 changes: 10 additions & 0 deletions examples/lwip/config/coap_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@
#define COAP_Q_BLOCK_SUPPORT 0
#endif

#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 0
#endif

#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 0
#endif

#ifndef PACKAGE_NAME
#define PACKAGE_NAME "libcoap"
#endif /* PACKAGE_NAME */
Expand Down
10 changes: 10 additions & 0 deletions examples/lwip/config/coap_config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,16 @@
#define COAP_Q_BLOCK_SUPPORT 0
#endif

#ifndef COAP_THREAD_SAFE
/* Define to 1 if libcoap has thread safe support. */
#define COAP_THREAD_SAFE 0
#endif

#ifndef COAP_THREAD_RECURSIVE_CHECK
/* Define to 1 to build with thread recursive lock detection support. */
#define COAP_THREAD_RECURSIVE_CHECK 0
#endif

#ifndef PACKAGE_NAME
#define PACKAGE_NAME "@PACKAGE_NAME@"
#endif /* PACKAGE_NAME */
Expand Down
3 changes: 3 additions & 0 deletions examples/lwip/config/lwipopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#if NO_SYS
#define LOCK_TCPIP_CORE()
#define UNLOCK_TCPIP_CORE()
#else
#define COAP_THREAD_SAFE 1
#define COAP_THREAD_RECURSIVE_CHECK 0
#endif

#define MEMP_NUM_SYS_TIMEOUT 10
Expand Down
15 changes: 13 additions & 2 deletions examples/lwip/server-coap.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@
*/

#include "coap_config.h"

#if COAP_THREAD_SAFE
/*
* Unfortunately, this needs to be set so that locking mapping of coap_
* functions does not take place in this file. coap.h includes coap_mem.h which
* includes lwip headers (lwippools.h) which includes coap_internal.h which
* includes coap_threadsafe_internal.h which does the mapping unless
* COAP_THREAD_IGNORE_LOCKED_MAPPING is set.
*/
#define COAP_THREAD_IGNORE_LOCKED_MAPPING
#endif

#include <coap3/coap.h>
#include "server-coap.h"

Expand Down Expand Up @@ -41,8 +53,7 @@ hnd_get_time(coap_resource_t *resource, coap_session_t *session,
* when query ?ticks is given. */

/* if my_clock_base was deleted, we pretend to have no such resource */
response->code =
my_clock_base ? COAP_RESPONSE_CODE(205) : COAP_RESPONSE_CODE(404);
coap_pdu_set_code(response, my_clock_base ? COAP_RESPONSE_CODE(205) : COAP_RESPONSE_CODE(404));

if (my_clock_base)
coap_add_option(response, COAP_OPTION_CONTENT_FORMAT,
Expand Down
11 changes: 7 additions & 4 deletions examples/lwip/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@
static ip4_addr_t ipaddr, netmask, gw;
#endif /* LWIP_IPV4 */

static int quit = 0;

void
handle_sigint(int signum) {
(void)signum;

server_coap_finished();
printf("Server Application finished.\n");
exit(0);
quit = 1;
}

/*
Expand Down Expand Up @@ -132,7 +132,7 @@ main(int argc, char **argv) {

printf("Server Application started.\n");

while (1) {
while (!quit) {
/*
* Poll netif, pass any read packet to lwIP
* Has internal timeout of 100 msec (sometimes less) based on
Expand All @@ -144,6 +144,9 @@ main(int argc, char **argv) {

server_coap_poll();
}
server_coap_finished();
printf("Server Application finished.\n");
exit(0);

return 0;
}
17 changes: 17 additions & 0 deletions examples/riot/pkg_libcoap/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,23 @@ config LIBCOAP_ASYNC_SUPPORT

If this option is disabled, redundent CoAP async separate responses code is removed.

config LIBCOAP_THREAD_SAFE
bool "Enable thread safe support within CoAP"
default n
help
Enable thread safe support within CoAP.

If this option is disabled, libcoap is not thread safe,

config LIBCOAP_THREAD_RECURSIVE_CHECK
bool "Enable thread recursive lock detection if thread safe support is enabled"
depends on LIBCOAP_THREAD_SAFE
default n
help
Enable thread recursive lock detection if thread safe support is enabled.

If this option is disabled, there is no multi thread recursive detection.

config LIBCOAP_CLIENT_SUPPORT
bool "Enable Client functionality within CoAP"
default n
Expand Down
1 change: 1 addition & 0 deletions examples/riot/pkg_libcoap/Makefile.libcoap
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SRC := coap_address.c \
coap_str.c \
coap_subscribe.c \
coap_tcp.c \
coap_threadsafe.c \
coap_tinydtls.c \
coap_uri.c \
coap_ws.c
Expand Down
1 change: 1 addition & 0 deletions include/coap3/coap_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ typedef struct oscore_ctx_t oscore_ctx_t;
#include "coap_sha1_internal.h"
#include "coap_subscribe_internal.h"
#include "coap_tcp_internal.h"
#include "coap_threadsafe_internal.h"
#include "coap_uri_internal.h"
#include "coap_utlist_internal.h"
#include "coap_uthash_internal.h"
Expand Down
Loading

0 comments on commit c69c5d5

Please sign in to comment.