OpenDNSSEC-signer  1.4.5
fifoq.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 #include "scheduler/fifoq.h"
34 #include "shared/log.h"
35 
36 #include <ldns/ldns.h>
37 
38 static const char* fifoq_str = "fifo";
39 
40 
47 {
48  fifoq_type* fifoq;
49  if (!allocator) {
50  return NULL;
51  }
52  fifoq = (fifoq_type*) allocator_alloc(allocator, sizeof(fifoq_type));
53  if (!fifoq) {
54  ods_log_error("[%s] unable to create fifoq: allocator_alloc() failed",
55  fifoq_str);
56  return NULL;
57  }
58  fifoq->allocator = allocator;
59  fifoq_wipe(fifoq);
60  lock_basic_init(&fifoq->q_lock);
61  lock_basic_set(&fifoq->q_threshold);
62  lock_basic_set(&fifoq->q_nonfull);
63  return fifoq;
64 }
65 
66 
71 void
73 {
74  size_t i = 0;
75  for (i=0; i < FIFOQ_MAX_COUNT; i++) {
76  q->blob[i] = NULL;
77  q->owner[i] = NULL;
78  }
79  q->count = 0;
80  return;
81 }
82 
83 
88 void*
90 {
91  void* pop = NULL;
92  size_t i = 0;
93  if (!q || q->count <= 0) {
94  return NULL;
95  }
96  pop = q->blob[0];
97  *worker = q->owner[0];
98  for (i = 0; i < q->count-1; i++) {
99  q->blob[i] = q->blob[i+1];
100  q->owner[i] = q->owner[i+1];
101  }
102  q->count -= 1;
103  if (q->count <= (size_t) FIFOQ_MAX_COUNT * 0.1) {
109  }
110  return pop;
111 }
112 
113 
119 fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries)
120 {
121  if (!q || !item || !worker) {
122  return ODS_STATUS_ASSERT_ERR;
123  }
124  if (q->count >= FIFOQ_MAX_COUNT) {
130  if (*tries > FIFOQ_TRIES_COUNT) {
132  ods_log_debug("[%s] queue full, notify drudgers again", fifoq_str);
133  /* reset tries */
134  *tries = 0;
135  }
136  return ODS_STATUS_UNCHANGED;
137  }
138  q->blob[q->count] = item;
139  q->owner[q->count] = worker;
140  q->count += 1;
141  if (q->count == 1) {
142  ods_log_deeebug("[%s] threshold %u reached, notify drudgers",
143  fifoq_str, q->count);
144  /* If no drudgers are waiting, this call has no effect. */
146  }
147  return ODS_STATUS_OK;
148 }
149 
150 
155 void
157 {
158  allocator_type* allocator;
159  lock_basic_type q_lock;
160  cond_basic_type q_threshold;
161  cond_basic_type q_nonfull;
162  if (!q) {
163  return;
164  }
165  allocator = q->allocator;
166  q_lock = q->q_lock;
167  q_threshold = q->q_threshold;
168  q_nonfull = q->q_nonfull;
169  allocator_deallocate(allocator, (void*) q);
170  lock_basic_off(&q_threshold);
171  lock_basic_off(&q_nonfull);
172  lock_basic_destroy(&q_lock);
173  return;
174 }