OpenDNSSEC-signer  2.0.4
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 "log.h"
35 
36 #include <ldns/ldns.h>
37 
38 static const char* fifoq_str = "fifo";
39 
40 
47 {
48  fifoq_type* fifoq;
49  CHECKALLOC(fifoq = (fifoq_type*) malloc(sizeof(fifoq_type)));
50  if (!fifoq) {
51  ods_log_error("[%s] unable to create fifoq: allocator_alloc() failed",
52  fifoq_str);
53  return NULL;
54  }
55  fifoq_wipe(fifoq);
56  lock_basic_init(&fifoq->q_lock);
57  lock_basic_set(&fifoq->q_threshold);
58  lock_basic_set(&fifoq->q_nonfull);
59  return fifoq;
60 }
61 
62 
67 void
69 {
70  size_t i = 0;
71  for (i=0; i < FIFOQ_MAX_COUNT; i++) {
72  q->blob[i] = NULL;
73  q->owner[i] = NULL;
74  }
75  q->count = 0;
76 }
77 
78 
83 void*
85 {
86  void* pop = NULL;
87  size_t i = 0;
88  if (!q || q->count <= 0) {
89  return NULL;
90  }
91  pop = q->blob[0];
92  *worker = q->owner[0];
93  for (i = 0; i < q->count-1; i++) {
94  q->blob[i] = q->blob[i+1];
95  q->owner[i] = q->owner[i+1];
96  }
97  q->count -= 1;
98  if (q->count <= (size_t) FIFOQ_MAX_COUNT * 0.1) {
103  lock_basic_broadcast(&q->q_nonfull);
104  }
105  return pop;
106 }
107 
108 
113 ods_status
114 fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries)
115 {
116  if (!q || !item || !worker) {
117  return ODS_STATUS_ASSERT_ERR;
118  }
119  if (q->count >= FIFOQ_MAX_COUNT) {
125  if (*tries > FIFOQ_TRIES_COUNT) {
126  lock_basic_broadcast(&q->q_threshold);
127  ods_log_debug("[%s] queue full, notify drudgers again", fifoq_str);
128  /* reset tries */
129  *tries = 0;
130  }
131  return ODS_STATUS_UNCHANGED;
132  }
133  q->blob[q->count] = item;
134  assert(worker);
135  assert(worker->task);
136  q->owner[q->count] = worker;
137  q->count += 1;
138  if (q->count == 1) {
139  ods_log_deeebug("[%s] threshold %lu reached, notify drudgers",
140  fifoq_str, (unsigned long) q->count);
141  /* If no drudgers are waiting, this call has no effect. */
142  lock_basic_broadcast(&q->q_threshold);
143  }
144  return ODS_STATUS_OK;
145 }
146 
147 
152 void
154 {
155  if (!q) {
156  return;
157  }
158  lock_basic_off(&q->q_threshold);
159  lock_basic_off(&q->q_nonfull);
160  lock_basic_destroy(&q->q_lock);
161  free(q);
162 }
cond_basic_type q_threshold
Definition: fifoq.h:65
lock_basic_type q_lock
Definition: fifoq.h:64
#define FIFOQ_MAX_COUNT
Definition: fifoq.h:54
ods_status fifoq_push(fifoq_type *q, void *item, worker_type *worker, int *tries)
Definition: fifoq.c:114
#define FIFOQ_TRIES_COUNT
Definition: fifoq.h:55
void fifoq_cleanup(fifoq_type *q)
Definition: fifoq.c:153
task_type * task
Definition: worker.h:55
size_t count
Definition: fifoq.h:63
void fifoq_wipe(fifoq_type *q)
Definition: fifoq.c:68
void * blob[FIFOQ_MAX_COUNT]
Definition: fifoq.h:61
worker_type * owner[FIFOQ_MAX_COUNT]
Definition: fifoq.h:62
fifoq_type * fifoq_create()
Definition: fifoq.c:46
cond_basic_type q_nonfull
Definition: fifoq.h:66
void * fifoq_pop(fifoq_type *q, worker_type **worker)
Definition: fifoq.c:84