suricata
tm-queues.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2019 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Thread module management functions
24  */
25 
26 #include "suricata.h"
27 #include "threads.h"
28 #include "tm-queues.h"
29 #include "util-debug.h"
30 #include "util-validate.h"
31 
32 static TAILQ_HEAD(TmqList_, Tmq_) tmq_list = TAILQ_HEAD_INITIALIZER(tmq_list);
33 
34 static uint16_t tmq_id = 0;
35 
36 Tmq *TmqCreateQueue(const char *name)
37 {
38  Tmq *q = SCCalloc(1, sizeof(*q));
39  if (q == NULL)
40  FatalError("SCCalloc failed");
41 
42  q->name = SCStrdup(name);
43  if (q->name == NULL)
44  FatalError("SCStrdup failed");
45 
46  q->id = tmq_id++;
47  q->is_packet_pool = (strcmp(q->name, "packetpool") == 0);
48  if (!q->is_packet_pool) {
49  q->pq = PacketQueueAlloc();
50  if (q->pq == NULL)
51  FatalError("PacketQueueAlloc failed");
52  }
53 
54  TAILQ_INSERT_HEAD(&tmq_list, q, next);
55 
56  SCLogDebug("created queue \'%s\', %p", name, q);
57  return q;
58 }
59 
60 Tmq *TmqGetQueueByName(const char *name)
61 {
62  Tmq *tmq = NULL;
63  TAILQ_FOREACH(tmq, &tmq_list, next) {
64  if (strcmp(tmq->name, name) == 0)
65  return tmq;
66  }
67  return NULL;
68 }
69 
70 void TmqDebugList(void)
71 {
72  Tmq *tmq = NULL;
73  TAILQ_FOREACH(tmq, &tmq_list, next) {
74  /* get a lock accessing the len */
75  SCMutexLock(&tmq->pq->mutex_q);
76  printf("TmqDebugList: id %" PRIu32 ", name \'%s\', len %" PRIu32 "\n", tmq->id, tmq->name, tmq->pq->len);
77  SCMutexUnlock(&tmq->pq->mutex_q);
78  }
79 }
80 
81 void TmqResetQueues(void)
82 {
83  Tmq *tmq;
84 
85  while ((tmq = TAILQ_FIRST(&tmq_list))) {
86  TAILQ_REMOVE(&tmq_list, tmq, next);
87  /* help code checkers to understand what TAILQ_REMOVE does */
88  DEBUG_VALIDATE_BUG_ON(TAILQ_FIRST(&tmq_list) == tmq);
89 
90  if (tmq->name) {
91  SCFree(tmq->name);
92  }
93  if (tmq->pq) {
94  PacketQueueFree(tmq->pq);
95  }
96  SCFree(tmq);
97  }
98  tmq_id = 0;
99 }
100 
101 /**
102  * \brief Checks if all the queues allocated so far have at least one reader
103  * and writer.
104  */
106 {
107  bool err = false;
108 
109  Tmq *tmq = NULL;
110  TAILQ_FOREACH(tmq, &tmq_list, next) {
111  SCMutexLock(&tmq->pq->mutex_q);
112  if (tmq->reader_cnt == 0) {
113  SCLogError("queue \"%s\" doesn't have a reader (id %d max %u)", tmq->name, tmq->id,
114  tmq_id);
115  err = true;
116  } else if (tmq->writer_cnt == 0) {
117  SCLogError("queue \"%s\" doesn't have a writer (id %d, max %u)", tmq->name, tmq->id,
118  tmq_id);
119  err = true;
120  }
121  SCMutexUnlock(&tmq->pq->mutex_q);
122 
123  if (err)
124  goto error;
125  }
126 
127  return;
128 
129 error:
130  FatalError("fatal error during threading setup");
131 }
Tmq_::writer_cnt
uint16_t writer_cnt
Definition: tm-queues.h:34
Tmq_::id
uint16_t id
Definition: tm-queues.h:32
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
name
const char * name
Definition: detect-engine-proto.c:48
threads.h
Tmq_::pq
PacketQueue * pq
Definition: tm-queues.h:35
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:252
Tmq_::is_packet_pool
bool is_packet_pool
Definition: tm-queues.h:31
SCMutexLock
#define SCMutexLock(mut)
Definition: threads-debug.h:117
TmValidateQueueState
void TmValidateQueueState(void)
Checks if all the queues allocated so far have at least one reader and writer.
Definition: tm-queues.c:105
Tmq_::name
char * name
Definition: tm-queues.h:30
PacketQueue_::mutex_q
SCMutex mutex_q
Definition: packet-queue.h:56
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:236
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:312
util-debug.h
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:250
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:120
TmqGetQueueByName
Tmq * TmqGetQueueByName(const char *name)
Definition: tm-queues.c:60
tm-queues.h
PacketQueue_::len
uint32_t len
Definition: packet-queue.h:52
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(...)
Definition: util-debug.h:517
util-validate.h
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
TmqCreateQueue
Tmq * TmqCreateQueue(const char *name)
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PacketQueueAlloc
PacketQueue * PacketQueueAlloc(void)
Definition: packet-queue.c:221
PacketQueueFree
void PacketQueueFree(PacketQueue *pq)
Definition: packet-queue.c:231
TAILQ_HEAD
#define TAILQ_HEAD(name, type)
Definition: queue.h:230
suricata.h
TAILQ_INSERT_HEAD
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:284
Tmq_
Definition: tm-queues.h:29
TmqDebugList
void TmqDebugList(void)
Definition: tm-queues.c:70
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
Tmq_::reader_cnt
uint16_t reader_cnt
Definition: tm-queues.h:33
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
TmqResetQueues
void TmqResetQueues(void)
Definition: tm-queues.c:81