mirror of https://gerrit.osmocom.org/libosmocore
wqueue: Reject messges if queue is considered full
The write queue was always meant to not queue more than the max_length messages but the implementation never rejected a message. Begin to log and enforce the queue size limit, add a testcase to verify the code and initialize except_cb as part of a fix for that new test case. Real applications might now run into the queue limit and drop messages where they just queued them before. It is unfortunate but I still think it is good to implement the routine as it was intended. We need to review osmo_wqueue_enqueue once more to see that no msgb is leaked. Change-Id: I1e6aef30f3e73d4bcf2967bc49f0783aa65395ae
This commit is contained in:
parent
d7c0a373ff
commit
c7f52c4c84
|
@ -95,6 +95,7 @@ tests/sim/sim_test
|
|||
tests/gsup/gsup_test
|
||||
tests/tlv/tlv_test
|
||||
tests/fsm/fsm_test
|
||||
tests/write_queue/wqueue_test
|
||||
|
||||
utils/osmo-arfcn
|
||||
utils/osmo-auc-gen
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* Generic write queue implementation */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther
|
||||
* (C) 2010-2016 by Holger Hans Peter Freyther
|
||||
* (C) 2010 by On-Waves
|
||||
*
|
||||
* All Rights Reserved
|
||||
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include <errno.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
|
||||
/*! \addtogroup write_queue
|
||||
* @{
|
||||
|
@ -93,6 +94,7 @@ void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
|
|||
queue->current_length = 0;
|
||||
queue->read_cb = NULL;
|
||||
queue->write_cb = NULL;
|
||||
queue->except_cb = NULL;
|
||||
queue->bfd.cb = osmo_wqueue_bfd_cb;
|
||||
INIT_LLIST_HEAD(&queue->msg_queue);
|
||||
}
|
||||
|
@ -104,8 +106,11 @@ void osmo_wqueue_init(struct osmo_wqueue *queue, int max_length)
|
|||
*/
|
||||
int osmo_wqueue_enqueue(struct osmo_wqueue *queue, struct msgb *data)
|
||||
{
|
||||
// if (queue->current_length + 1 >= queue->max_length)
|
||||
// LOGP(DMSC, LOGL_ERROR, "The queue is full. Dropping not yet implemented.\n");
|
||||
if (queue->current_length >= queue->max_length) {
|
||||
LOGP(DLGLOBAL, LOGL_ERROR,
|
||||
"wqueue(%p) is full. Rejecting msgb\n", queue);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
++queue->current_length;
|
||||
msgb_enqueue(&queue->msg_queue, data);
|
||||
|
|
|
@ -13,7 +13,8 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
|
|||
vty/vty_test comp128/comp128_test utils/utils_test \
|
||||
smscb/gsm0341_test stats/stats_test \
|
||||
bitvec/bitvec_test msgb/msgb_test bits/bitcomp_test \
|
||||
tlv/tlv_test gsup/gsup_test fsm/fsm_test
|
||||
tlv/tlv_test gsup/gsup_test fsm/fsm_test \
|
||||
write_queue/wqueue_test
|
||||
|
||||
if ENABLE_MSGFILE
|
||||
check_PROGRAMS += msgfile/msgfile_test
|
||||
|
@ -133,6 +134,9 @@ gsup_gsup_test_LDADD = $(top_builddir)/src/gsm/libosmogsm.la $(top_builddir)/src
|
|||
fsm_fsm_test_SOURCES = fsm/fsm_test.c
|
||||
fsm_fsm_test_LDADD = $(top_builddir)/src/libosmocore.la
|
||||
|
||||
write_queue_wqueue_test_SOURCES = write_queue/wqueue_test.c
|
||||
write_queue_wqueue_test_LDADD = $(top_builddir)/src/libosmocore.la
|
||||
|
||||
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
|
||||
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
|
||||
:;{ \
|
||||
|
@ -168,7 +172,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
|
|||
utils/utils_test.ok stats/stats_test.ok \
|
||||
bitvec/bitvec_test.ok msgb/msgb_test.ok bits/bitcomp_test.ok \
|
||||
sim/sim_test.ok tlv/tlv_test.ok gsup/gsup_test.ok \
|
||||
fsm/fsm_test.ok fsm/fsm_test.err
|
||||
fsm/fsm_test.ok fsm/fsm_test.err write_queue/wqueue_test.ok
|
||||
|
||||
DISTCLEANFILES = atconfig atlocal
|
||||
|
||||
|
|
|
@ -177,6 +177,12 @@ cat $abs_srcdir/stats/stats_test.ok > expout
|
|||
AT_CHECK([$abs_top_builddir/tests/stats/stats_test], [0], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([write_queue])
|
||||
AT_KEYWORDS([write_queue])
|
||||
cat $abs_srcdir/write_queue/wqueue_test.ok > expout
|
||||
AT_CHECK([$abs_top_builddir/tests/write_queue/wqueue_test], [0], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([bssgp-fc])
|
||||
AT_KEYWORDS([bssgp-fc])
|
||||
cat $abs_srcdir/gb/bssgp_fc_tests.ok > expout
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/core/write_queue.h>
|
||||
|
||||
static const struct log_info_cat default_categories[] = {
|
||||
};
|
||||
|
||||
static const struct log_info log_info = {
|
||||
.cat = default_categories,
|
||||
.num_cat = ARRAY_SIZE(default_categories),
|
||||
};
|
||||
|
||||
static void test_wqueue_limit(void)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct osmo_wqueue wqueue;
|
||||
int rc;
|
||||
|
||||
osmo_wqueue_init(&wqueue, 0);
|
||||
OSMO_ASSERT(wqueue.max_length == 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 0);
|
||||
OSMO_ASSERT(wqueue.read_cb == NULL);
|
||||
OSMO_ASSERT(wqueue.write_cb == NULL);
|
||||
OSMO_ASSERT(wqueue.except_cb == NULL);
|
||||
|
||||
/* try to add and fail */
|
||||
msg = msgb_alloc(4096, "msg1");
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc < 0);
|
||||
|
||||
/* add one and fail on the second */
|
||||
wqueue.max_length = 1;
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 1);
|
||||
msg = msgb_alloc(4096, "msg2");
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc < 0);
|
||||
|
||||
/* add one more */
|
||||
wqueue.max_length = 2;
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 2);
|
||||
|
||||
/* release everything */
|
||||
osmo_wqueue_clear(&wqueue);
|
||||
OSMO_ASSERT(wqueue.current_length == 0);
|
||||
OSMO_ASSERT(wqueue.max_length == 2);
|
||||
|
||||
/* Add two, fail on the third, free it and the queue */
|
||||
msg = msgb_alloc(4096, "msg3");
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 1);
|
||||
msg = msgb_alloc(4096, "msg4");
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc == 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 2);
|
||||
msg = msgb_alloc(4096, "msg5");
|
||||
rc = osmo_wqueue_enqueue(&wqueue, msg);
|
||||
OSMO_ASSERT(rc < 0);
|
||||
OSMO_ASSERT(wqueue.current_length == 2);
|
||||
msgb_free(msg);
|
||||
osmo_wqueue_clear(&wqueue);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct log_target *stderr_target;
|
||||
|
||||
log_init(&log_info, NULL);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_print_filename(stderr_target, 0);
|
||||
|
||||
test_wqueue_limit();
|
||||
|
||||
printf("Done\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Done
|
Loading…
Reference in New Issue