summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2017-09-10 16:00:43 +0300
committerVadim Yanitskiy <axilirator@gmail.com>2017-12-31 12:20:59 +0100
commit3839a88ea681024752048c902b23144c42f4fa42 (patch)
treebcffa10e18bdcbd97007ed670d78e5798134abc8
parent459791c488c6b66a5cd0d7cff9392a7a0b8ca733 (diff)
procqueue: separate queue check function
In order to give advanced control over a processing queue, it would be better to have the checking function separated from the osmo_gapk_pq_prepare(). Moreover, this change introduces an additional 'strict' checking mode that requires a queue to have a source item first and a sink item in the last position.
-rw-r--r--include/osmocom/gapk/procqueue.h1
-rw-r--r--src/app_osmo_gapk.c6
-rw-r--r--src/libosmogapk.map1
-rw-r--r--src/procqueue.c66
4 files changed, 58 insertions, 16 deletions
diff --git a/include/osmocom/gapk/procqueue.h b/include/osmocom/gapk/procqueue.h
index c2f2675..e73f73e 100644
--- a/include/osmocom/gapk/procqueue.h
+++ b/include/osmocom/gapk/procqueue.h
@@ -71,6 +71,7 @@ struct osmo_gapk_pq {
/* Processing queue management */
struct osmo_gapk_pq *osmo_gapk_pq_create(const char *name);
+int osmo_gapk_pq_check(struct osmo_gapk_pq *pq, int strict);
int osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq);
int osmo_gapk_pq_execute(struct osmo_gapk_pq *pq);
void osmo_gapk_pq_destroy(struct osmo_gapk_pq *pq);
diff --git a/src/app_osmo_gapk.c b/src/app_osmo_gapk.c
index 6543eef..2aac0aa 100644
--- a/src/app_osmo_gapk.c
+++ b/src/app_osmo_gapk.c
@@ -521,6 +521,7 @@ make_processing_chain(struct gapk_state *gs)
const struct osmo_gapk_codec_desc *codec_in, *codec_out;
int need_dec, need_enc;
+ int rc;
LOGP(DAPP, LOGL_NOTICE, "Creating a processing queue\n");
@@ -627,6 +628,11 @@ make_processing_chain(struct gapk_state *gs)
return -1;
}
+ /* Check the processing queue in strict mode */
+ rc = osmo_gapk_pq_check(gs->pq, 1);
+ if (rc)
+ return rc;
+
return 0;
}
diff --git a/src/libosmogapk.map b/src/libosmogapk.map
index 5fd7a7a..4494cdb 100644
--- a/src/libosmogapk.map
+++ b/src/libosmogapk.map
@@ -14,6 +14,7 @@ osmo_gapk_pq_execute;
osmo_gapk_pq_destroy;
osmo_gapk_pq_describe;
+osmo_gapk_pq_check;
osmo_gapk_pq_add_item;
osmo_gapk_pq_queue_file_input;
diff --git a/src/procqueue.c b/src/procqueue.c
index 4de7a6a..b95b3ec 100644
--- a/src/procqueue.c
+++ b/src/procqueue.c
@@ -103,24 +103,65 @@ osmo_gapk_pq_add_item(struct osmo_gapk_pq *pq)
return item;
}
-/*! prepare a processing queue; allocates buffers; checks lengths
+/*! check a processing queue; make sure I/O data lengths are equal
+ * \param[in] pq Make sure both source and sink are preset
+ * \param[in] strict Processing Queue to be checked
+ * \returns 0 on succcess; negative on error */
+int
+osmo_gapk_pq_check(struct osmo_gapk_pq *pq, int strict)
+{
+ struct osmo_gapk_pq_item *item_prev = NULL;
+ struct osmo_gapk_pq_item *item;
+
+ /* Make sure I/O data lengths are equal */
+ llist_for_each_entry(item, &pq->items, list) {
+ if (item_prev && item->len_in) {
+ if (item->len_in != item_prev->len_out) {
+ LOGPGAPK(LOGL_ERROR, "PQ '%s': item '%s/%s' requires "
+ "input size %u, but previous '%s/%s' has %u\n",
+ pq->name, item->cat_name, item->sub_name,
+ item->len_in, item_prev->cat_name,
+ item_prev->sub_name, item_prev->len_out);
+ return -EINVAL;
+ }
+ }
+
+ /* Save pointer to the previous item */
+ item_prev = item;
+ }
+
+ if (strict) {
+ /* Make sure the first item is a source */
+ item = llist_first_entry(&pq->items,
+ struct osmo_gapk_pq_item, list);
+ if (item->type != OSMO_GAPK_ITEM_TYPE_SOURCE)
+ goto src_sink_err;
+
+ /* Make sure the last item is a sink */
+ item = llist_last_entry(&pq->items,
+ struct osmo_gapk_pq_item, list);
+ if (item->type != OSMO_GAPK_ITEM_TYPE_SINK)
+ goto src_sink_err;
+ }
+
+ return 0;
+
+src_sink_err:
+ LOGPGAPK(LOGL_ERROR, "PQ '%s': the first item should be a source, "
+ "and the last one should be a sink\n", pq->name);
+ return -EINVAL;
+}
+
+/*! prepare a processing queue; allocates buffers
* \param[in] pq Processing Queue to be prepared
* \returns 0 on succcess; negative on error */
int
osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq)
{
struct osmo_gapk_pq_item *item;
- unsigned int len_prev = 0;
/* Iterate over all items in queue */
llist_for_each_entry(item, &pq->items, list) {
- /* Make sure I/O data lengths are equal */
- if (item->len_in && item->len_in != len_prev) {
- LOGPGAPK(LOGL_ERROR, "PQ item requires input size %u, "
- "but previous output is %u\n", item->len_in, len_prev);
- return -EINVAL;
- }
-
/* The sink item doesn't require an output buffer */
if (item->list.next != &pq->items) {
unsigned int buf_size = item->len_out;
@@ -136,14 +177,7 @@ osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq)
item->buf = talloc_size(item, buf_size);
if (!item->buf)
return -ENOMEM;
- } else {
- /* Make sure the last item is a sink */
- if (item->len_out)
- return -EINVAL;
}
-
- /* Store output length for further comparation */
- len_prev = item->len_out;
}
return 0;