void *gwlist_timed_consume(List *list, long sec) { void *item; struct timespec abstime; int rc; abstime.tv_sec = time(NULL) + sec; abstime.tv_nsec = 0; lock(list); ++list->num_consumers; while (list->len == 0 && list->num_producers > 0) { list->single_operation_lock->owner = -1; rc = pthread_cond_timedwait(&list->nonempty, &list->single_operation_lock->mutex, &abstime); list->single_operation_lock->owner = gwthread_self(); if (rc == ETIMEDOUT) break; } if (list->len > 0) { item = GET(list, 0); delete_items_from_list(list, 0, 1); } else { item = NULL; } --list->num_consumers; unlock(list); return item; }
void *list_extract_first(List *list) { void *item; gw_assert(list != NULL); lock(list); if (list->len == 0) item = NULL; else { item = GET(list, 0); delete_items_from_list(list, 0, 1); } unlock(list); return item; }
void *list_consume(List *list) { void *item; lock(list); while (list->len == 0 && list->num_producers > 0) { list->single_operation_lock->owner = -1; pthread_cond_wait(&list->nonempty, &list->single_operation_lock->mutex); list->single_operation_lock->owner = gwthread_self(); } if (list->len > 0) { item = GET(list, 0); delete_items_from_list(list, 0, 1); } else { item = NULL; } unlock(list); return item; }
List *list_extract_matching(List *list, void *pat, list_item_matches_t *cmp) { List *new_list; long i; new_list = list_create(); lock(list); i = 0; while (i < list->len) { if (cmp(GET(list, i), pat)) { list_append(new_list, GET(list, i)); delete_items_from_list(list, i, 1); } else ++i; } unlock(list); if (list_len(new_list) == 0) { list_destroy(new_list, NULL); return NULL; } return new_list; }
long list_delete_equal(List *list, void *item) { long i; long count; lock(list); /* XXX this could be made more efficient by noticing consecutive items to be removed, but leave that for later. --liw */ i = 0; count = 0; while (i < list->len) { if (GET(list, i) == item) { delete_items_from_list(list, i, 1); count++; } else { ++i; } } unlock(list); return count; }
long gwlist_delete_matching(List *list, void *pat, gwlist_item_matches_t *matches) { long i; long count; lock(list); /* XXX this could be made more efficient by noticing consecutive items to be removed, but leave that for later. --liw */ i = 0; count = 0; while (i < list->len) { if (matches(GET(list, i), pat)) { delete_items_from_list(list, i, 1); count++; } else { ++i; } } unlock(list); return count; }
void list_delete(List *list, long pos, long count) { lock(list); delete_items_from_list(list, pos, count); unlock(list); }