fifo.c

来自「使用最广泛的radius的linux的源码」· C语言 代码 · 共 209 行

C
209
字号
/* * fifo.c	Non-thread-safe fifo (FIFO) implementation, based *		on hash tables. * * Version:	$Id: fifo.c,v 1.11 2008/04/03 08:37:07 aland Exp $ * *   This library is free software; you can redistribute it and/or *   modify it under the terms of the GNU Lesser General Public *   License as published by the Free Software Foundation; either *   version 2.1 of the License, or (at your option) any later version. * *   This library is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *   Lesser General Public License for more details. * *   You should have received a copy of the GNU Lesser General Public *   License along with this library; if not, write to the Free Software *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * *  Copyright 2005,2006  The FreeRADIUS server project *  Copyright 2005  Alan DeKok <aland@ox.org> */#include <freeradius-devel/ident.h>RCSID("$Id: fifo.c,v 1.11 2008/04/03 08:37:07 aland Exp $")#include <freeradius-devel/libradius.h>typedef struct fr_fifo_entry_t {	struct fr_fifo_entry_t *next;	void			*data;} fr_fifo_entry_t;struct fr_fifo_t {	fr_fifo_entry_t *head, **tail;	fr_fifo_entry_t *freelist;	int num_elements;	int max_entries;	fr_fifo_free_t freeNode;};fr_fifo_t *fr_fifo_create(int max_entries, fr_fifo_free_t freeNode){	fr_fifo_t *fi;	if ((max_entries < 2) || (max_entries > (1024 * 1024))) return NULL;	fi = malloc(sizeof(*fi));	if (!fi) return NULL;	memset(fi, 0, sizeof(*fi));	fi->max_entries = max_entries;	fi->freeNode = freeNode;	return fi;}static void fr_fifo_free_entries(fr_fifo_t *fi, fr_fifo_entry_t *head){	fr_fifo_entry_t *next;	while (head) {		next = head->next;		if (fi->freeNode && head->data) fi->freeNode(head->data);		free(head);		head = next;	}}void fr_fifo_free(fr_fifo_t *fi){	if (!fi) return;	fr_fifo_free_entries(fi, fi->head);	fr_fifo_free_entries(fi, fi->freelist);	free(fi);}static fr_fifo_entry_t *fr_fifo_alloc_entry(fr_fifo_t *fi){	fr_fifo_entry_t *entry;	if (fi->freelist) {		entry = fi->freelist;		fi->freelist = entry->next;	} else {		entry = malloc(sizeof(*entry));		if (!entry) return NULL;	}	memset(entry, 0, sizeof(*entry));	return entry;}int fr_fifo_push(fr_fifo_t *fi, void *data){	fr_fifo_entry_t *entry;	if (!fi || !data) return 0;	if (fi->num_elements >= fi->max_entries) return 0;	entry = fr_fifo_alloc_entry(fi);	if (!entry) return 0;	entry->data = data;	if (!fi->head) {		fi->head = entry;	} else {		*fi->tail = entry;	}	fi->tail = &(entry->next);	fi->num_elements++;	return 1;}static void fr_fifo_free_entry(fr_fifo_t *fi, fr_fifo_entry_t *entry){	entry->data = NULL;	entry->next = fi->freelist;	fi->freelist = entry;}void *fr_fifo_pop(fr_fifo_t *fi){	void *data;	fr_fifo_entry_t *entry;	if (!fi || !fi->head) return NULL;	entry = fi->head;	fi->head = entry->next;	data = entry->data;	fr_fifo_free_entry(fi, entry);	fi->num_elements--;	if (!fi->head) {		fi->tail = NULL;		fi->num_elements = 0;	}	return data;}void *fr_fifo_peek(fr_fifo_t *fi){	if (!fi || !fi->head) return NULL;	return fi->head->data;}int fr_fifo_num_elements(fr_fifo_t *fi){	if (!fi) return 0;	return fi->num_elements;}#ifdef TESTING/* *  cc -DTESTING -I .. fifo.c -o fifo * *  ./fifo */#define MAX 1024int main(int argc, char **argv){	int i, array[MAX];	fr_fifo_t *fi;	fi = fr_fifo_create(MAX, NULL);	if (!fi) exit(1);	for (i = 0; i < MAX; i++) {		array[i] = i;		if (!fr_fifo_push(fi, &array[i])) exit(2);	}	for (i = 0; i < MAX; i++) {		int *p;		p = fr_fifo_pop(fi);		if (!p) {			fprintf(stderr, "No pop at %d\n", i);			exit(3);		}		if (*p != i) exit(4);	}	exit(0);}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?