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 
31 static TAILQ_HEAD(TmqList_, Tmq_) tmq_list = TAILQ_HEAD_INITIALIZER(tmq_list);
32 
33 static uint16_t tmq_id = 0;
34 
35 Tmq *TmqCreateQueue(const char *name)
36 {
37  Tmq *q = SCCalloc(1, sizeof(*q));
38  if (q == NULL)
39  FatalError(SC_ERR_MEM_ALLOC, "SCCalloc failed");
40 
41  q->name = SCStrdup(name);
42  if (q->name == NULL)
43  FatalError(SC_ERR_MEM_ALLOC, "SCStrdup failed");
44 
45  q->id = tmq_id++;
46  q->is_packet_pool = (strcmp(q->name, "packetpool") == 0);
47  if (!q->is_packet_pool) {
48  q->pq = PacketQueueAlloc();
49  if (q->pq == NULL)
50  FatalError(SC_ERR_MEM_ALLOC, "PacketQueueAlloc failed");
51  }
52 
53  TAILQ_INSERT_HEAD(&tmq_list, q, next);
54 
55  SCLogDebug("created queue \'%s\', %p", name, q);
56  return q;
57 }
58 
59 Tmq *TmqGetQueueByName(const char *name)
60 {
61  Tmq *tmq = NULL;
62  TAILQ_FOREACH(tmq, &tmq_list, next) {
63  if (strcmp(tmq->name, name) == 0)
64  return tmq;
65  }
66  return NULL;
67 }
68 
69 void TmqDebugList(void)
70 {
71  Tmq *tmq = NULL;
72  TAILQ_FOREACH(tmq, &tmq_list, next) {
73  /* get a lock accessing the len */
74  SCMutexLock(&tmq->pq->mutex_q);
75  printf("TmqDebugList: id %" PRIu32 ", name \'%s\', len %" PRIu32 "\n", tmq->id, tmq->name, tmq->pq->len);
76  SCMutexUnlock(&tmq->pq->mutex_q);
77  }
78 }
79 
80 void TmqResetQueues(void)
81 {
82  Tmq *tmq;
83 
84  while ((tmq = TAILQ_FIRST(&tmq_list))) {
85  TAILQ_REMOVE(&tmq_list, tmq, next);
86  if (tmq->name) {
87  SCFree(tmq->name);
88  }
89  if (tmq->pq) {
90  PacketQueueFree(tmq->pq);
91  }
92  SCFree(tmq);
93  }
94  tmq_id = 0;
95 }
96 
97 /**
98  * \brief Checks if all the queues allocated so far have at least one reader
99  * and writer.
100  */
102 {
103  bool err = false;
104 
105  Tmq *tmq = NULL;
106  TAILQ_FOREACH(tmq, &tmq_list, next) {
107  SCMutexLock(&tmq->pq->mutex_q);
108  if (tmq->reader_cnt == 0) {
109  SCLogError(SC_ERR_THREAD_QUEUE, "queue \"%s\" doesn't have a reader (id %d max %u)",
110  tmq->name, tmq->id, tmq_id);
111  err = true;
112  } else if (tmq->writer_cnt == 0) {
113  SCLogError(SC_ERR_THREAD_QUEUE, "queue \"%s\" doesn't have a writer (id %d, max %u)",
114  tmq->name, tmq->id, tmq_id);
115  err = true;
116  }
117  SCMutexUnlock(&tmq->pq->mutex_q);
118 
119  if (err == true)
120  goto error;
121  }
122 
123  return;
124 
125 error:
126  FatalError(SC_ERR_FATAL, "fatal error during threading setup");
127 }
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:298
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
threads.h
Tmq_::pq
PacketQueue * pq
Definition: tm-queues.h:35
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
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:101
Tmq_::name
char * name
Definition: tm-queues.h:30
PacketQueue_::mutex_q
SCMutex mutex_q
Definition: packet-queue.h:54
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:327
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:412
util-debug.h
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:339
SCMutexUnlock
#define SCMutexUnlock(mut)
Definition: threads-debug.h:119
TmqGetQueueByName
Tmq * TmqGetQueueByName(const char *name)
Definition: tm-queues.c:59
SC_ERR_THREAD_QUEUE
@ SC_ERR_THREAD_QUEUE
Definition: util-error.h:267
tm-queues.h
PacketQueue_::len
uint32_t len
Definition: packet-queue.h:50
SCLogError
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:257
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
FatalError
#define FatalError(x,...)
Definition: util-debug.h:532
TmqCreateQueue
Tmq * TmqCreateQueue(const char *name)
SCFree
#define SCFree(p)
Definition: util-mem.h:61
PacketQueueAlloc
PacketQueue * PacketQueueAlloc(void)
Definition: packet-queue.c:217
SC_ERR_FATAL
@ SC_ERR_FATAL
Definition: util-error.h:203
PacketQueueFree
void PacketQueueFree(PacketQueue *pq)
Definition: packet-queue.c:227
TAILQ_HEAD
#define TAILQ_HEAD(name, type)
Definition: queue.h:321
SC_ERR_MEM_ALLOC
@ SC_ERR_MEM_ALLOC
Definition: util-error.h:31
suricata.h
TAILQ_INSERT_HEAD
#define TAILQ_INSERT_HEAD(head, elm, field)
Definition: queue.h:375
Tmq_
Definition: tm-queues.h:29
TmqDebugList
void TmqDebugList(void)
Definition: tm-queues.c:69
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
Tmq_::reader_cnt
uint16_t reader_cnt
Definition: tm-queues.h:33
TmqResetQueues
void TmqResetQueues(void)
Definition: tm-queues.c:80