mirror of https://gerrit.osmocom.org/gapk
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.
This commit is contained in:
parent
459791c488
commit
3839a88ea6
|
@ -71,6 +71,7 @@ struct osmo_gapk_pq {
|
||||||
|
|
||||||
/* Processing queue management */
|
/* Processing queue management */
|
||||||
struct osmo_gapk_pq *osmo_gapk_pq_create(const char *name);
|
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_prepare(struct osmo_gapk_pq *pq);
|
||||||
int osmo_gapk_pq_execute(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);
|
void osmo_gapk_pq_destroy(struct osmo_gapk_pq *pq);
|
||||||
|
|
|
@ -521,6 +521,7 @@ make_processing_chain(struct gapk_state *gs)
|
||||||
const struct osmo_gapk_codec_desc *codec_in, *codec_out;
|
const struct osmo_gapk_codec_desc *codec_in, *codec_out;
|
||||||
|
|
||||||
int need_dec, need_enc;
|
int need_dec, need_enc;
|
||||||
|
int rc;
|
||||||
|
|
||||||
LOGP(DAPP, LOGL_NOTICE, "Creating a processing queue\n");
|
LOGP(DAPP, LOGL_NOTICE, "Creating a processing queue\n");
|
||||||
|
|
||||||
|
@ -627,6 +628,11 @@ make_processing_chain(struct gapk_state *gs)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check the processing queue in strict mode */
|
||||||
|
rc = osmo_gapk_pq_check(gs->pq, 1);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ osmo_gapk_pq_execute;
|
||||||
osmo_gapk_pq_destroy;
|
osmo_gapk_pq_destroy;
|
||||||
osmo_gapk_pq_describe;
|
osmo_gapk_pq_describe;
|
||||||
|
|
||||||
|
osmo_gapk_pq_check;
|
||||||
osmo_gapk_pq_add_item;
|
osmo_gapk_pq_add_item;
|
||||||
|
|
||||||
osmo_gapk_pq_queue_file_input;
|
osmo_gapk_pq_queue_file_input;
|
||||||
|
|
|
@ -103,24 +103,65 @@ osmo_gapk_pq_add_item(struct osmo_gapk_pq *pq)
|
||||||
return item;
|
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
|
* \param[in] pq Processing Queue to be prepared
|
||||||
* \returns 0 on succcess; negative on error */
|
* \returns 0 on succcess; negative on error */
|
||||||
int
|
int
|
||||||
osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq)
|
osmo_gapk_pq_prepare(struct osmo_gapk_pq *pq)
|
||||||
{
|
{
|
||||||
struct osmo_gapk_pq_item *item;
|
struct osmo_gapk_pq_item *item;
|
||||||
unsigned int len_prev = 0;
|
|
||||||
|
|
||||||
/* Iterate over all items in queue */
|
/* Iterate over all items in queue */
|
||||||
llist_for_each_entry(item, &pq->items, list) {
|
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 */
|
/* The sink item doesn't require an output buffer */
|
||||||
if (item->list.next != &pq->items) {
|
if (item->list.next != &pq->items) {
|
||||||
unsigned int buf_size = item->len_out;
|
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);
|
item->buf = talloc_size(item, buf_size);
|
||||||
if (!item->buf)
|
if (!item->buf)
|
||||||
return -ENOMEM;
|
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;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue