⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⢠⣴⣿⣿⣿⣷⣼⣿⠀⣴⠾⠷⠶⠦⡄⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⢠⡤⢶⣦⣾⣿⣿⣿⣿⣿⣿⣿⠀⣿⣶⣶⣦⣄⠳⣤⣤⠄⠀⠀⠀ ⠀⠀⠀⢀⣼⣳⡿⢻⣿⣿⣿⣿⣿⣿⣿⣿⣶⣿⣿⣗⠈⠙⠻⣶⣄⡀⠀⠀⠀ ⠀⠀⠀⣰⠿⠁⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠈⠳⣤⠀⠀ ⠀⠀⢀⡟⠀⢰⣿⠟⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⠉⠁⠈⠻⣶⣄⠀⠀⠈⠛⢦ ⠀⣀⡼⠃⠀⣼⡟⠀⠀⢸⣿⡿⠉⣿⡿⠿⠛⣿⡄⠀⠀⠀⠙⠿⣆⠀⠀⠀⠈ ⠈⠁⠀⠀⢸⡟⠀⠀⠀⢸⣿⠀⠀⣿⠁⠀⠀⠈⠃⠀⠀⠀⠀⠀⠘⢷⡄⠀⠀ ⠀⠀⠀⠀⣼⠃⠀⠀⠀⢸⡟⠀⠀⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⡆⠀ ⠀⠀⠀⣠⡏⠀⠀⠀⠀⣼⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠻⠃⠀⠀⠀⠀⣻⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ Current Dir: /usr/include/bind9/isc/ [FILE] aes.h [ edit | delete | rename | download ] [FILE] app.h [ edit | delete | rename | download ] [FILE] assertions.h [ edit | delete | rename | download ] [FILE] atomic.h [ edit | delete | rename | download ] [FILE] backtrace.h [ edit | delete | rename | download ] [FILE] base32.h [ edit | delete | rename | download ] [FILE] base64.h [ edit | delete | rename | download ] [FILE] bind9.h [ edit | delete | rename | download ] [FILE] boolean.h [ edit | delete | rename | download ] [FILE] buffer.h [ edit | delete | rename | download ] [FILE] bufferlist.h [ edit | delete | rename | download ] [FILE] commandline.h [ edit | delete | rename | download ] [FILE] condition.h [ edit | delete | rename | download ] [FILE] counter.h [ edit | delete | rename | download ] [FILE] crc64.h [ edit | delete | rename | download ] [FILE] deprecated.h [ edit | delete | rename | download ] [FILE] dir.h [ edit | delete | rename | download ] [FILE] entropy.h [ edit | delete | rename | download ] [FILE] errno.h [ edit | delete | rename | download ] [FILE] errno2result.h [ edit | delete | rename | download ] [FILE] error.h [ edit | delete | rename | download ] [FILE] event.h [ edit | delete | rename | download ] [FILE] eventclass.h [ edit | delete | rename | download ] [FILE] file.h [ edit | delete | rename | download ] [FILE] formatcheck.h [ edit | delete | rename | download ] [FILE] fsaccess.h [ edit | delete | rename | download ] [FILE] hash.h [ edit | delete | rename | download ] [FILE] heap.h [ edit | delete | rename | download ] [FILE] hex.h [ edit | delete | rename | download ] [FILE] hmacmd5.h [ edit | delete | rename | download ] [FILE] hmacsha.h [ edit | delete | rename | download ] [FILE] ht.h [ edit | delete | rename | download ] [FILE] httpd.h [ edit | delete | rename | download ] [FILE] int.h [ edit | delete | rename | download ] [FILE] interfaceiter.h [ edit | delete | rename | download ] [FILE] iterated_hash.h [ edit | delete | rename | download ] [FILE] json.h [ edit | delete | rename | download ] [FILE] keyboard.h [ edit | delete | rename | download ] [FILE] lang.h [ edit | delete | rename | download ] [FILE] lex.h [ edit | delete | rename | download ] [FILE] lfsr.h [ edit | delete | rename | download ] [FILE] lib.h [ edit | delete | rename | download ] [FILE] likely.h [ edit | delete | rename | download ] [FILE] list.h [ edit | delete | rename | download ] [FILE] log.h [ edit | delete | rename | download ] [FILE] magic.h [ edit | delete | rename | download ] [FILE] md5.h [ edit | delete | rename | download ] [FILE] mem.h [ edit | delete | rename | download ] [FILE] meminfo.h [ edit | delete | rename | download ] [FILE] msgcat.h [ edit | delete | rename | download ] [FILE] msgs.h [ edit | delete | rename | download ] [FILE] mutex.h [ edit | delete | rename | download ] [FILE] mutexblock.h [ edit | delete | rename | download ] [FILE] net.h [ edit | delete | rename | download ] [FILE] netaddr.h [ edit | delete | rename | download ] [FILE] netdb.h [ edit | delete | rename | download ] [FILE] netscope.h [ edit | delete | rename | download ] [FILE] offset.h [ edit | delete | rename | download ] [FILE] once.h [ edit | delete | rename | download ] [FILE] ondestroy.h [ edit | delete | rename | download ] [FILE] os.h [ edit | delete | rename | download ] [FILE] parseint.h [ edit | delete | rename | download ] [FILE] platform.h [ edit | delete | rename | download ] [FILE] pool.h [ edit | delete | rename | download ] [FILE] portset.h [ edit | delete | rename | download ] [FILE] print.h [ edit | delete | rename | download ] [FILE] queue.h [ edit | delete | rename | download ] [FILE] quota.h [ edit | delete | rename | download ] [FILE] radix.h [ edit | delete | rename | download ] [FILE] random.h [ edit | delete | rename | download ] [FILE] ratelimiter.h [ edit | delete | rename | download ] [FILE] refcount.h [ edit | delete | rename | download ] [FILE] regex.h [ edit | delete | rename | download ] [FILE] region.h [ edit | delete | rename | download ] [FILE] resource.h [ edit | delete | rename | download ] [FILE] result.h [ edit | delete | rename | download ] [FILE] resultclass.h [ edit | delete | rename | download ] [FILE] rwlock.h [ edit | delete | rename | download ] [FILE] safe.h [ edit | delete | rename | download ] [FILE] serial.h [ edit | delete | rename | download ] [FILE] sha1.h [ edit | delete | rename | download ] [FILE] sha2.h [ edit | delete | rename | download ] [FILE] sockaddr.h [ edit | delete | rename | download ] [FILE] socket.h [ edit | delete | rename | download ] [FILE] stat.h [ edit | delete | rename | download ] [FILE] stats.h [ edit | delete | rename | download ] [FILE] stdio.h [ edit | delete | rename | download ] [FILE] stdlib.h [ edit | delete | rename | download ] [FILE] stdtime.h [ edit | delete | rename | download ] [FILE] strerror.h [ edit | delete | rename | download ] [FILE] string.h [ edit | delete | rename | download ] [FILE] symtab.h [ edit | delete | rename | download ] [FILE] syslog.h [ edit | delete | rename | download ] [FILE] task.h [ edit | delete | rename | download ] [FILE] taskpool.h [ edit | delete | rename | download ] [FILE] thread.h [ edit | delete | rename | download ] [FILE] time.h [ edit | delete | rename | download ] [FILE] timer.h [ edit | delete | rename | download ] [FILE] tm.h [ edit | delete | rename | download ] [FILE] types.h [ edit | delete | rename | download ] [FILE] util.h [ edit | delete | rename | download ] [FILE] version.h [ edit | delete | rename | download ] [FILE] xml.h [ edit | delete | rename | download ] Viewing: /usr/include/bind9/isc/queue.h /* * Copyright (C) Internet Systems Consortium, Inc. ("ISC") * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * See the COPYRIGHT file distributed with this work for additional * information regarding copyright ownership. */ /* * This is a generic implementation of a two-lock concurrent queue. * There are built-in mutex locks for the head and tail of the queue, * allowing elements to be safely added and removed at the same time. * * NULL is "end of list" * -1 is "not linked" */ #ifndef ISC_QUEUE_H #define ISC_QUEUE_H 1 #include <isc/assertions.h> #include <isc/boolean.h> #include <isc/mutex.h> #ifdef ISC_QUEUE_CHECKINIT #define ISC_QLINK_INSIST(x) ISC_INSIST(x) #else #define ISC_QLINK_INSIST(x) (void)0 #endif #define ISC_QLINK(type) struct { type *prev, *next; } #define ISC_QLINK_INIT(elt, link) \ do { \ (elt)->link.next = (elt)->link.prev = (void *)(-1); \ } while(0) #define ISC_QLINK_LINKED(elt, link) ((void*)(elt)->link.next != (void*)(-1)) #define ISC_QUEUE(type) struct { \ type *head, *tail; \ isc_mutex_t headlock, taillock; \ } #define ISC_QUEUE_INIT(queue, link) \ do { \ (void) isc_mutex_init(&(queue).taillock); \ (void) isc_mutex_init(&(queue).headlock); \ (queue).tail = (queue).head = NULL; \ } while (0) #define ISC_QUEUE_EMPTY(queue) ISC_TF((queue).head == NULL) #define ISC_QUEUE_DESTROY(queue) \ do { \ ISC_QLINK_INSIST(ISC_QUEUE_EMPTY(queue)); \ (void) isc_mutex_destroy(&(queue).taillock); \ (void) isc_mutex_destroy(&(queue).headlock); \ } while (0) /* * queues are meant to separate the locks at either end. For best effect, that * means keeping the ends separate - i.e. non-empty queues work best. * * a push to an empty queue has to take the pop lock to update * the pop side of the queue. * Popping the last entry has to take the push lock to update * the push side of the queue. * * The order is (pop, push), because a pop is presumably in the * latency path and a push is when we're done. * * We do an MT hot test in push to see if we need both locks, so we can * acquire them in order. Hopefully that makes the case where we get * the push lock and find we need the pop lock (and have to release it) rare. * * > 1 entry - no collision, push works on one end, pop on the other * 0 entry - headlock race * pop wins - return(NULL), push adds new as both head/tail * push wins - updates head/tail, becomes 1 entry case. * 1 entry - taillock race * pop wins - return(pop) sets head/tail NULL, becomes 0 entry case * push wins - updates {head,tail}->link.next, pop updates head * with new ->link.next and doesn't update tail * */ #define ISC_QUEUE_PUSH(queue, elt, link) \ do { \ isc_boolean_t headlocked = ISC_FALSE; \ ISC_QLINK_INSIST(!ISC_QLINK_LINKED(elt, link)); \ if ((queue).head == NULL) { \ LOCK(&(queue).headlock); \ headlocked = ISC_TRUE; \ } \ LOCK(&(queue).taillock); \ if ((queue).tail == NULL && !headlocked) { \ UNLOCK(&(queue).taillock); \ LOCK(&(queue).headlock); \ LOCK(&(queue).taillock); \ headlocked = ISC_TRUE; \ } \ (elt)->link.prev = (queue).tail; \ (elt)->link.next = NULL; \ if ((queue).tail != NULL) \ (queue).tail->link.next = (elt); \ (queue).tail = (elt); \ UNLOCK(&(queue).taillock); \ if (headlocked) { \ if ((queue).head == NULL) \ (queue).head = (elt); \ UNLOCK(&(queue).headlock); \ } \ } while (0) #define ISC_QUEUE_POP(queue, link, ret) \ do { \ LOCK(&(queue).headlock); \ ret = (queue).head; \ while (ret != NULL) { \ if (ret->link.next == NULL) { \ LOCK(&(queue).taillock); \ if (ret->link.next == NULL) { \ (queue).head = (queue).tail = NULL; \ UNLOCK(&(queue).taillock); \ break; \ }\ UNLOCK(&(queue).taillock); \ } \ (queue).head = ret->link.next; \ (queue).head->link.prev = NULL; \ break; \ } \ UNLOCK(&(queue).headlock); \ if (ret != NULL) \ (ret)->link.next = (ret)->link.prev = (void *)(-1); \ } while(0) #define ISC_QUEUE_UNLINK(queue, elt, link) \ do { \ ISC_QLINK_INSIST(ISC_QLINK_LINKED(elt, link)); \ LOCK(&(queue).headlock); \ LOCK(&(queue).taillock); \ if ((elt)->link.prev == NULL) \ (queue).head = (elt)->link.next; \ else \ (elt)->link.prev->link.next = (elt)->link.next; \ if ((elt)->link.next == NULL) \ (queue).tail = (elt)->link.prev; \ else \ (elt)->link.next->link.prev = (elt)->link.prev; \ UNLOCK(&(queue).taillock); \ UNLOCK(&(queue).headlock); \ (elt)->link.next = (elt)->link.prev = (void *)(-1); \ } while(0) #endif /* ISC_QUEUE_H */