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