queue.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 1998,1999,2001  Ross Combs (rocombs@cs.nmsu.edu)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #define QUEUE_INTERNAL_ACCESS
  19. #include "common/setup_before.h"
  20. #ifdef HAVE_STDDEF_H
  21. # include <stddef.h>
  22. #else
  23. # ifndef NULL
  24. #  define NULL ((void *)0)
  25. # endif
  26. #endif
  27. #ifdef STDC_HEADERS
  28. # include <stdlib.h>
  29. #else
  30. # ifdef HAVE_MALLOC_H
  31. #  include <malloc.h>
  32. # endif
  33. #endif
  34. #ifdef HAVE_STRING_H
  35. # include <string.h>
  36. #else
  37. # ifdef HAVE_STRINGS_H
  38. #  include <strings.h>
  39. # endif
  40. # ifdef HAVE_MEMORY_H
  41. #  include <memory.h>
  42. # endif
  43. #endif
  44. #include "common/packet.h"
  45. #include "common/eventlog.h"
  46. #include "common/queue.h"
  47. #include "common/setup_after.h"
  48. #define QUEUE_QUANTUM 10 /* allocate ring buffer slots for 10 packets at once */
  49. extern t_packet * queue_pull_packet(t_queue * * queue)
  50. {
  51.     t_queue *  temp;
  52.     t_packet * packet;
  53. //    eventlog(eventlog_level_debug, __FUNCTION__, "entered: queue %p", queue);
  54.     if (!queue)
  55.     {
  56. eventlog(eventlog_level_error,"queue_pull_packet","got NULL queue pointer");
  57.         return NULL;
  58.     }
  59.     temp = *queue;
  60.     if (!temp || !temp->ulen)
  61.         return NULL;
  62. //    eventlog(eventlog_level_debug, __FUNCTION__, "getting element from tail (%d/%d head/tail %d/%d)", temp->alen, temp->ulen, temp->head, temp->tail);
  63.     /* getting entry from tail and updating queue */
  64.     packet = temp->ring[temp->tail];
  65.     temp->tail = (temp->tail + 1) % temp->alen;
  66.     temp->ulen--;
  67. //    eventlog(eventlog_level_debug, __FUNCTION__, "read %p element from tail (%d/%d head/tail %d/%d)", packet, temp->alen, temp->ulen, temp->head, temp->tail);
  68.     if (!packet)
  69.     {
  70. eventlog(eventlog_level_error,"queue_pull_packet","NULL packet in queue");
  71.         return NULL;
  72.     }
  73.     
  74.     return packet;
  75. }
  76. extern t_packet * queue_peek_packet(t_queue const * const * queue)
  77. {
  78.     t_packet * packet;
  79. //    eventlog(eventlog_level_debug, __FUNCTION__, "entered: queue %p", queue);
  80.     if (!queue)
  81.     {
  82. eventlog(eventlog_level_error,"queue_peek_packet","got NULL queue pointer");
  83.         return NULL;
  84.     }
  85.     if (!*queue || !(*queue)->ulen)
  86.         return NULL;
  87.     packet = (*queue)->ring[(*queue)->tail];
  88.     
  89.     if (!packet)
  90.     {
  91.         eventlog(eventlog_level_error,"queue_peek_packet","NULL packet in queue");
  92.         return NULL;
  93.     }
  94.     
  95.     return packet;
  96. }
  97. extern void queue_push_packet(t_queue * * queue, t_packet * packet)
  98. {
  99.     t_queue * temp;
  100.     void *ptr;
  101. //    eventlog(eventlog_level_debug, __FUNCTION__, "entered: queue %p packet %p", queue, packet);
  102.     if (!queue)
  103.     {
  104. eventlog(eventlog_level_error,"queue_push_packet","got NULL queue pointer");
  105.         return;
  106.     }
  107.     if (!packet)
  108.     {
  109. eventlog(eventlog_level_error,"queue_push_packet","got NULL packet");
  110.         return;
  111.     }
  112.     temp = *queue;
  113.     if (!temp)
  114.     {
  115. // eventlog(eventlog_level_debug, __FUNCTION__, "queue is NULL , initilizing");
  116.         if (!(temp = malloc(sizeof(t_queue))))
  117.         {
  118.     eventlog(eventlog_level_error,"queue_push_packet","could not allocate memory for head of queue");
  119.             return;
  120.         }
  121. temp->alen = temp->ulen = 0;
  122. temp->ring = NULL;
  123. temp->head = temp->tail = 0;
  124.         *queue = temp;
  125.     }
  126.     if (temp->ulen == temp->alen) { /* ring queue is full, need to allocate some memory */
  127. /* FIXME: find a solution
  128. if (temp->alen)
  129.     eventlog(eventlog_level_error, __FUNCTION__, "queue is full (resizing) (oldsize: %u)", temp->alen);
  130. */
  131. if (!(ptr = realloc(temp->ring, sizeof(t_packet *) * (temp->alen + QUEUE_QUANTUM)))) {
  132.     eventlog(eventlog_level_error, __FUNCTION__, "not enough memory for ring buffer");
  133.     return ;
  134. }
  135. temp->ring = (t_packet **)ptr;
  136. temp->alen += QUEUE_QUANTUM;
  137. // eventlog(eventlog_level_debug, __FUNCTION__, "queue new size %d/%d head/tail %d/%d", temp->alen, temp->ulen, temp->head, temp->tail);
  138. if (temp->head) {
  139.     unsigned moved;
  140.     moved = (QUEUE_QUANTUM <= temp->head) ? QUEUE_QUANTUM : temp->head;
  141.     memmove(temp->ring + temp->ulen, temp->ring, sizeof(t_packet *) * moved);
  142.     if (temp->head > QUEUE_QUANTUM) {
  143. memmove(temp->ring, temp->ring + moved, sizeof(t_packet *) * (temp->head - moved));
  144. temp->head -= moved;
  145.     } else if (temp->head < QUEUE_QUANTUM)
  146. temp->head = temp->ulen + moved;
  147.     else temp->head = 0;
  148. } else temp->head = temp->ulen;
  149.     }
  150.     temp->ring[temp->head] = packet_add_ref(packet);
  151.     temp->head = (temp->head + 1) % temp->alen;
  152.     temp->ulen++;
  153. //    eventlog(eventlog_level_debug, __FUNCTION__, "packet added (%d/%d head/tail %d/%d)", temp->alen, temp->ulen, temp->head, temp->tail);
  154. }
  155. extern int queue_get_length(t_queue const * const * queue)
  156. {
  157. //    eventlog(eventlog_level_debug, __FUNCTION__, "entered: queue %p", queue);
  158.     if (!queue)
  159.     {
  160. eventlog(eventlog_level_error,"queue_get_length","got NULL queue pointer");
  161. return 0;
  162.     }
  163.     if (*queue == NULL) return 0;
  164.     return (*queue)->ulen;
  165. }
  166. extern void queue_clear(t_queue * * queue)
  167. {
  168.     t_packet * temp;
  169. //    eventlog(eventlog_level_debug, __FUNCTION__, "entered: queue %p", queue);
  170.     if (!queue)
  171.     {
  172. eventlog(eventlog_level_error,"queue_clear","got NULL queue pointer");
  173. return;
  174.     }
  175.     if (*queue) {
  176. while ((temp = queue_pull_packet(queue)))
  177.     packet_del_ref(temp);
  178. if ((*queue)->ring) free((void*)((*queue)->ring));
  179. free((void*)(*queue));
  180.     }
  181. }