1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <pthread.h> 29 #include <memory.h> 30 #include "queue.h" 31 #include <stdio.h> 32 #include <assert.h> 33 #include "plugin.h" 34 35 #define DEBUG 0 36 37 #if DEBUG 38 static FILE *dbfp; 39 extern FILE *__auditd_debug_file_open(); 40 #define DPRINT(x) {(void) fprintf x; } 41 #else 42 #define DPRINT(x) 43 #endif 44 45 void 46 audit_queue_init(au_queue_t *q) 47 { 48 q->auq_head = NULL; 49 q->auq_tail = NULL; 50 (void) pthread_mutex_init(&q->auq_lock, NULL); 51 q->auq_count = 0; 52 #if DEBUG 53 dbfp = __auditd_debug_file_open(); 54 #endif 55 } 56 57 /* 58 * enqueue() caller creates queue entry 59 */ 60 61 void 62 audit_enqueue(au_queue_t *q, void *p) 63 { 64 (void) pthread_mutex_lock(&q->auq_lock); 65 66 DPRINT((dbfp, "enqueue0(%X): p=%X, head=%X, tail=%X, count=%d\n", 67 q, p, q->auq_head, q->auq_tail, q->auq_count)); 68 69 if (q->auq_head == NULL) 70 q->auq_head = p; 71 else { 72 DPRINT((dbfp, "\tindirect tail=%X\n", 73 &(((audit_link_t *)(q->auq_tail))->aln_next))); 74 75 ((audit_link_t *)(q->auq_tail))->aln_next = p; 76 } 77 q->auq_tail = p; 78 ((audit_link_t *)p)->aln_next = NULL; 79 q->auq_count++; 80 81 DPRINT((dbfp, "enqueue1(%X): p=%X, head=%X, tail=%X, " 82 "count=%d, pnext=%X\n", 83 q, p, q->auq_head, q->auq_tail, q->auq_count, 84 ((audit_link_t *)p)->aln_next)); 85 86 (void) pthread_mutex_unlock(&q->auq_lock); 87 } 88 89 /* 90 * audit_dequeue() returns entry; caller is responsible for free 91 */ 92 93 int 94 audit_dequeue(au_queue_t *q, void **p) 95 { 96 (void) pthread_mutex_lock(&q->auq_lock); 97 98 if ((*p = q->auq_head) == NULL) { 99 DPRINT((dbfp, "dequeue1(%X): p=%X, head=%X, " 100 "tail=%X, count=%d\n", 101 q, *p, q->auq_head, q->auq_tail, q->auq_count)); 102 103 (void) pthread_mutex_unlock(&q->auq_lock); 104 return (1); 105 } 106 q->auq_count--; 107 108 /* if *p is the last, next is NULL */ 109 q->auq_head = ((audit_link_t *)*p)->aln_next; 110 111 DPRINT((dbfp, "dequeue0(%X): p=%X, head=%X, tail=%X, " 112 "count=%d, pnext=%X\n", 113 q, *p, q->auq_head, q->auq_tail, q->auq_count, 114 ((audit_link_t *)*p)->aln_next)); 115 116 (void) pthread_mutex_unlock(&q->auq_lock); 117 return (0); 118 } 119 120 /* 121 * increment ref count 122 */ 123 void 124 audit_incr_ref(pthread_mutex_t *l, audit_rec_t *p) 125 { 126 (void) pthread_mutex_lock(l); 127 p->abq_ref_count++; 128 DPRINT((dbfp, "incr_ref: p=%X, count=%d\n", 129 p, p->abq_ref_count)); 130 (void) pthread_mutex_unlock(l); 131 } 132 /* 133 * decrement reference count; if it reaches zero, 134 * return a pointer to it. Otherwise, return NULL. 135 */ 136 audit_rec_t * 137 audit_release(pthread_mutex_t *l, audit_rec_t *p) 138 { 139 assert(p != NULL); 140 141 (void) pthread_mutex_lock(l); 142 143 DPRINT((dbfp, "release: p=%X, count=%d\n", 144 p, p->abq_ref_count)); 145 146 if (--(p->abq_ref_count) > 0) { 147 (void) pthread_mutex_unlock(l); 148 return (NULL); 149 } 150 (void) pthread_mutex_unlock(l); 151 152 return (p); 153 } 154 155 int 156 audit_queue_size(au_queue_t *q) 157 { 158 int size; 159 160 (void) pthread_mutex_lock(&q->auq_lock); 161 size = q->auq_count; 162 (void) pthread_mutex_unlock(&q->auq_lock); 163 164 return (size); 165 } 166 167 168 void 169 audit_queue_destroy(au_queue_t *q) 170 { 171 (void) pthread_mutex_destroy(&q->auq_lock); 172 } 173