Imported Upstream version 2.4.3
[platform/upstream/audit.git] / audisp / plugins / zos-remote / zos-remote-queue.c
1 /***************************************************************************
2  *   Copyright (C) 2007 International Business Machines  Corp.             *
3  *   All Rights Reserved.                                                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  *                                                                         *
20  * Authors:                                                                *
21  *   Klaus Heinrich Kiwi <klausk@br.ibm.com>                               *
22  *   based on code by Steve Grubb <sgrubb@redhat.com>                      *
23  ***************************************************************************/
24
25 #include "zos-remote-queue.h"
26
27 #include <stdlib.h>
28 #include <pthread.h>
29 #include <syslog.h>
30 #include "zos-remote-log.h"
31
32 static volatile BerElement **q;
33 static pthread_mutex_t queue_lock;
34 static pthread_cond_t queue_nonempty;
35 static unsigned int q_next, q_last, q_depth;
36
37
38 int init_queue(unsigned int size)
39 {
40     unsigned int i;
41
42     q_next = 0;
43     q_last = 0;
44     q_depth = size;
45     q = malloc(q_depth * sizeof(BerElement *));
46     if (q == NULL)
47         return -1;
48
49     for (i=0; i<q_depth; i++) 
50         q[i] = NULL;
51
52     /* Setup IPC mechanisms */
53     pthread_mutex_init(&queue_lock, NULL);
54     pthread_cond_init(&queue_nonempty, NULL);
55
56     return 0;
57 }
58
59 void enqueue(BerElement *ber)
60 {
61     unsigned int n, retry_cnt = 0;
62
63 retry:
64     /* We allow 3 retries and then its over */
65     if (retry_cnt > 3) {
66         log_err("queue is full - dropping event");
67         return;
68     }
69     pthread_mutex_lock(&queue_lock);
70
71     /* OK, have lock add event */
72     n = q_next%q_depth;
73     if (q[n] == NULL) {
74         q[n] = ber;
75         q_next = (n+1) % q_depth;
76         pthread_cond_signal(&queue_nonempty);
77         pthread_mutex_unlock(&queue_lock);
78     } else {
79         pthread_mutex_unlock(&queue_lock);
80         pthread_yield(); /* Let dequeue thread run to clear queue */
81         retry_cnt++;
82         goto retry;
83     }
84 }
85
86 BerElement *dequeue(void)
87 {
88     BerElement *ber;
89     unsigned int n;
90
91     /* Wait until its got something in it */
92     pthread_mutex_lock(&queue_lock);
93     n = q_last%q_depth;
94     if (q[n] == NULL) {
95         pthread_cond_wait(&queue_nonempty, &queue_lock);
96         n = q_last%q_depth;
97     }
98
99     /* OK, grab the next event */
100     if (q[n] != NULL) {
101         ber = (BerElement *) q[n];
102         q[n] = NULL;
103         q_last = (n+1) % q_depth;
104     } else
105         ber = NULL;
106
107     pthread_mutex_unlock(&queue_lock);
108
109     /* Process the event */
110     return ber;
111 }
112
113 void nudge_queue(void)
114 {
115     pthread_cond_signal(&queue_nonempty);
116 }
117
118 void increase_queue_depth(unsigned int size)
119 {
120     pthread_mutex_lock(&queue_lock);
121     if (size > q_depth) {
122         unsigned int i;
123         void *tmp_q;
124
125         tmp_q = realloc(q, size * sizeof(BerElement *));
126         q = tmp_q;
127         for (i=q_depth; i<size; i++)
128             q[i] = NULL;
129         q_depth = size;
130     }
131     pthread_mutex_unlock(&queue_lock);
132 }
133
134 void destroy_queue(void)
135 {
136     unsigned int i;
137
138     for (i=0; i<q_depth; i++) {
139         ber_free(q[i], 1);
140     }
141
142     free(q);
143 }
144