diff --git a/vxworks-6.9/target/src/os/vxtss_symlist.c b/vxworks-6.9/target/src/os/vxtss_symlist.c index 4e3c48b3..20038198 100644 --- a/vxworks-6.9/target/src/os/vxtss_symlist.c +++ b/vxworks-6.9/target/src/os/vxtss_symlist.c @@ -17,6 +17,7 @@ typedef struct { char run_once_arg_str[MAX_STR_LEN]; char tss_key_name[MAX_STR_LEN]; tss_t *tss_key; + void (*dtor)(void *); } tss_sym_info; /* Sym table entry */ @@ -202,7 +203,8 @@ tss_symlist_add_new_internal(TASK_ID taskId, char *tss_key_name, tss_t *key, tss_sym_state state, - int cloned) + int cloned, + void (*dtor)(void *)) { int idx; @@ -220,12 +222,55 @@ tss_symlist_add_new_internal(TASK_ID taskId, strncpy(tss_sym_table[idx].info.tss_key_name, tss_key_name, MAX_STR_LEN - 1); tss_sym_table[idx].info.tss_key_name[MAX_STR_LEN - 1] = '\0'; tss_sym_table[idx].info.tss_key = (tss_t*)key; + tss_sym_table[idx].info.dtor = dtor; tss_sym_table[idx].state = state; tss_sym_table[idx].cloned = cloned; return OK; } +/* taskHook cleanup */ +void +tss_symlist_task_cleanup_hook(int taskId) +{ + const char *name = taskName(taskId); + + CRYPTO_THREAD_write_lock(tss_sym_table_lock); + + int i; + for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { + if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID || + tss_sym_table[i].taskid != taskId) + continue; + + tss_t *thread_local_ptr = tss_sym_table[i].info.tss_key; + tss_entry_t *entry = (tss_entry_t *)(*thread_local_ptr); + + /* Clear the global key pointer for this task immediately */ + *thread_local_ptr = (tss_t)0; + + if (entry) { + + /* Call destructor only if entry->var is non‑NULL and looks valid */ + if (entry->var && tss_sym_table[i].info.dtor) { + tss_sym_table[i].info.dtor(entry->var); + } + + taskVarDelete(taskId, (void *)&entry->var); + entry->var = NULL; + entry->dtor = NULL; + free(entry); + } + + /* clear the table slot */ + memset(&tss_sym_table[i], 0, sizeof(tss_sym_entry)); + tss_sym_table[i].info.tss_key = NULL; + tss_sym_table[i].state = TSS_SYMLIST_STATE_INVALID; + } + + CRYPTO_THREAD_unlock(tss_sym_table_lock); +} + /* Initialize the TSS symbol table and clone list */ int tss_sym_init(void) @@ -247,6 +292,9 @@ tss_sym_init(void) /* Create new lock */ tss_sym_table_lock = (CRYPTO_RWLOCK *)CRYPTO_THREAD_lock_new(); + /* Attach cleanup routine to task delete hook chain */ + taskDeleteHookAdd((FUNCPTR)tss_symlist_task_cleanup_hook); + g_tss_sym_initialized = 1; return OK; @@ -268,8 +316,11 @@ tss_symlist_add_new(TASK_ID taskId, char *run_once_arg_str, char *tss_key_name, /* Acquire lock */ CRYPTO_THREAD_write_lock(tss_sym_table_lock); - int result = tss_symlist_add_new_internal(taskId, run_once_arg_str, - tss_key_name, key, TSS_SYMLIST_STATE_ADDED, FALSE); + tss_entry_t *tmp_entry = (tss_entry_t*)(*key); + + int result = tss_symlist_add_new_internal(taskId, run_once_arg_str, tss_key_name, + key, TSS_SYMLIST_STATE_ADDED, FALSE, + tmp_entry ? tmp_entry->dtor : NULL); /* Add this entry to the clone list if it isn't already added */ if (result == OK) { @@ -278,6 +329,7 @@ tss_symlist_add_new(TASK_ID taskId, char *run_once_arg_str, char *tss_key_name, strncpy(tmp.run_once_arg_str, run_once_arg_str, MAX_STR_LEN - 1); strncpy(tmp.tss_key_name, tss_key_name, MAX_STR_LEN - 1); tmp.tss_key = key; + tmp.dtor = tmp_entry ? tmp_entry->dtor : NULL; tss_clone_list_add(&tmp); } @@ -289,7 +341,9 @@ tss_symlist_add_new(TASK_ID taskId, char *run_once_arg_str, char *tss_key_name, /* Create entry and update the global key (thread_local) for the current task */ static int -tss_create_and_update_table(tss_t *key, char *tss_key_name, char *run_once_arg_str) +tss_create_and_update_table(tss_t *key, char *tss_key_name, + char *run_once_arg_str, + void (*dtor)(void *)) { tss_entry_t *entry; TASK_ID selfTaskId; @@ -318,7 +372,8 @@ tss_create_and_update_table(tss_t *key, char *tss_key_name, char *run_once_arg_s /* Add to symbol table for tracking */ int result = tss_symlist_add_new_internal(selfTaskId, run_once_arg_str, - tss_key_name, key, TSS_SYMLIST_STATE_ADDED, TRUE); + tss_key_name, key, TSS_SYMLIST_STATE_ADDED, + TRUE, dtor); if (result != OK) { /* Rollback on failure */ @@ -336,7 +391,8 @@ static int tss_symlist_check_and_clone(TASK_ID tid, const char *tss_key_name, const char *run_once_arg_str, - tss_t *key) + tss_t *key, + void (*dtor)(void *)) { int idx; /* First, check if entry already exists in the symbol table */ @@ -355,7 +411,8 @@ tss_symlist_check_and_clone(TASK_ID tid, /* Not found, clone entry - lock already held by caller */ return tss_create_and_update_table(key, (char *)tss_key_name, - (char *)run_once_arg_str); + (char *)run_once_arg_str, + dtor); } /* Clone missing entries for a new task */ @@ -388,7 +445,8 @@ tss_symlist_clone_entries_for_new_task(char *run_once_arg_string) int result = tss_symlist_check_and_clone(current_tid, tss_clone_list[i].tss_key_name, tss_clone_list[i].run_once_arg_str, - tss_clone_list[i].tss_key); + tss_clone_list[i].tss_key, + tss_clone_list[i].dtor); } CRYPTO_THREAD_unlock(tss_sym_table_lock); @@ -412,21 +470,28 @@ tss_sym_deinit(void) /* Acquire write lock before tearing down */ CRYPTO_THREAD_write_lock(tss_sym_table_lock); + /* Remove cleanup hook from task delete chain */ + taskDeleteHookDelete((FUNCPTR)tss_symlist_task_cleanup_hook); + /* Free any remaining per-task entries in the symbol table */ for (i = 0; i < MAX_TSS_SYM_ENTRY; i++) { if (tss_sym_table[i].state == TSS_SYMLIST_STATE_INVALID) continue; - if (tss_sym_table[i].info.tss_key) { - tss_entry_t *entry = (tss_entry_t *)(*tss_sym_table[i].info.tss_key); - if (entry) { - if (entry->dtor) - entry->dtor(entry->var); - free(entry); - *tss_sym_table[i].info.tss_key = (tss_t)0; /* clear per-task slot */ + tss_t *thread_local_ptr = tss_sym_table[i].info.tss_key; + tss_entry_t *entry = NULL; + + if (thread_local_ptr) { + entry = (tss_entry_t *)(*thread_local_ptr); + /* Clear the global key for this task immediately */ + *thread_local_ptr = (tss_t)0; + } + + if (entry) { + if (entry->var && tss_sym_table[i].info.dtor) { + tss_sym_table[i].info.dtor(entry->var); } - /* Clear the stored pointer to the key variable itself */ - tss_sym_table[i].info.tss_key = NULL; + free(entry); } /* Clear the table slot */ @@ -436,8 +501,6 @@ tss_sym_deinit(void) /* Clear clone list entries */ for (i = 0; i < MAX_CLONE_ENTRIES; i++) { - if (tss_clone_list[i].tss_key == NULL) - continue; memset(&tss_clone_list[i], 0, sizeof(tss_sym_info)); tss_clone_list[i].tss_key = NULL; }