/** * prop_mutex can be held here, so we need to avoid locking it */ void mp_release(media_pipe_t *mp) { if(atomic_dec(&mp->mp_refcount)) return; event_t *e; /* Make sure a clean shutdown has been made */ assert(mp->mp_audio_decoder == NULL); assert(mp != media_primary); if(media_pipe_fini_extra != NULL) media_pipe_fini_extra(mp); while((e = TAILQ_FIRST(&mp->mp_eq)) != NULL) { TAILQ_REMOVE(&mp->mp_eq, e, e_link); event_release(e); } mq_flush(mp, &mp->mp_audio, 1); mq_flush(mp, &mp->mp_video, 1); mq_destroy(&mp->mp_audio); mq_destroy(&mp->mp_video); video_overlay_flush_locked(mp, 0); dvdspu_destroy_all(mp); hts_cond_destroy(&mp->mp_backpressure); hts_mutex_destroy(&mp->mp_mutex); hts_mutex_destroy(&mp->mp_clock_mutex); hts_mutex_destroy(&mp->mp_overlay_mutex); pool_destroy(mp->mp_mb_pool); if(mp->mp_satisfied == 0) atomic_dec(&media_buffer_hungry); cancellable_release(mp->mp_cancellable); /** * We need to destroy mp_prop_root but there is a risk that prop_mutex * is held here, so we need to dispatch */ task_run(mp_final_release, mp); }
int main(void) { message_queue *q = mq_create(); message_node *n = NULL; printf("size should be 0, is %d\n", mq_size(q)); mq_push_msgz(q, "one"); mq_push_msgz(q, "two"); mq_push_msgz(q, "three"); printf("size should be 3, is %d\n", mq_size(q)); n = mq_pop(q); printf("expecting \"one\", got \"%s\"\n", n->message); mn_destroy(n); mq_push_msgz(q, "four"); n = mq_pop(q); printf("expecting \"two\", got \"%s\"\n", n->message); mn_destroy(n); n = mq_pop(q); printf("expecting \"three\", got \"%s\"\n", n->message); mn_destroy(n); printf("size should be 1, is %d\n", mq_size(q)); n = mq_pop(q); printf("expecting \"four\", got \"%s\"\n", n->message); mn_destroy(n); printf("size should be 0, is %d\n", mq_size(q)); n = mq_pop(q); printf("expecting \"%p\", got \"%p\"\n", NULL, n); mq_destroy(q); return 0; }
static int mq_init(struct Qdisc *sch, struct nlattr *opt) { struct net_device *dev = qdisc_dev(sch); struct mq_sched *priv = qdisc_priv(sch); struct netdev_queue *dev_queue; struct Qdisc *qdisc; unsigned int ntx; if (sch->parent != TC_H_ROOT) return -EOPNOTSUPP; if (!netif_is_multiqueue(dev)) return -EOPNOTSUPP; /* pre-allocate qdiscs, attachment can't fail */ priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]), GFP_KERNEL); if (priv->qdiscs == NULL) return -ENOMEM; for (ntx = 0; ntx < dev->num_tx_queues; ntx++) { dev_queue = netdev_get_tx_queue(dev, ntx); qdisc = qdisc_create_dflt(dev_queue, default_qdisc_ops, TC_H_MAKE(TC_H_MAJ(sch->handle), TC_H_MIN(ntx + 1))); if (qdisc == NULL) goto err; priv->qdiscs[ntx] = qdisc; qdisc->flags |= TCQ_F_ONETXQUEUE; } sch->flags |= TCQ_F_MQROOT; return 0; err: mq_destroy(sch); return -ENOMEM; }
/** * destroy module function */ static void mod_destroy(void) { mq_destroy(); }