OpenDNSSEC-signer  1.4.6
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 }
#define lock_basic_off(cond)
Definition: locks.h:98
void ods_log_debug(const char *format,...)
Definition: log.c:270
#define lock_basic_destroy(lock)
Definition: locks.h:90
cond_basic_type q_threshold
Definition: fifoq.h:66
void * allocator_alloc(allocator_type *allocator, size_t size)
Definition: allocator.c:66
lock_basic_type q_lock
Definition: fifoq.h:65
#define FIFOQ_MAX_COUNT
Definition: fifoq.h:53
enum ods_enum_status ods_status
Definition: status.h:90
void ods_log_error(const char *format,...)
Definition: log.c:334
#define lock_basic_set(cond)
Definition: locks.h:94
ods_status fifoq_push(fifoq_type *q, void *item, worker_type *worker, int *tries)
Definition: fifoq.c:119
#define FIFOQ_TRIES_COUNT
Definition: fifoq.h:54
void fifoq_cleanup(fifoq_type *q)
Definition: fifoq.c:156
int lock_basic_type
Definition: locks.h:88
fifoq_type * fifoq_create(allocator_type *allocator)
Definition: fifoq.c:46
size_t count
Definition: fifoq.h:64
void fifoq_wipe(fifoq_type *q)
Definition: fifoq.c:72
void * blob[FIFOQ_MAX_COUNT]
Definition: fifoq.h:62
worker_type * owner[FIFOQ_MAX_COUNT]
Definition: fifoq.h:63
#define lock_basic_init(lock)
Definition: locks.h:89
allocator_type * allocator
Definition: fifoq.h:61
void ods_log_deeebug(const char *format,...)
Definition: log.c:254
void allocator_deallocate(allocator_type *allocator, void *data)
Definition: allocator.c:135
cond_basic_type q_nonfull
Definition: fifoq.h:67
#define lock_basic_broadcast(cond)
Definition: locks.h:97
void * fifoq_pop(fifoq_type *q, worker_type **worker)
Definition: fifoq.c:89