mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(ble): Fixed AI review bugs in bt common
This commit is contained in:
@@ -323,9 +323,20 @@ bool osi_alarm_is_active(osi_alarm_t *alarm)
|
||||
{
|
||||
assert(alarm != NULL);
|
||||
|
||||
if (alarm->alarm_hdl != NULL) {
|
||||
return esp_timer_is_active(alarm->alarm_hdl);
|
||||
assert(alarm_mutex != NULL);
|
||||
|
||||
bool active = false;
|
||||
osi_mutex_lock(&alarm_mutex, OSI_MUTEX_MAX_TIMEOUT);
|
||||
if (alarm_state != ALARM_STATE_OPEN) {
|
||||
active = false;
|
||||
goto end;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (alarm->alarm_hdl != NULL) {
|
||||
active = esp_timer_is_active(alarm->alarm_hdl);
|
||||
}
|
||||
|
||||
end:
|
||||
osi_mutex_unlock(&alarm_mutex);
|
||||
return active;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "bt_common.h"
|
||||
#include "esp_assume.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "osi/config.h"
|
||||
#include "osi/list.h"
|
||||
@@ -40,7 +41,7 @@ struct config_t {
|
||||
// Empty definition; this type is aliased to list_node_t.
|
||||
struct config_section_iter_t {};
|
||||
|
||||
static void config_parse(nvs_handle_t fp, config_t *config);
|
||||
static bool config_parse(nvs_handle_t fp, config_t *config);
|
||||
|
||||
static section_t *section_new(const char *name);
|
||||
static void section_free(void *ptr);
|
||||
@@ -94,8 +95,12 @@ config_t *config_new(const char *filename)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config_parse(fp, config);
|
||||
bool ok = config_parse(fp, config);
|
||||
nvs_close(fp);
|
||||
if (!ok) {
|
||||
config_free(config);
|
||||
return NULL;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -136,7 +141,7 @@ bool config_has_key_in_section(config_t *config, const char *key, char *key_valu
|
||||
entry_t *entry = list_node(node);
|
||||
OSI_TRACE_DEBUG("entry->key = %s, entry->value = %s", entry->key, entry->value);
|
||||
if (!strcmp(entry->key, key) && !strcmp(entry->value, key_value)) {
|
||||
OSI_TRACE_DEBUG("%s, the irk aready in the flash.", __func__);
|
||||
OSI_TRACE_DEBUG("%s, the irk already in the flash.", __func__);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -221,6 +226,10 @@ void config_set_string(config_t *config, const char *section, const char *key, c
|
||||
section_t *sec = section_find(config, section);
|
||||
if (!sec) {
|
||||
sec = section_new(section);
|
||||
if (sec == NULL) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate section\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (insert_back) {
|
||||
list_append(config->sections, sec);
|
||||
} else {
|
||||
@@ -231,13 +240,22 @@ void config_set_string(config_t *config, const char *section, const char *key, c
|
||||
for (const list_node_t *node = list_begin(sec->entries); node != list_end(sec->entries); node = list_next(node)) {
|
||||
entry_t *entry = list_node(node);
|
||||
if (!strcmp(entry->key, key)) {
|
||||
char *new_value = osi_strdup(value);
|
||||
if (new_value == NULL) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate entry value\n", __func__);
|
||||
return;
|
||||
}
|
||||
osi_free(entry->value);
|
||||
entry->value = osi_strdup(value);
|
||||
entry->value = new_value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
entry_t *entry = entry_new(key, value);
|
||||
if (entry == NULL) {
|
||||
OSI_TRACE_ERROR("%s unable to allocate entry\n", __func__);
|
||||
return;
|
||||
}
|
||||
list_append(sec->entries, entry);
|
||||
}
|
||||
|
||||
@@ -327,32 +345,57 @@ const char *config_section_name(const config_section_node_t *node)
|
||||
return section->name;
|
||||
}
|
||||
|
||||
static int get_config_size(const config_t *config)
|
||||
static bool get_config_size(const config_t *config, size_t *out_size)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(out_size != NULL);
|
||||
|
||||
int w_len = 0, total_size = 0;
|
||||
size_t total_size = 0;
|
||||
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
const section_t *section = (const section_t *)list_node(node);
|
||||
w_len = strlen(section->name) + strlen("[]\n");// format "[section->name]\n"
|
||||
/* CONTRACT / PRECONDITION:
|
||||
* - section->name is guaranteed non-NULL.
|
||||
* - Upstream guard: section_new() stores osi_strdup(name) from config_set_string().
|
||||
*/
|
||||
ESP_ASSUME_NONNULL(section->name);
|
||||
size_t w_len = strlen(section->name) + strlen("[]\n"); // format "[section->name]\n"
|
||||
if (total_size > SIZE_MAX - w_len) {
|
||||
return false;
|
||||
}
|
||||
total_size += w_len;
|
||||
|
||||
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
|
||||
const entry_t *entry = (const entry_t *)list_node(enode);
|
||||
w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n");// format "entry->key = entry->value\n"
|
||||
/* CONTRACT / PRECONDITION:
|
||||
* - entry->key/value are guaranteed non-NULL.
|
||||
* - Upstream guard: entry_new() stores osi_strdup(key/value) from config_set_string().
|
||||
*/
|
||||
ESP_ASSUME_NONNULL(entry->key);
|
||||
ESP_ASSUME_NONNULL(entry->value);
|
||||
w_len = strlen(entry->key) + strlen(entry->value) + strlen(" = \n"); // format "entry->key = entry->value\n"
|
||||
if (total_size > SIZE_MAX - w_len) {
|
||||
return false;
|
||||
}
|
||||
total_size += w_len;
|
||||
}
|
||||
|
||||
// Only add a separating newline if there are more sections.
|
||||
if (list_next(node) != list_end(config->sections)) {
|
||||
total_size ++; //'\n'
|
||||
if (total_size == SIZE_MAX) {
|
||||
return false;
|
||||
}
|
||||
total_size++; // '\n'
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
total_size ++; //'\0'
|
||||
return total_size;
|
||||
if (total_size == SIZE_MAX) {
|
||||
return false;
|
||||
}
|
||||
total_size++; // '\0'
|
||||
*out_size = total_size;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int get_config_size_from_flash(nvs_handle_t fp)
|
||||
@@ -364,7 +407,7 @@ static int get_config_size_from_flash(nvs_handle_t fp)
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
if (!keyname){
|
||||
OSI_TRACE_ERROR("%s, malloc error\n", __func__);
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
size_t length = CONFIG_FILE_DEFAULE_LENGTH;
|
||||
size_t total_length = 0;
|
||||
@@ -378,7 +421,7 @@ static int get_config_size_from_flash(nvs_handle_t fp)
|
||||
if (err != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s, error %d\n", __func__, err);
|
||||
osi_free(keyname);
|
||||
return 0;
|
||||
return -2;
|
||||
}
|
||||
total_length += length;
|
||||
while (length == CONFIG_FILE_MAX_SIZE) {
|
||||
@@ -392,7 +435,7 @@ static int get_config_size_from_flash(nvs_handle_t fp)
|
||||
if (err != ESP_OK) {
|
||||
OSI_TRACE_ERROR("%s, error %d\n", __func__, err);
|
||||
osi_free(keyname);
|
||||
return 0;
|
||||
return -3;
|
||||
}
|
||||
total_length += length;
|
||||
}
|
||||
@@ -409,12 +452,21 @@ bool config_save(const config_t *config, const char *filename)
|
||||
esp_err_t err;
|
||||
int err_code = 0;
|
||||
nvs_handle_t fp;
|
||||
char *line = osi_calloc(1024);
|
||||
char *buf = NULL;
|
||||
bool nvs_opened = false;
|
||||
const size_t keyname_bufsz = sizeof(CONFIG_KEY) + 5 + 1; // including log10(sizeof(i))
|
||||
char *keyname = osi_calloc(keyname_bufsz);
|
||||
int config_size = get_config_size(config);
|
||||
char *buf = osi_calloc(config_size);
|
||||
if (!line || !buf || !keyname) {
|
||||
if (!keyname) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
}
|
||||
size_t config_size = 0;
|
||||
if (!get_config_size(config, &config_size) || config_size == 0) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
}
|
||||
buf = osi_calloc(config_size);
|
||||
if (!buf) {
|
||||
err_code |= 0x01;
|
||||
goto error;
|
||||
}
|
||||
@@ -428,63 +480,67 @@ bool config_save(const config_t *config, const char *filename)
|
||||
err_code |= 0x02;
|
||||
goto error;
|
||||
}
|
||||
nvs_opened = true;
|
||||
|
||||
int w_cnt, w_cnt_total = 0;
|
||||
int w_cnt;
|
||||
size_t w_cnt_total = 0;
|
||||
for (const list_node_t *node = list_begin(config->sections); node != list_end(config->sections); node = list_next(node)) {
|
||||
const section_t *section = (const section_t *)list_node(node);
|
||||
w_cnt = snprintf(line, 1024, "[%s]\n", section->name);
|
||||
if(w_cnt < 0) {
|
||||
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt);
|
||||
err_code |= 0x10;
|
||||
goto error;
|
||||
}
|
||||
if(w_cnt_total + w_cnt > config_size) {
|
||||
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size (config_size = %d).", __func__, (w_cnt + w_cnt_total), config_size);
|
||||
size_t remaining = (w_cnt_total < config_size) ? (config_size - w_cnt_total) : 0;
|
||||
if (remaining == 0) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, w_cnt + w_cnt_total);
|
||||
memcpy(buf + w_cnt_total, line, w_cnt);
|
||||
w_cnt_total += w_cnt;
|
||||
w_cnt = snprintf(buf + w_cnt_total, remaining, "[%s]\n", section->name);
|
||||
if (w_cnt < 0 || (size_t)w_cnt >= remaining) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("section name: %s, w_cnt + w_cnt_total = %d\n", section->name, (int)(w_cnt + w_cnt_total));
|
||||
w_cnt_total += (size_t)w_cnt;
|
||||
|
||||
for (const list_node_t *enode = list_begin(section->entries); enode != list_end(section->entries); enode = list_next(enode)) {
|
||||
const entry_t *entry = (const entry_t *)list_node(enode);
|
||||
OSI_TRACE_DEBUG("(key, val): (%s, %s)\n", entry->key, entry->value);
|
||||
w_cnt = snprintf(line, 1024, "%s = %s\n", entry->key, entry->value);
|
||||
if(w_cnt < 0) {
|
||||
OSI_TRACE_ERROR("snprintf error w_cnt %d.",w_cnt);
|
||||
err_code |= 0x10;
|
||||
goto error;
|
||||
}
|
||||
if(w_cnt_total + w_cnt > config_size) {
|
||||
OSI_TRACE_ERROR("%s, memcpy size (w_cnt + w_cnt_total = %d) is larger than buffer size.(config_size = %d)", __func__, (w_cnt + w_cnt_total), config_size);
|
||||
remaining = (w_cnt_total < config_size) ? (config_size - w_cnt_total) : 0;
|
||||
if (remaining == 0) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, w_cnt + w_cnt_total);
|
||||
memcpy(buf + w_cnt_total, line, w_cnt);
|
||||
w_cnt_total += w_cnt;
|
||||
w_cnt = snprintf(buf + w_cnt_total, remaining, "%s = %s\n", entry->key, entry->value);
|
||||
if (w_cnt < 0 || (size_t)w_cnt >= remaining) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
OSI_TRACE_DEBUG("%s, w_cnt + w_cnt_total = %d", __func__, (int)(w_cnt + w_cnt_total));
|
||||
w_cnt_total += (size_t)w_cnt;
|
||||
}
|
||||
|
||||
// Only add a separating newline if there are more sections.
|
||||
if (list_next(node) != list_end(config->sections)) {
|
||||
buf[w_cnt_total] = '\n';
|
||||
w_cnt_total += 1;
|
||||
if (w_cnt_total + 1 >= config_size) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
buf[w_cnt_total++] = '\n';
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (w_cnt_total >= config_size) {
|
||||
err_code |= 0x20;
|
||||
goto error;
|
||||
}
|
||||
buf[w_cnt_total] = '\0';
|
||||
if (w_cnt_total < CONFIG_FILE_MAX_SIZE) {
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0);
|
||||
err = nvs_set_blob(fp, keyname, buf, w_cnt_total);
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x04;
|
||||
goto error;
|
||||
}
|
||||
}else {
|
||||
int count = (w_cnt_total / CONFIG_FILE_MAX_SIZE);
|
||||
int count = (int)(w_cnt_total / CONFIG_FILE_MAX_SIZE);
|
||||
assert(count <= 0xFF);
|
||||
for (uint8_t i = 0; i <= count; i++)
|
||||
{
|
||||
@@ -497,7 +553,6 @@ bool config_save(const config_t *config, const char *filename)
|
||||
OSI_TRACE_DEBUG("save keyname = %s, i = %d, %d\n", keyname, i, CONFIG_FILE_MAX_SIZE);
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x04;
|
||||
goto error;
|
||||
}
|
||||
@@ -506,24 +561,23 @@ bool config_save(const config_t *config, const char *filename)
|
||||
|
||||
err = nvs_commit(fp);
|
||||
if (err != ESP_OK) {
|
||||
nvs_close(fp);
|
||||
err_code |= 0x08;
|
||||
goto error;
|
||||
}
|
||||
|
||||
nvs_close(fp);
|
||||
osi_free(line);
|
||||
nvs_opened = false;
|
||||
osi_free(buf);
|
||||
osi_free(keyname);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (nvs_opened) {
|
||||
nvs_close(fp);
|
||||
}
|
||||
if (buf) {
|
||||
osi_free(buf);
|
||||
}
|
||||
if (line) {
|
||||
osi_free(line);
|
||||
}
|
||||
if (keyname) {
|
||||
osi_free(keyname);
|
||||
}
|
||||
@@ -552,7 +606,7 @@ static char *trim(char *str)
|
||||
return str;
|
||||
}
|
||||
|
||||
static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
static bool config_parse(nvs_handle_t fp, config_t *config)
|
||||
{
|
||||
assert(fp != 0);
|
||||
assert(config != NULL);
|
||||
@@ -570,9 +624,14 @@ static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
int buf_size = get_config_size_from_flash(fp);
|
||||
char *buf = NULL;
|
||||
|
||||
if(buf_size == 0) { //First use nvs
|
||||
if (buf_size < 0) {
|
||||
err_code |= 0x04;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(buf_size == 0) { //First use nvs
|
||||
goto ok;
|
||||
}
|
||||
buf = osi_calloc(buf_size);
|
||||
if (!line || !section || !buf || !keyname) {
|
||||
err_code |= 0x01;
|
||||
@@ -581,7 +640,7 @@ static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
snprintf(keyname, keyname_bufsz, "%s%d", CONFIG_KEY, 0);
|
||||
err = nvs_get_blob(fp, keyname, buf, &length);
|
||||
if (err == ESP_ERR_NVS_NOT_FOUND) {
|
||||
goto error;
|
||||
goto ok;
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
err_code |= 0x02;
|
||||
@@ -644,6 +703,21 @@ static void config_parse(nvs_handle_t fp, config_t *config)
|
||||
}
|
||||
}
|
||||
|
||||
ok:
|
||||
if (buf) {
|
||||
osi_free(buf);
|
||||
}
|
||||
if (line) {
|
||||
osi_free(line);
|
||||
}
|
||||
if (section) {
|
||||
osi_free(section);
|
||||
}
|
||||
if (keyname) {
|
||||
osi_free(keyname);
|
||||
}
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (buf) {
|
||||
osi_free(buf);
|
||||
@@ -660,6 +734,7 @@ error:
|
||||
if (err_code) {
|
||||
OSI_TRACE_ERROR("%s returned with err code: %d\n", __func__, err_code);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static section_t *section_new(const char *name)
|
||||
@@ -671,6 +746,10 @@ static section_t *section_new(const char *name)
|
||||
|
||||
section->name = osi_strdup(name);
|
||||
section->entries = list_new(entry_free);
|
||||
if (section->name == NULL || section->entries == NULL) {
|
||||
section_free(section);
|
||||
return NULL;
|
||||
}
|
||||
return section;
|
||||
}
|
||||
|
||||
@@ -707,6 +786,10 @@ static entry_t *entry_new(const char *key, const char *value)
|
||||
|
||||
entry->key = osi_strdup(key);
|
||||
entry->value = osi_strdup(value);
|
||||
if (entry->key == NULL || entry->value == NULL) {
|
||||
entry_free(entry);
|
||||
return NULL;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "osi/osi.h"
|
||||
#include "osi/mutex.h"
|
||||
#include "osi/semaphore.h"
|
||||
#include "esp_assume.h"
|
||||
|
||||
typedef struct fixed_queue_t {
|
||||
|
||||
@@ -43,6 +44,12 @@ fixed_queue_t *fixed_queue_new(size_t capacity)
|
||||
}
|
||||
|
||||
osi_mutex_new(&ret->lock);
|
||||
/* CONTRACT / PRECONDITION:
|
||||
* - ret->lock is guaranteed non-NULL after successful osi_mutex_new().
|
||||
* - Rationale: treat mutex allocation failure as fatal in debug builds;
|
||||
* release builds do not add extra code size.
|
||||
*/
|
||||
ESP_ASSUME_NONNULL(ret->lock);
|
||||
ret->capacity = capacity;
|
||||
|
||||
ret->list = list_new(NULL);
|
||||
|
||||
@@ -138,26 +138,37 @@ bool hash_map_set(hash_map_t *hash_map, const void *key, void *data)
|
||||
}
|
||||
list_t *hash_bucket_list = hash_map->bucket[hash_key].list;
|
||||
|
||||
hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
/* Allocate the new entry FIRST, before touching any existing entry.
|
||||
* This preserves the atomicity of hash_map_set: on failure the map
|
||||
* stays exactly as it was, and the caller's previously-stored
|
||||
* key/data remain valid. */
|
||||
hash_map_entry_t *new_entry = osi_calloc(sizeof(hash_map_entry_t));
|
||||
if (new_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
new_entry->key = key;
|
||||
new_entry->data = data;
|
||||
new_entry->hash_map = hash_map;
|
||||
|
||||
if (hash_map_entry) {
|
||||
// Calls hash_map callback to delete the hash_map_entry.
|
||||
bool rc = list_remove(hash_bucket_list, hash_map_entry);
|
||||
hash_map_entry_t *old_entry = find_bucket_entry_(hash_bucket_list, key);
|
||||
|
||||
if (!list_append(hash_bucket_list, new_entry)) {
|
||||
osi_free(new_entry);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Only after the new entry has been successfully inserted do we
|
||||
* destroy the old one (which frees the previous key/data via
|
||||
* bucket_free_). For a brand-new key, bump hash_size instead. */
|
||||
if (old_entry) {
|
||||
bool rc = list_remove(hash_bucket_list, old_entry);
|
||||
assert(rc == true);
|
||||
(void)rc;
|
||||
} else {
|
||||
hash_map->hash_size++;
|
||||
}
|
||||
hash_map_entry = osi_calloc(sizeof(hash_map_entry_t));
|
||||
if (hash_map_entry == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hash_map_entry->key = key;
|
||||
hash_map_entry->data = data;
|
||||
hash_map_entry->hash_map = hash_map;
|
||||
|
||||
return list_append(hash_bucket_list, hash_map_entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hash_map_erase(hash_map_t *hash_map, const void *key)
|
||||
|
||||
@@ -181,8 +181,9 @@ bool list_remove(list_t *list, void *data)
|
||||
}
|
||||
|
||||
if (list->head->data == data) {
|
||||
const bool was_tail = (list->tail == list->head);
|
||||
list_node_t *next = list_free_node(list, list->head);
|
||||
if (list->tail == list->head) {
|
||||
if (was_tail) {
|
||||
list->tail = next;
|
||||
}
|
||||
list->head = next;
|
||||
@@ -191,8 +192,9 @@ bool list_remove(list_t *list, void *data)
|
||||
|
||||
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next)
|
||||
if (node->data == data) {
|
||||
const bool was_tail = (list->tail == node);
|
||||
prev->next = list_free_node(list, node);
|
||||
if (list->tail == node) {
|
||||
if (was_tail) {
|
||||
list->tail = prev;
|
||||
}
|
||||
return true;
|
||||
@@ -211,8 +213,9 @@ bool list_delete(list_t *list, void *data)
|
||||
}
|
||||
|
||||
if (list->head->data == data) {
|
||||
const bool was_tail = (list->tail == list->head);
|
||||
list_node_t *next = list_delete_node(list, list->head);
|
||||
if (list->tail == list->head) {
|
||||
if (was_tail) {
|
||||
list->tail = next;
|
||||
}
|
||||
list->head = next;
|
||||
@@ -221,8 +224,9 @@ bool list_delete(list_t *list, void *data)
|
||||
|
||||
for (list_node_t *prev = list->head, *node = list->head->next; node; prev = node, node = node->next)
|
||||
if (node->data == data) {
|
||||
const bool was_tail = (list->tail == node);
|
||||
prev->next = list_delete_node(list, node);
|
||||
if (list->tail == node) {
|
||||
if (was_tail) {
|
||||
list->tail = prev;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "osi/mutex.h"
|
||||
|
||||
|
||||
@@ -90,15 +92,21 @@ int osi_mutex_global_init(void)
|
||||
|
||||
void osi_mutex_global_deinit(void)
|
||||
{
|
||||
if (gl_mutex == NULL) {
|
||||
return;
|
||||
}
|
||||
vSemaphoreDelete(gl_mutex);
|
||||
gl_mutex = NULL;
|
||||
}
|
||||
|
||||
void osi_mutex_global_lock(void)
|
||||
{
|
||||
assert(gl_mutex != NULL);
|
||||
xSemaphoreTakeRecursive(gl_mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
void osi_mutex_global_unlock(void)
|
||||
{
|
||||
assert(gl_mutex != NULL);
|
||||
xSemaphoreGiveRecursive(gl_mutex);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user