⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⢠⣴⣿⣿⣿⣷⣼⣿⠀⣴⠾⠷⠶⠦⡄⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢠⡤⢶⣦⣾⣿⣿⣿⣿⣿⣿⣿⠀⣿⣶⣶⣦⣄⠳⣤⣤⠄⠀⠀⠀
⠀⠀⠀⢀⣼⣳⡿⢻⣿⣿⣿⣿⣿⣿⣿⣿⣶⣿⣿⣗⠈⠙⠻⣶⣄⡀⠀⠀⠀
⠀⠀⠀⣰⠿⠁⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⡄⠀⠀⠈⠳⣤⠀⠀
⠀⠀⢀⡟⠀⢰⣿⠟⠻⢿⣿⣿⣿⣿⣿⣿⣿⣿⠉⠁⠈⠻⣶⣄⠀⠀⠈⠛⢦   
⠀⣀⡼⠃⠀⣼⡟⠀⠀⢸⣿⡿⠉⣿⡿⠿⠛⣿⡄⠀⠀⠀⠙⠿⣆⠀⠀⠀⠈
⠈⠁⠀⠀⢸⡟⠀⠀⠀⢸⣿⠀⠀⣿⠁⠀⠀⠈⠃⠀⠀⠀⠀⠀⠘⢷⡄⠀⠀
⠀⠀⠀⠀⣼⠃⠀⠀⠀⢸⡟⠀⠀⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢿⡆⠀
⠀⠀⠀⣠⡏⠀⠀⠀⠀⣼⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠻⠃⠀⠀⠀⠀⣻⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

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 */

Upload File: