static hal_funct_entry_t *alloc_funct_entry_struct(void) { hal_list_t *freelist, *l; hal_funct_entry_t *p; /* check the free list */ freelist = &(hal_data->funct_entry_free); l = list_next(freelist); if (l != freelist) { /* found a free structure, unlink from the free list */ list_remove_entry(l); p = (hal_funct_entry_t *) l; } else { /* nothing on free list, allocate a brand new one */ p = shmalloc_dn(sizeof(hal_funct_entry_t)); l = (hal_list_t *) p; list_init_entry(l); } if (p) { /* make sure it's empty */ p->funct_ptr = 0; p->arg = 0; p->funct.l = 0; } return p; }
int hal_del_funct_from_thread(const char *funct_name, const char *thread_name) { hal_funct_t *funct; hal_list_t *list_root, *list_entry; hal_funct_entry_t *funct_entry; CHECK_HALDATA(); CHECK_LOCK(HAL_LOCK_CONFIG); CHECK_STR(funct_name); CHECK_STR(thread_name); HALDBG("removing function '%s' from thread '%s'", funct_name, thread_name); { hal_thread_t *thread __attribute__((cleanup(halpr_autorelease_mutex))); /* get mutex before accessing data structures */ rtapi_mutex_get(&(hal_data->mutex)); /* search function list for the function */ funct = halpr_find_funct_by_name(funct_name); if (funct == 0) { HALERR("function '%s' not found", funct_name); return -EINVAL; } /* found the function, is it in use? */ if (funct->users == 0) { HALERR("function '%s' is not in use", funct_name); return -EINVAL; } /* search thread list for thread_name */ thread = halpr_find_thread_by_name(thread_name); if (thread == 0) { /* thread not found */ HALERR("thread '%s' not found", thread_name); return -EINVAL; } /* ok, we have thread and function, does thread use funct? */ list_root = &(thread->funct_list); list_entry = list_next(list_root); while (1) { if (list_entry == list_root) { /* reached end of list, funct not found */ HALERR("thread '%s' doesn't use %s", thread_name, funct_name); return -EINVAL; } funct_entry = (hal_funct_entry_t *) list_entry; if (SHMPTR(funct_entry->funct_ptr) == funct) { /* this funct entry points to our funct, unlink */ list_remove_entry(list_entry); /* and delete it */ free_funct_entry_struct(funct_entry); /* done */ return 0; } /* try next one */ list_entry = list_next(list_entry); } } }
void free_funct_struct(hal_funct_t * funct) { int next_thread; hal_thread_t *thread; hal_list_t *list_root, *list_entry; hal_funct_entry_t *funct_entry; if (funct->users > 0) { /* We can't casually delete the function, there are thread(s) which will call it. So we must check all the threads and remove any funct_entrys that call this function */ /* start at root of thread list */ next_thread = hal_data->thread_list_ptr; /* run through thread list */ while (next_thread != 0) { /* point to thread */ thread = SHMPTR(next_thread); /* start at root of funct_entry list */ list_root = &(thread->funct_list); list_entry = list_next(list_root); /* run thru funct_entry list */ while (list_entry != list_root) { /* point to funct entry */ funct_entry = (hal_funct_entry_t *) list_entry; /* test it */ if (SHMPTR(funct_entry->funct_ptr) == funct) { /* this funct entry points to our funct, unlink */ list_entry = list_remove_entry(list_entry); /* and delete it */ free_funct_entry_struct(funct_entry); } else { /* no match, try the next one */ list_entry = list_next(list_entry); } } /* move on to the next thread */ next_thread = thread->next_ptr; } } /* clear contents of struct */ funct->uses_fp = 0; funct->owner_id = 0; funct->reentrant = 0; funct->users = 0; funct->arg = 0; funct->funct.l = 0; funct->runtime = 0; funct->name[0] = '\0'; /* add it to free list */ funct->next_ptr = hal_data->funct_free_ptr; hal_data->funct_free_ptr = SHMOFF(funct); }
void test_list_remove_entry(void) { ListEntry *empty_list = NULL; ListEntry *list; ListEntry *entry; list = generate_list(); /* Remove the third entry */ entry = list_nth_entry(list, 2); assert(list_remove_entry(&list, entry) != 0); assert(list_length(list) == 3); check_list_integrity(list); /* Remove the first entry */ entry = list_nth_entry(list, 0); assert(list_remove_entry(&list, entry) != 0); assert(list_length(list) == 2); check_list_integrity(list); /* Try some invalid removes */ /* NULL */ assert(list_remove_entry(&list, NULL) == 0); /* Removing NULL from an empty list */ assert(list_remove_entry(&empty_list, NULL) == 0); list_free(list); /* Test removing an entry when it is the only entry. */ list = NULL; assert(list_append(&list, &variable1) != NULL); assert(list != NULL); assert(list_remove_entry(&list, list) != 0); assert(list == NULL); /* Test removing the last entry */ list = generate_list(); entry = list_nth_entry(list, 3); assert(list_remove_entry(&list, entry) != 0); check_list_integrity(list); list_free(list); }
END_TEST START_TEST(test_list_remove_entry) { list_t *list = list_new(); list_insert(list, (void*)1); list_remove_entry(list, list_first(list)); fail_unless(list_first(list) == NULL, "The first and only entry in the list was removed, " "but it is not null"); fail_unless(list_last(list) == NULL, "The last and only entry in the list was removed, " "but it is not null"); list_delete(list); }