mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 04:04:31 +02:00
Merge branch 'bugfix/pthread_detach' into 'master'
Bugfix in pthread_detach() implementation See merge request idf/esp-idf!4038
This commit is contained in:
@@ -395,8 +395,19 @@ int pthread_detach(pthread_t thread)
|
|||||||
TaskHandle_t handle = pthread_find_handle(thread);
|
TaskHandle_t handle = pthread_find_handle(thread);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
ret = ESRCH;
|
ret = ESRCH;
|
||||||
} else {
|
} else if (pthread->detached) {
|
||||||
|
// already detached
|
||||||
|
ret = EINVAL;
|
||||||
|
} else if (pthread->join_task) {
|
||||||
|
// already have waiting task to join
|
||||||
|
ret = EINVAL;
|
||||||
|
} else if (pthread->state == PTHREAD_TASK_STATE_RUN) {
|
||||||
|
// pthread still running
|
||||||
pthread->detached = true;
|
pthread->detached = true;
|
||||||
|
} else {
|
||||||
|
// pthread already stopped
|
||||||
|
pthread_delete(pthread);
|
||||||
|
vTaskDelete(handle);
|
||||||
}
|
}
|
||||||
xSemaphoreGive(s_threads_mux);
|
xSemaphoreGive(s_threads_mux);
|
||||||
ESP_LOGV(TAG, "%s %p EXIT %d", __FUNCTION__, pthread, ret);
|
ESP_LOGV(TAG, "%s %p EXIT %d", __FUNCTION__, pthread, ret);
|
||||||
|
@@ -60,6 +60,75 @@ TEST_CASE("pthread create join", "[pthread]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *waiting_thread(void *arg)
|
||||||
|
{
|
||||||
|
TaskHandle_t *task_handle = (TaskHandle_t *)arg;
|
||||||
|
TaskHandle_t parent_task = *task_handle;
|
||||||
|
|
||||||
|
*task_handle = xTaskGetCurrentTaskHandle();
|
||||||
|
|
||||||
|
xTaskNotify(parent_task, 0, eNoAction);
|
||||||
|
xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("pthread detach", "[pthread]")
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
pthread_t new_thread = (pthread_t)NULL;
|
||||||
|
TaskHandle_t task_handle = NULL;
|
||||||
|
const int task_count = uxTaskGetNumberOfTasks();
|
||||||
|
bool detach_works = false;
|
||||||
|
|
||||||
|
if (TEST_PROTECT()) {
|
||||||
|
task_handle = xTaskGetCurrentTaskHandle();
|
||||||
|
res = pthread_create(&new_thread, NULL, waiting_thread, (void *)&task_handle);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, res);
|
||||||
|
|
||||||
|
res = xTaskNotifyWait(0, 0, NULL, 100 / portTICK_PERIOD_MS);
|
||||||
|
TEST_ASSERT_EQUAL_INT(pdTRUE, res);
|
||||||
|
|
||||||
|
xTaskNotify(task_handle, 0, eNoAction);
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
res = pthread_detach(new_thread);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, res);
|
||||||
|
|
||||||
|
res = uxTaskGetNumberOfTasks();
|
||||||
|
TEST_ASSERT_EQUAL_INT(task_count, res);
|
||||||
|
detach_works = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!detach_works) {
|
||||||
|
vTaskDelete(task_handle);
|
||||||
|
} else {
|
||||||
|
detach_works = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TEST_PROTECT()) {
|
||||||
|
task_handle = xTaskGetCurrentTaskHandle();
|
||||||
|
res = pthread_create(&new_thread, NULL, waiting_thread, (void *)&task_handle);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, res);
|
||||||
|
|
||||||
|
res = xTaskNotifyWait(0, 0, NULL, 100 / portTICK_PERIOD_MS);
|
||||||
|
TEST_ASSERT_EQUAL_INT(pdTRUE, res);
|
||||||
|
|
||||||
|
res = pthread_detach(new_thread);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, res);
|
||||||
|
|
||||||
|
xTaskNotify(task_handle, 0, eNoAction);
|
||||||
|
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
res = uxTaskGetNumberOfTasks();
|
||||||
|
TEST_ASSERT_EQUAL_INT(task_count, res);
|
||||||
|
detach_works = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!detach_works) {
|
||||||
|
vTaskDelete(task_handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("pthread attr init destroy", "[pthread]")
|
TEST_CASE("pthread attr init destroy", "[pthread]")
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
Reference in New Issue
Block a user