OpenDNSSEC-signer
1.3.4
|
00001 /* 00002 * $Id$ 00003 * 00004 * Copyright (c) 2011 NLNet Labs. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 00015 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 00016 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00017 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00018 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 00019 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00020 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 00021 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00023 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 00024 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 00025 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 * 00027 */ 00028 00034 #include "config.h" 00035 #include "daemon/worker.h" 00036 #include "scheduler/fifoq.h" 00037 #include "shared/allocator.h" 00038 #include "shared/log.h" 00039 00040 #include <ldns/ldns.h> 00041 00042 static const char* fifoq_str = "fifo"; 00043 00044 00049 fifoq_type* 00050 fifoq_create(allocator_type* allocator) 00051 { 00052 fifoq_type* fifoq; 00053 if (!allocator) { 00054 ods_log_error("[%s] unable to create: no allocator available", 00055 fifoq_str); 00056 return NULL; 00057 } 00058 ods_log_assert(allocator); 00059 00060 fifoq = (fifoq_type*) allocator_alloc(allocator, sizeof(fifoq_type)); 00061 if (!fifoq) { 00062 ods_log_error("[%s] unable to create: allocator failed", fifoq_str); 00063 return NULL; 00064 } 00065 ods_log_assert(fifoq); 00066 00067 fifoq->allocator = allocator; 00068 fifoq_wipe(fifoq); 00069 lock_basic_init(&fifoq->q_lock); 00070 lock_basic_set(&fifoq->q_threshold); 00071 return fifoq; 00072 } 00073 00074 00079 void 00080 fifoq_wipe(fifoq_type* q) 00081 { 00082 size_t i = 0; 00083 00084 for (i=0; i < FIFOQ_MAX_COUNT; i++) { 00085 q->blob[i] = NULL; 00086 q->owner[i] = NULL; 00087 } 00088 q->count = 0; 00089 return; 00090 } 00091 00092 00097 void* 00098 fifoq_pop(fifoq_type* q, worker_type** worker) 00099 { 00100 void* pop = NULL; 00101 size_t i = 0; 00102 00103 if (!q) { 00104 return NULL; 00105 } 00106 if (q->count <= 0) { 00107 return NULL; 00108 } 00109 00110 pop = q->blob[0]; 00111 *worker = q->owner[0]; 00112 for (i = 0; i < q->count-1; i++) { 00113 q->blob[i] = q->blob[i+1]; 00114 q->owner[i] = q->owner[i+1]; 00115 } 00116 q->count -= 1; 00117 ods_log_deeebug("[%s] popped item, count=%u", fifoq_str, q->count); 00118 return pop; 00119 } 00120 00121 00126 ods_status 00127 fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries) 00128 { 00129 size_t count = 0; 00130 00131 if (!item) { 00132 ods_log_error("[%s] unable to push item: no item", fifoq_str); 00133 return ODS_STATUS_ASSERT_ERR; 00134 } 00135 ods_log_assert(item); 00136 if (!q) { 00137 ods_log_error("[%s] unable to push item: no queue", fifoq_str); 00138 return ODS_STATUS_ASSERT_ERR; 00139 } 00140 ods_log_assert(q); 00141 00142 if (q->count >= FIFOQ_MAX_COUNT) { 00143 ods_log_deeebug("[%s] unable to push item: max cap reached", 00144 fifoq_str); 00145 /* #262 if drudgers remain on hold, do additional broadcast */ 00146 if (*tries > FIFOQ_TRIES_COUNT) { 00147 lock_basic_broadcast(&q->q_threshold); 00148 ods_log_debug("[%s] max cap reached, but drudgers seem to be " 00149 "on hold, notify drudgers again", fifoq_str); 00150 /* reset tries */ 00151 *tries = 0; 00152 } 00153 return ODS_STATUS_UNCHANGED; 00154 } 00155 count = q->count; 00156 00157 q->blob[q->count] = item; 00158 q->owner[q->count] = worker; 00159 q->count += 1; 00160 00161 if (count == 0 && q->count == 1) { 00162 lock_basic_broadcast(&q->q_threshold); 00163 ods_log_deeebug("[%s] threshold %u reached, notify drudgers", 00164 fifoq_str, q->count); 00165 } 00166 return ODS_STATUS_OK; 00167 } 00168 00169 00174 void 00175 fifoq_cleanup(fifoq_type* q) 00176 { 00177 allocator_type* allocator; 00178 lock_basic_type q_lock; 00179 cond_basic_type q_cond; 00180 00181 if (!q) { 00182 return; 00183 } 00184 ods_log_assert(q); 00185 allocator = q->allocator; 00186 q_lock = q->q_lock; 00187 q_cond = q->q_threshold; 00188 00189 allocator_deallocate(allocator, (void*) q); 00190 lock_basic_off(&q_cond); 00191 lock_basic_destroy(&q_lock); 00192 return; 00193 }