static void finalize_queue(Queue *queue) { finalize_mutex(&queue->mutex); finalize_condvar(&queue->value_available); finalize_condvar(&queue->space_available); finalize_list(&queue->values); }
void finalize_phrase(pedphrase * phrase) { pedlistnode * node; pedchar * pchar; if(phrase != NULL) { node = phrase->chars->head; while(node != NULL) { pchar = (pedchar *) node->content; finalize_char(pchar); node->content = NULL; node = node->next; } finalize_list (phrase->chars); free(phrase->phrasebox); free(phrase); } }
void finalize_doc(peddoc *doc) { pedlistnode *pnode; pedpage * page; if (doc != NULL) { pnode = doc->pages->head; while (pnode != NULL) { page = (pedpage *)pnode->content; finalize_page(page); pnode->content = NULL; pnode = pnode->next; } finalize_list(doc->pages); finalize_font_cache(doc->fontcache); free(doc->docbox); free(doc); } }
const char* test_list() { gc_list list; initialize_list(&list); for(long i = 1; i < 17; ++i) append_item((os_pointer)i, &list); gc_list_iterator itr; begin_list_iteration(&list, &itr); os_pointer item = 0; long expected = 1; while((item = current_item(&itr))) { if((long)item != expected) return "append item failed"; if((long)item % 2 == 0 || (long)item < 7) remove_item(&itr); advance_item(&itr); ++expected; } for(long i = 16; i < 19; ++i) append_item((os_pointer)i, &list); long expected2[] = {7, 9, 11, 13, 15, 16, 17, 18}; int expected2_idx = 0; begin_list_iteration(&list, &itr); while((item = current_item(&itr))) { if((long)item != expected2[expected2_idx++]) return "remove item failed"; advance_item(&itr); } finalize_list(&list); return "passed"; }
static void finalize_condvar(ConditionVariable *condvar) { finalize_list(&condvar->waiting); }
static void finalize_mutex(Mutex *mutex) { finalize_list(&mutex->waiting); }
static void libevent_tap_process(int fd, short which, void *arg) { LIBEVENT_THREAD *me = arg; assert(me->type == TAP); if (recv(fd, devnull, sizeof(devnull), 0) == -1) { if (settings.verbose > 0) { settings.extensions.logger->log(EXTENSION_LOG_WARNING, NULL, "Can't read from libevent pipe: %s\n", strerror(errno)); } } if (memcached_shutdown) { event_base_loopbreak(me->base); return ; } // Do we have pending closes? const size_t max_items = 256; LOCK_THREAD(me); conn *pending_close[max_items]; size_t n_pending_close = 0; if (me->pending_close && me->last_checked != current_time) { assert(!has_cycle(me->pending_close)); me->last_checked = current_time; n_pending_close = list_to_array(pending_close, max_items, &me->pending_close); } // Now copy the pending IO buffer and run them... conn *pending_io[max_items]; size_t n_items = list_to_array(pending_io, max_items, &me->pending_io); UNLOCK_THREAD(me); for (size_t i = 0; i < n_items; ++i) { conn *c = pending_io[i]; assert(c->thread == me); LOCK_THREAD(c->thread); assert(me == c->thread); settings.extensions.logger->log(EXTENSION_LOG_DEBUG, NULL, "Processing tap pending_io for %d\n", c->sfd); UNLOCK_THREAD(me); if (!c->registered_in_libevent) { register_event(c, NULL); } /* * We don't want the thread to keep on serving all of the data * from the context of the notification pipe, so just let it * run one time to set up the correct mask in libevent */ c->nevents = 1; c->which = EV_WRITE; while (c->state(c)) { /* do task */ } } /* Close any connections pending close */ for (size_t i = 0; i < n_pending_close; ++i) { conn *ce = pending_close[i]; if (ce->refcount == 1) { settings.extensions.logger->log(EXTENSION_LOG_DEBUG, NULL, "OK, time to nuke: %p\n", (void*)ce); assert(ce->next == NULL); conn_close(ce); pending_close[i] = NULL; } else { LOCK_THREAD(me); enlist_conn(ce, &me->pending_close); UNLOCK_THREAD(me); } } LOCK_THREAD(me); finalize_list(pending_io, n_items); finalize_list(pending_close, n_pending_close); UNLOCK_THREAD(me); }