jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 /* priority jqueues */ 00022 00023 #include "util.h" 00024 00025 jqueue_t jqueue_new(void) { 00026 pool_t p; 00027 jqueue_t q; 00028 00029 p = pool_new(); 00030 q = (jqueue_t) pmalloco(p, sizeof(struct _jqueue_st)); 00031 00032 q->p = p; 00033 q->init_time = time(NULL); 00034 00035 return q; 00036 } 00037 00038 void jqueue_free(jqueue_t q) { 00039 assert((int) (q != NULL)); 00040 00041 pool_free(q->p); 00042 } 00043 00044 void jqueue_push(jqueue_t q, void *data, int priority) { 00045 _jqueue_node_t qn, scan; 00046 00047 assert((int) (q != NULL)); 00048 00049 q->size++; 00050 00051 /* node from the cache, or make a new one */ 00052 qn = q->cache; 00053 if(qn != NULL) 00054 q->cache = qn->next; 00055 else 00056 qn = (_jqueue_node_t) pmalloc(q->p, sizeof(struct _jqueue_node_st)); 00057 00058 qn->data = data; 00059 qn->priority = priority; 00060 00061 qn->next = NULL; 00062 qn->prev = NULL; 00063 00064 /* first one */ 00065 if(q->back == NULL && q->front == NULL) { 00066 q->back = qn; 00067 q->front = qn; 00068 00069 return; 00070 } 00071 00072 /* find the first node with priority <= to us */ 00073 for(scan = q->back; scan != NULL && scan->priority > priority; scan = scan->next); 00074 00075 /* didn't find one, so we have top priority - push us on the front */ 00076 if(scan == NULL) { 00077 qn->prev = q->front; 00078 qn->prev->next = qn; 00079 q->front = qn; 00080 00081 return; 00082 } 00083 00084 /* push us in front of scan */ 00085 qn->next = scan; 00086 qn->prev = scan->prev; 00087 00088 if(scan->prev != NULL) 00089 scan->prev->next = qn; 00090 else 00091 q->back = qn; 00092 00093 scan->prev = qn; 00094 } 00095 00096 void *jqueue_pull(jqueue_t q) { 00097 void *data; 00098 _jqueue_node_t qn; 00099 00100 assert((int) (q != NULL)); 00101 00102 if(q->front == NULL) 00103 return NULL; 00104 00105 data = q->front->data; 00106 00107 qn = q->front; 00108 00109 if(qn->prev != NULL) 00110 qn->prev->next = NULL; 00111 00112 q->front = qn->prev; 00113 00114 /* node to cache for later reuse */ 00115 qn->next = q->cache; 00116 q->cache = qn; 00117 00118 if(q->front == NULL) 00119 q->back = NULL; 00120 00121 q->size--; 00122 00123 return data; 00124 } 00125 00126 int jqueue_size(jqueue_t q) { 00127 return q->size; 00128 } 00129 00130 time_t jqueue_age(jqueue_t q) { 00131 return time(NULL) - q->init_time; 00132 }