diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index 6e04e8fa..023f9b46 100755 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -602,4 +602,9 @@ config LWIP_SNTP_DEBUG depends on LWIP_DEBUG default n +config LWIP_THREAD_SAFE_DEBUG + bool "Enable debugging for LWIP thread safety." + depends on LWIP_DEBUG + default n + endmenu diff --git a/components/lwip/include/lwip/port/arch/sys_arch.h b/components/lwip/include/lwip/port/arch/sys_arch.h index d132c1cf..b88535a6 100644 --- a/components/lwip/include/lwip/port/arch/sys_arch.h +++ b/components/lwip/include/lwip/port/arch/sys_arch.h @@ -50,5 +50,16 @@ typedef xTaskHandle sys_thread_t; #define LWIP_COMPAT_MUTEX 0 +#if LWIP_NETCONN_SEM_PER_THREAD + +sys_sem_t* sys_thread_sem_init(void); +void sys_thread_sem_deinit(void); +sys_sem_t* sys_thread_sem_get(void); + +#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_thread_sem_init() +#define LWIP_NETCONN_THREAD_SEM_FREE() sys_thread_sem_deinit() +#define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem_get() +#endif + #endif /* __SYS_ARCH_H__ */ diff --git a/components/lwip/include/lwip/port/lwipopts.h b/components/lwip/include/lwip/port/lwipopts.h index 1c1bc6b6..62b12bcc 100644 --- a/components/lwip/include/lwip/port/lwipopts.h +++ b/components/lwip/include/lwip/port/lwipopts.h @@ -1313,7 +1313,7 @@ extern void vPortFree(void *pv, const char * file, unsigned line); * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). * Ports may call these for threads created with sys_thread_new(). */ -#define LWIP_NETCONN_SEM_PER_THREAD 0 +#define LWIP_NETCONN_SEM_PER_THREAD 1 /** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, * writing from a 2nd thread and closing from a 3rd thread at the same time. @@ -2146,6 +2146,12 @@ extern void vPortFree(void *pv, const char * file, unsigned line); #define SNTP_DEBUG LWIP_DBG_ON #endif +#ifdef CONFIG_LWIP_THREAD_SAFE_DEBUG +#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_ON +#else +#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF +#endif + /** * @} */ diff --git a/components/lwip/port/freertos/sys_arch.c b/components/lwip/port/freertos/sys_arch.c index 44404c5d..a238cb6c 100644 --- a/components/lwip/port/freertos/sys_arch.c +++ b/components/lwip/port/freertos/sys_arch.c @@ -38,6 +38,7 @@ #include "lwip/mem.h" #include "arch/sys_arch.h" +#define LWIP_THREAD_TLS 0 /* Message queue constants. */ #define archMESG_QUEUE_LENGTH (100)//( 6 ) @@ -424,3 +425,69 @@ sys_arch_msleep(int ms) vTaskDelay(ms / portTICK_RATE_MS); } +#if LWIP_NETCONN_SEM_PER_THREAD + +static void sys_thread_sem_free(int index, void *data) // destructor for TLS semaphore +{ + sys_sem_t *sem = (sys_sem_t *)(data); + + if (sem && *sem){ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem del, sem=%p\n", *sem)); + vSemaphoreDelete(*sem); + } + + if (sem) { + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem pointer del, sem_p=%p\n", sem)); + free(sem); + } +} + +/* + * get per thread semphore + */ +sys_sem_t* sys_thread_sem_init(void) +{ + sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*)); + + if (!sem){ + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, "thread_sem_init: out of memory\n"); + return 0; + } + + *sem = xSemaphoreCreateBinary(); + if (!(*sem)){ + free(sem); + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, "thread_sem_init: out of memory\n"); + return 0; + } + + vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, LWIP_THREAD_TLS, sem, sys_thread_sem_free); + + return sem; +} + +/* + * get per thread semphore + */ +sys_sem_t* sys_thread_sem_get(void) +{ + sys_sem_t *sem = pvTaskGetThreadLocalStoragePointer(NULL, LWIP_THREAD_TLS); + + if (!sem) { + sem = sys_thread_sem_init(); + } + LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sem_get s=%p\n", sem)); + + return sem; +} + +void sys_thread_sem_deinit(void) +{ + sys_sem_t *sem = pvTaskGetThreadLocalStoragePointer(NULL, LWIP_THREAD_TLS); + if (sem != NULL) { + sys_thread_sem_free(LWIP_THREAD_TLS, sem); + vTaskSetThreadLocalStoragePointerAndDelCallback(NULL, LWIP_THREAD_TLS, NULL, NULL); + } +} + +#endif